Breadcrumb & Bookmark Styling

This commit is contained in:
Sebastian
2020-09-02 15:12:58 +02:00
parent 3fb6cd29f7
commit 41791981d7
13 changed files with 411 additions and 147 deletions

View File

@@ -1,4 +1,7 @@
import { OrderItemProcessingStatusValue, EnvironmentChannel } from '@swagger/oms';
import {
OrderItemProcessingStatusValue,
EnvironmentChannel,
} from '@swagger/oms';
export interface OrderDetailsCardInput {
firstName?: string;
@@ -12,4 +15,5 @@ export interface OrderDetailsCardInput {
pickupDeadline?: Date;
compartmentCode?: string;
compartmentInfo?: string;
processingStatusDate?: Date;
}

View File

@@ -1,7 +1,9 @@
<h2 class="isa-flex isa-justify-content-space-between">
<span>{{ orderDetails?.firstName }} {{ orderDetails?.lastName }}</span>
<span>{{ orderDetails?.compartmentCode }}
{{ orderDetails?.compartmentInfo }}</span>
<span
>{{ orderDetails?.compartmentCode }}
{{ orderDetails?.compartmentInfo }}</span
>
</h2>
<div class="isa-flex isa-justify-content-space-between">
<div class="isa-flex isa-flex-direction-column">
@@ -30,23 +32,49 @@
<div class="detail">
<div class="name">Status</div>
<div class="value">
<button class="isa-btn isa-p-0 isa-btn-block isa-text-right" (click)="statusDropdown.toggle()">
<lib-icon class="isa-mr-8" [ngClass]="icon" *ngIf="
<button
class="isa-btn isa-p-0 isa-btn-block isa-text-right"
(click)="statusDropdown.toggle()"
>
<lib-icon
class="isa-mr-8"
[ngClass]="icon"
*ngIf="
orderDetails?.processingStatus | processingStatus: 'icon';
let icon
" [name]="icon">
"
[name]="icon"
>
</lib-icon>
<strong>{{
orderDetails?.processingStatus | processingStatus
}}</strong>
<lib-icon class="dp-button-icon" [class.up]="statusDropdown.visible" [class.down]="!statusDropdown.visible"
name="Arrow_right" [height]="'16px'"></lib-icon>
<lib-icon
class="dp-button-icon"
[class.up]="statusDropdown.visible"
[class.down]="!statusDropdown.visible"
name="Arrow_right"
[height]="'16px'"
></lib-icon>
</button>
<app-ui-dropdown #statusDropdown [value]="orderDetails?.processingStatus"
(valueChange)="changeProcessingStatus.emit($event)">
<ng-container *ngFor="let status of processingKeys | keyvalue | processingStatusOptionsKeyValuePipe">
<button appUiDropdownItem class="isa-btn isa-text-left isa-p-16" [value]="status.key"
*ngIf="status.key !== orderDetails?.processingStatus">
<app-ui-dropdown
#statusDropdown
[value]="orderDetails?.processingStatus"
(valueChange)="changeProcessingStatus.emit($event)"
>
<ng-container
*ngFor="
let status of processingKeys
| keyvalue
| processingStatusOptionsKeyValuePipe
"
>
<button
appUiDropdownItem
class="isa-btn isa-text-left isa-p-16"
[value]="status.key"
*ngIf="status.key !== orderDetails?.processingStatus"
>
{{ status?.value?.value }}
</button>
</ng-container>
@@ -57,17 +85,30 @@
<div class="detail" *ngSwitchCase="16">
<div class="name">vsl. Lieferdatum</div>
<div class="value">
<button class="isa-btn isa-p-0 isa-btn-block isa-text-right" (click)="uiDatepicker.toggle()">
<button
class="isa-btn isa-p-0 isa-btn-block isa-text-right"
(click)="uiDatepicker.toggle()"
>
<strong>
{{ orderDetails?.estimatedShippingDate | date: 'dd.MM.yy' }}
</strong>
<lib-icon class="dp-button-icon" [class.up]="uiDatepicker.opened" [class.down]="!uiDatepicker.opened"
name="Arrow_right" [height]="'16px'"></lib-icon>
<lib-icon
class="dp-button-icon"
[class.up]="uiDatepicker.opened"
[class.down]="!uiDatepicker.opened"
name="Arrow_right"
[height]="'16px'"
></lib-icon>
</button>
<app-ui-datepicker #uiDatepicker [right]="'-1rem'" [min]="minDate"
[selected]="orderDetails?.estimatedShippingDate" (save)="
changeEstimatedDeliveryDate.emit($event); uiDatepicker.close()
">
<app-ui-datepicker
#uiDatepicker
[right]="'-1rem'"
[min]="minDate"
[selected]="orderDetails?.estimatedShippingDate"
(save)="
changeEstimatedDeliveryDate.emit($event); uiDatepicker.close()
"
>
</app-ui-datepicker>
</div>
</div>
@@ -82,7 +123,12 @@
</ng-container>
<div class="detail" *ngSwitchDefault>
<div class="name">Geändert</div>
<div class="value isa-text-right"></div>
<div class="value isa-text-right">
{{
orderDetails?.processingStatusDate | date: 'dd.MM.yy | HH:mm'
}}
Uhr
</div>
</div>
</ng-container>
</div>
@@ -92,17 +138,28 @@
<div class="detail">
<div class="name">vsl. Lieferdatum</div>
<div class="value">
<button class="isa-btn isa-p-0 isa-btn-block isa-text-right" (click)="uiDatepicker.toggle()">
<button
class="isa-btn isa-p-0 isa-btn-block isa-text-right"
(click)="uiDatepicker.toggle()"
>
<strong>
{{ orderDetails?.estimatedShippingDate | date: 'dd.MM.yy' }}
</strong>
<lib-icon class="dp-button-icon" [class.up]="uiDatepicker.opened" [class.down]="!uiDatepicker.opened"
name="Arrow_right" [height]="'16px'"></lib-icon>
<lib-icon
class="dp-button-icon"
[class.up]="uiDatepicker.opened"
[class.down]="!uiDatepicker.opened"
name="Arrow_right"
[height]="'16px'"
></lib-icon>
</button>
<app-ui-datepicker #uiDatepicker [right]="'-1rem'" [min]="minDate"
[selected]="orderDetails?.estimatedShippingDate" (save)="
changeEstimatedDeliveryDate.emit($event); uiDatepicker.close()
">
<app-ui-datepicker
#uiDatepicker
[right]="'-1rem'"
[min]="minDate"
[selected]="orderDetails?.estimatedShippingDate"
(save)="changeEstimatedDeliveryDate.emit($event); uiDatepicker.close()"
>
</app-ui-datepicker>
</div>
</div>
@@ -112,21 +169,36 @@
<div class="detail">
<div class="name">Abholfrist</div>
<div class="value">
<button class="isa-btn isa-p-0 isa-btn-block isa-text-right" (click)="deadlineDropdown.toggle()">
<button
class="isa-btn isa-p-0 isa-btn-block isa-text-right"
(click)="deadlineDropdown.toggle()"
>
<strong>
{{ orderDetails?.pickupDeadline | date: 'dd.MM.yy' }}
</strong>
<lib-icon class="dp-button-icon" [class.up]="deadlineDropdown.visible" [class.down]="!deadlineDropdown.visible"
name="Arrow_right" [height]="'16px'"></lib-icon>
<lib-icon
class="dp-button-icon"
[class.up]="deadlineDropdown.visible"
[class.down]="!deadlineDropdown.visible"
name="Arrow_right"
[height]="'16px'"
></lib-icon>
</button>
<app-ui-dropdown #deadlineDropdown [value]="orderDetails?.pickupDeadline"
(valueChange)="changePickUpDeadline.emit($event)">
<app-ui-dropdown
#deadlineDropdown
[value]="orderDetails?.pickupDeadline"
(valueChange)="changePickUpDeadline.emit($event)"
>
<ng-container *ngFor="let dl of pickupDeadlines | keyvalue">
<button appUiDropdownItem class="isa-btn isa-text-left isa-p-16" [value]="dl.value">
<button
appUiDropdownItem
class="isa-btn isa-text-left isa-p-16"
[value]="dl.value"
>
{{ dl.key }}
</button>
</ng-container>
</app-ui-dropdown>
</div>
</div>
</ng-template>
</ng-template>

View File

@@ -1,49 +1,76 @@
<div class="tags" *ngIf="item.features?.prebooked">
<lib-icon name="tag_icon_preorder" width="30px"></lib-icon>
<div class="tags" *ngIf="item.features">
<lib-icon
*ngIf="item.features?.prebooked"
name="tag_icon_preorder"
height="48px"
></lib-icon>
</div>
<div class="isa-text-right isa-mb-9" *ngIf="item.compartmentCode">
<strong>{{ item.compartmentCode }} {{ item.compartmentInfo }} </strong>
<div class="feature-spacing" *ngIf="item.features"></div>
<div
class="isa-text-right isa-mb-9 isa-font-size-24"
*ngIf="item.compartmentCode && displayCompartmentCode"
>
<strong>{{ item.compartmentCode }} {{ item.compartmentInfo }} </strong>
</div>
<div class="paid isa-mt-9 isa-mb-9" *ngIf="item.features?.paid">
<lib-icon height="24px" width="24px" name="Check_green_circle" class="isa-mr-10"></lib-icon>
<strong> {{ item.features?.paid }} </strong>
<lib-icon
height="24px"
width="24px"
name="Check_green_circle"
class="isa-mr-10"
></lib-icon>
<strong> {{ item.features?.paid }} </strong>
</div>
<div class="grid-container">
<div class="cover">
<img class="thumbnail" src="https://produktbilder.ihugendubel.de/{{item.product.ean}}.jpg?showDummy=true"
alt="item.product.name">
<div class="cover">
<img
class="thumbnail"
src="https://produktbilder.ihugendubel.de/{{
item.product.ean
}}.jpg?showDummy=true"
alt="item.product.name"
/>
</div>
<div class="title">
<strong class="product-name">
{{ [item.product.contributors, item.product.name] | title }}</strong
>
<strong class="processing-status">
<lib-icon
class="isa-mr-9"
*ngIf="item.processingStatus | processingStatus: 'icon'; let icon"
[name]="icon"
[ngClass]="icon"
>
</lib-icon>
{{ item.processingStatus | processingStatus }}
</strong>
</div>
<div class="details">
<div class="item-type">
<lib-icon
class="isa-mr-9"
name="Icon_{{ item.product.format }}"
></lib-icon>
<strong>{{ item.product.formatDetail }}</strong>
</div>
<div class="title">
<strong class="product-name"> {{ [ item.product.contributors, item.product.name] | title }}</strong>
<strong class="processing-status">
<lib-icon class="isa-mr-9" *ngIf="item.processingStatus | processingStatus:'icon'; let icon" [name]="icon"
[ngClass]="icon">
</lib-icon>
{{ item.processingStatus | processingStatus }}
</strong>
<div class="order-date spec">
<span>Bestelldatum</span>
<strong>{{ item.orderDate | date }}</strong>
</div>
<div class="details">
<div class="item-type">
<lib-icon class="isa-mr-9" name="Icon_{{item.product.format}}"></lib-icon>
<strong>{{ item.product.formatDetail }}</strong>
</div>
<div class="order-date spec">
<span>Bestelldatum</span>
<strong>{{ item.orderDate | date }}</strong>
</div>
<div class="item-number">
<strong>{{ item.product.ean }}</strong>
</div>
<div class="quantity spec">
<span>Menge</span>
<strong>{{ item.quantity }}x</strong>
</div>
<div class="price">
<strong>{{ item.price | currency:'EUR':'code' }}</strong>
</div>
<div class="target-branch spec">
<span>Zielfiliale</span>
<strong>{{ item.targetBranch }}</strong>
</div>
<div class="item-number">
<strong>{{ item.product.ean }}</strong>
</div>
</div>
<div class="quantity spec">
<span>Menge</span>
<strong>{{ item.quantity }}x</strong>
</div>
<div class="price">
<strong>{{ item.price | currency: 'EUR':'code' }}</strong>
</div>
<div class="target-branch spec">
<span>Zielfiliale</span>
<strong>{{ item.targetBranch }}</strong>
</div>
</div>
</div>

View File

@@ -101,5 +101,9 @@
.tags {
position: absolute;
top: -16px;
right: 150px;
right: 0;
}
.feature-spacing {
height: 40px;
}

View File

@@ -1,4 +1,9 @@
import { Component, OnInit, ChangeDetectionStrategy, Input } from '@angular/core';
import {
Component,
OnInit,
ChangeDetectionStrategy,
Input,
} from '@angular/core';
import { OrderItemListItemDTO } from '@swagger/oms';
@Component({
@@ -11,6 +16,9 @@ export class SearchResultGroupItemComponent implements OnInit {
@Input()
item: OrderItemListItemDTO;
@Input()
displayCompartmentCode = true;
constructor() {}
ngOnInit() {}

View File

@@ -2,23 +2,38 @@
<h3 class="heading">
{{ group.items[0].firstName }} {{ group.items[0].lastName }}
</h3>
<ng-container *ngFor="
<ng-container
*ngFor="
let byOrderNumber of group.items | groupBy: byOrderNumberFn;
let lastOrder = last
">
<ng-container *ngFor="
"
>
<ng-container
*ngFor="
let byProcessingStatus of byOrderNumber.items
| groupBy: byProcessingStatusFn;
let lastStatus = last
">
<ng-container *ngFor="
"
>
<ng-container
*ngFor="
let groupedBy of byProcessingStatus.items
| groupBy: byCompartmentCodeFn;
let lastCompartment = last
">
"
>
<div class="isa-mb-12 isa-mt-12">
<app-search-result-group-item *ngFor="let item of groupedBy.items; let lastItem = last" [item]="item"
[class.group-item-bottom-space]="!lastItem" (click)="selectOrderItemListItem.emit(item)">
<app-search-result-group-item
*ngFor="
let item of groupedBy.items;
let firstItem = first;
let lastItem = last
"
[item]="item"
[class.group-item-bottom-space]="!lastItem"
(click)="selectOrderItemListItem.emit(item)"
[displayCompartmentCode]="firstItem"
>
</app-search-result-group-item>
</div>
<div class="divider" *ngIf="!lastCompartment"></div>
@@ -27,4 +42,4 @@
</ng-container>
<div class="divider" *ngIf="!lastOrder"></div>
</ng-container>
</div>
</div>

View File

@@ -63,6 +63,7 @@ export class ShelfHistoryHeaderComponent implements OnInit {
orderDate: new Date(item.orderDate),
orderNumber: item.orderNumber,
processingStatus: item.processingStatus,
processingStatusDate: new Date(item.processingStatusDate),
orderChannel: item.clientChannel,
compartmentCode: item.compartmentCode,
compartmentInfo: item.compartmentInfo,

View File

@@ -1,7 +1,18 @@
import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
import { DetailsFacade } from '@shelf-store/details';
import { ActivatedRoute } from '@angular/router';
import { map, switchMap, first, filter, flatMap, distinctUntilChanged, shareReplay, take, takeUntil, withLatestFrom } from 'rxjs/operators';
import {
map,
switchMap,
first,
filter,
flatMap,
distinctUntilChanged,
shareReplay,
take,
takeUntil,
withLatestFrom,
} from 'rxjs/operators';
import { OrderDetailsCardInput } from '../../components/order-details-card';
import {
OrderItemProcessingStatusValue,
@@ -22,10 +33,15 @@ import { PrinterSelectionComponent } from 'apps/sales/src/app/components/printer
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShelfOrderDetailsComponent {
@ViewChild(PrinterSelectionComponent, { read: PrinterSelectionComponent, static: true })
@ViewChild(PrinterSelectionComponent, {
read: PrinterSelectionComponent,
static: true,
})
printerSlectionComponent: PrinterSelectionComponent;
processingStatus$ = this.activatedRoute.params.pipe(map((params) => params['processingStatus']));
processingStatus$ = this.activatedRoute.params.pipe(
map((params) => params['processingStatus'])
);
partialPickup = false;
@@ -46,14 +62,24 @@ export class ShelfOrderDetailsComponent {
);
orderItems$ = race(
this.orderNumber$.pipe(switchMap((orderNumber) => this.detailsFacade.getOrderItemsByOrderNumber$(orderNumber))),
this.compartmentCode$.pipe(switchMap((compartmentCode) => this.detailsFacade.getOrderItemsByCompartmentCode$(compartmentCode)))
this.orderNumber$.pipe(
switchMap((orderNumber) =>
this.detailsFacade.getOrderItemsByOrderNumber$(orderNumber)
)
),
this.compartmentCode$.pipe(
switchMap((compartmentCode) =>
this.detailsFacade.getOrderItemsByCompartmentCode$(compartmentCode)
)
)
).pipe(
flatMap((items) =>
this.processingStatus$.pipe(
map((processingStatus) => {
if (!!processingStatus) {
return items.filter((item) => item.processingStatus === +processingStatus);
return items.filter(
(item) => item.processingStatus === +processingStatus
);
}
return items;
})
@@ -70,10 +96,13 @@ export class ShelfOrderDetailsComponent {
firstName: item.firstName,
lastName: item.lastName,
customerNumber: item.buyerNumber,
estimatedShippingDate: item.estimatedShippingDate ? new Date(item.estimatedShippingDate) : undefined,
estimatedShippingDate: item.estimatedShippingDate
? new Date(item.estimatedShippingDate)
: undefined,
orderDate: new Date(item.orderDate),
orderNumber: item.orderNumber,
processingStatus: item.processingStatus,
processingStatusDate: new Date(item.processingStatusDate),
orderChannel: item.clientChannel,
compartmentCode: item.compartmentCode,
compartmentInfo: item.compartmentInfo,
@@ -86,28 +115,45 @@ export class ShelfOrderDetailsComponent {
);
showArrivedAndPrintCta$ = this.orderDetailsCard$.pipe(
map((details) => details.processingStatus === 16 || details.processingStatus === 8192) // wenn bestellt(=16) oder nachbestellt(=8192)
map(
(details) =>
details.processingStatus === 16 || details.processingStatus === 8192
) // wenn bestellt(=16) oder nachbestellt(=8192)
);
showPickUpCta$ = this.orderDetailsCard$.pipe(
map((details) => details.processingStatus === 128) // wenn eingetroffen(=128)
);
showPickUpPartialCollectCta$ = combineLatest([this.orderDetailsCard$, this.orderItems$]).pipe(
showPickUpPartialCollectCta$ = combineLatest([
this.orderDetailsCard$,
this.orderItems$,
]).pipe(
map(([details, items]) => {
return details.processingStatus === 128 && (items.length > 1 || items.some((i) => i.quantity > 1));
return (
details.processingStatus === 128 &&
(items.length > 1 || items.some((i) => i.quantity > 1))
);
}) // wenn eingetroffen(=128) und mehr als 1 Artikel
);
showBackToStoreCta$ = this.orderDetailsCard$.pipe(
map((details) => details.processingStatus === 1024 || details.processingStatus === 512)
map(
(details) =>
details.processingStatus === 1024 || details.processingStatus === 512
)
);
showAddToRemissionListCta$ = this.orderDetailsCard$.pipe(
map((details) => details.processingStatus === 1024 || details.processingStatus === 512)
map(
(details) =>
details.processingStatus === 1024 || details.processingStatus === 512
)
);
showReOrderCta$ = this.orderDetailsCard$.pipe(map((details) => details.processingStatus === 2048));
showReOrderCta$ = this.orderDetailsCard$.pipe(
map((details) => details.processingStatus === 2048)
);
constructor(
private activatedRoute: ActivatedRoute,
@@ -137,29 +183,43 @@ export class ShelfOrderDetailsComponent {
});
}
async changeProcessingStatus(status: OrderItemProcessingStatusValue, data: { compartmentInfo?: string } = {}) {
async changeProcessingStatus(
status: OrderItemProcessingStatusValue,
data: { compartmentInfo?: string } = {}
) {
let items = await this.orderItems$.pipe(first()).toPromise();
let results: ResponseArgsOfValueTupleOfOrderItemSubsetDTOAndOrderItemSubsetDTO[];
const navigate = this.partialPickup ? items.length === this.selectedForPartialPickup.size : true;
const navigate = this.partialPickup
? items.length === this.selectedForPartialPickup.size
: true;
if (status === 256) {
if (this.partialPickup) {
items = items.filter(({ orderItemId }) => this.selectedForPartialPickup.has(orderItemId));
items = items.filter(({ orderItemId }) =>
this.selectedForPartialPickup.has(orderItemId)
);
}
results = await this.detailsFacade.pickedUp(items, this.quantityForPartialPickup);
results = await this.detailsFacade.pickedUp(
items,
this.quantityForPartialPickup
);
} else if (status === 131072) {
results = await this.detailsFacade.backToStock(items);
} else if (status === 8192) {
results = await this.detailsFacade.reorder(items);
} else if (status === 128) {
results = await this.detailsFacade.arrived(items, data.compartmentInfo);
this.printAbholfachetikett(items.map(({ orderItemSubsetId }) => orderItemSubsetId));
this.printAbholfachetikett(
items.map(({ orderItemSubsetId }) => orderItemSubsetId)
);
} else {
const payloads = items.map(({ orderId, orderItemId, orderItemSubsetId }) => ({
orderId,
orderItemId,
orderItemSubsetId,
data: { processingStatus: status } as StatusValues,
}));
const payloads = items.map(
({ orderId, orderItemId, orderItemSubsetId }) => ({
orderId,
orderItemId,
orderItemSubsetId,
data: { processingStatus: status } as StatusValues,
})
);
results = await this.detailsFacade.changeStatus(payloads);
}
@@ -187,7 +247,10 @@ export class ShelfOrderDetailsComponent {
changeEstimatedShippingDate(estimatedShippingDate: Date | string) {
this.orderItems$.pipe(first()).subscribe((items) => {
this.detailsFacade.setEstimatedShippingDate({ items, estimatedShippingDate });
this.detailsFacade.setEstimatedShippingDate({
items,
estimatedShippingDate,
});
});
}
@@ -208,10 +271,12 @@ export class ShelfOrderDetailsComponent {
if (this.appService.isIPadEnv()) {
this.printerSlectionComponent.openDialog();
this.printerSlectionComponent.print.pipe(takeUntil(this.printerSlectionComponent.closed), take(1)).subscribe((printer) => {
print(printer);
this.printerSlectionComponent.closeModal();
});
this.printerSlectionComponent.print
.pipe(takeUntil(this.printerSlectionComponent.closed), take(1))
.subscribe((printer) => {
print(printer);
this.printerSlectionComponent.closeModal();
});
} else {
const defaultPrinter = await this.getDefaultPrinter();
print(defaultPrinter);
@@ -236,7 +301,9 @@ export class ShelfOrderDetailsComponent {
async navigateToDetails() {
const data = await race(
this.orderNumber$.pipe(map((orderNumber) => ({ orderNumber }))),
this.compartmentCode$.pipe(map((compartmentCode) => ({ compartmentCode })))
this.compartmentCode$.pipe(
map((compartmentCode) => ({ compartmentCode }))
)
)
.pipe(
withLatestFrom(this.processingStatus$),

View File

@@ -1,6 +1,13 @@
import { Subject, fromEvent, combineLatest } from 'rxjs';
import { Component, OnDestroy, OnInit, ViewChild, ElementRef, ChangeDetectionStrategy } from '@angular/core';
import {
Component,
OnDestroy,
OnInit,
ViewChild,
ElementRef,
ChangeDetectionStrategy,
} from '@angular/core';
import { SearchStateFacade } from 'apps/sales/src/app/store/customer';
import { first, takeUntil, map } from 'rxjs/operators';
import { groupBy } from 'apps/sales/src/app/utils';
@@ -19,11 +26,16 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy {
destroy$ = new Subject();
grouped$ = this.searchStateFacade.result$.pipe(map((results) => groupBy(results, (item) => (item ? item.buyerNumber : ''))));
grouped$ = this.searchStateFacade.result$.pipe(
map((results) => groupBy(results, (item) => (item ? item.buyerNumber : '')))
);
fetching$ = this.searchStateFacade.fetching$;
constructor(private searchStateFacade: SearchStateFacade, private shelfNavigationService: ShelfNavigationService) {}
constructor(
private searchStateFacade: SearchStateFacade,
private shelfNavigationService: ShelfNavigationService
) {}
ngOnInit() {
this.initScrollContainer();
@@ -43,16 +55,25 @@ export class ShelfSearchResultsComponent implements OnInit, OnDestroy {
reachedBottom() {
const scrollContainer: HTMLElement = this.scrollContainer.nativeElement;
return scrollContainer.scrollHeight - (scrollContainer.scrollTop + scrollContainer.clientHeight) - 100 <= 0;
return (
scrollContainer.scrollHeight -
(scrollContainer.scrollTop + scrollContainer.clientHeight) -
100 <=
0
);
}
async fetch(force = false) {
const [hits, result, fetching] = await combineLatest([this.searchStateFacade.hits$, this.searchStateFacade.result$, this.fetching$])
const [hits, result, fetching] = await combineLatest([
this.searchStateFacade.hits$,
this.searchStateFacade.result$,
this.fetching$,
])
.pipe(first())
.toPromise();
if (force || !hits || (!result.length && !fetching)) {
this.searchStateFacade.fetchResult();
this.searchStateFacade.fetchResult({});
}
}

View File

@@ -38,7 +38,7 @@ export class ShelfSearchFacadeService {
}
this.searchStateFacade.setInput(searchQuery);
return this.requestSearch();
return this.requestSearch(true);
}
searchWithBarcode(barcode: string) {
@@ -49,7 +49,7 @@ export class ShelfSearchFacadeService {
}
this.searchStateFacade.setInput(searchQuery);
return this.requestSearch();
return this.requestSearch(true);
}
searchForAutocomplete(
@@ -72,8 +72,8 @@ export class ShelfSearchFacadeService {
return this.requestAutocompleteSearch(autoCompleteQuery);
}
private requestSearch() {
return this.searchStateFacade.fetchResult();
private requestSearch(isNewSearch: boolean = false) {
return this.searchStateFacade.fetchResult({ isNewSearch });
}
private generateAutocompleteToken(params: {

View File

@@ -15,13 +15,11 @@ import {
flatMap,
} from 'rxjs/operators';
import {
OrderService,
StrictHttpResponse,
ListResponseArgsOfOrderItemListItemDTO,
ResponseArgsOfIEnumerableOfInputDTO,
AbholfachService,
} from '@swagger/oms';
import { BranchService } from '@sales/core-services';
import { SearchStateFacade } from './search.facade';
import { of, NEVER } from 'rxjs';
import {

View File

@@ -6,7 +6,10 @@ import * as selectors from './search.selectors';
import { switchMap, filter, map, first } from 'rxjs/operators';
import { SharedSelectors } from 'apps/sales/src/app/core/store/selectors/shared.selectors';
import { combineLatest } from 'rxjs';
import { selectFiltersToFiltersDictionary, primaryFiltersToFiltersDictionary } from './mappers';
import {
selectFiltersToFiltersDictionary,
primaryFiltersToFiltersDictionary,
} from './mappers';
import { Observable } from 'rxjs';
import { isNullOrUndefined } from 'util';
import { SelectFilter } from 'apps/sales/src/app/modules/filter';
@@ -51,23 +54,34 @@ export class SearchStateFacade {
}
get pendingInput$() {
return this.getProcessId$().pipe(switchMap((id) => this.getPendingInput$(id)));
return this.getProcessId$().pipe(
switchMap((id) => this.getPendingInput$(id))
);
}
get showNoResultError$() {
return this.getProcessId$().pipe(
switchMap((id) => combineLatest([this.getState$(id), this.getHasResult$(id)])),
map(([state, hasResults]) => (!hasResults && state === SearchProcessState.FETCHED ? true : false))
switchMap((id) =>
combineLatest([this.getState$(id), this.getHasResult$(id)])
),
map(([state, hasResults]) =>
!hasResults && state === SearchProcessState.FETCHED ? true : false
)
);
}
get primaryFilters$(): Observable<PrimaryFilterOption[]> {
return this.process$.pipe(switchMap((process) => this.getPrimaryFilters$(process.id)));
return this.process$.pipe(
switchMap((process) => this.getPrimaryFilters$(process.id))
);
}
get selectFilters$(): Observable<SelectFilter[]> {
return this.process$.pipe(
filter((process) => !isNullOrUndefined(process) && !isNullOrUndefined(process.filters)),
filter(
(process) =>
!isNullOrUndefined(process) && !isNullOrUndefined(process.filters)
),
switchMap((process) => this.getSelectedFilters$(process.id))
);
}
@@ -75,7 +89,9 @@ export class SearchStateFacade {
get hasActiveFilters$(): Observable<boolean> {
return this.selectedFilter$.pipe(
map((selectedFilters) => Object.values(selectedFilters)),
map((filterValues) => filterValues.reduce((acc, curr) => [...acc, curr], [])),
map((filterValues) =>
filterValues.reduce((acc, curr) => [...acc, curr], [])
),
map((flattenedFilters) => !!flattenedFilters.length)
);
}
@@ -86,7 +102,9 @@ export class SearchStateFacade {
return selectFilters.some((f) => {
if (f.options) {
return f.options.some((o) => {
return isNullOrUndefined(o.initial_selected_state) ? o.selected !== true : o.selected !== o.initial_selected_state;
return isNullOrUndefined(o.initial_selected_state)
? o.selected !== true
: o.selected !== o.initial_selected_state;
});
}
@@ -100,14 +118,19 @@ export class SearchStateFacade {
return this.primaryFilters$.pipe(
map((primaryFilters) => {
return primaryFilters.some((pf) =>
isNullOrUndefined(pf.initial_selected_state) ? pf.selected !== false : pf.selected !== pf.initial_selected_state
isNullOrUndefined(pf.initial_selected_state)
? pf.selected !== false
: pf.selected !== pf.initial_selected_state
);
})
);
}
get filtersChangedFromDefault$(): Observable<boolean> {
return combineLatest([this.selectedFilterChangedFromDefault$, this.primaryFilterChangedFromDefault$]).pipe(
return combineLatest([
this.selectedFilterChangedFromDefault$,
this.primaryFilterChangedFromDefault$,
]).pipe(
map(([selectFiltersChanged, primaryFiltersChanged]) => {
return selectFiltersChanged || primaryFiltersChanged;
})
@@ -117,8 +140,12 @@ export class SearchStateFacade {
get selectedFilter$(): Observable<{ [key: string]: string }> {
return combineLatest([this.selectFilters$, this.primaryFilters$]).pipe(
map(([selectFilters, primaryFilters]) => {
const selectFilterDictionary = selectFiltersToFiltersDictionary(selectFilters);
const primaryFiltersDictionary = primaryFiltersToFiltersDictionary(primaryFilters);
const selectFilterDictionary = selectFiltersToFiltersDictionary(
selectFilters
);
const primaryFiltersDictionary = primaryFiltersToFiltersDictionary(
primaryFilters
);
const mergedFilters = {
...selectFilterDictionary,
@@ -232,17 +259,26 @@ export class SearchStateFacade {
processId = await this.getProcessId();
}
const currentPrimaryFilters = await this.getPrimaryFilters$(processId).pipe(first()).toPromise();
const currentPrimaryFilters = await this.getPrimaryFilters$(processId)
.pipe(first())
.toPromise();
const indexOfUpdatedFilter = currentPrimaryFilters.findIndex((f) => f.id === primaryFilter.id);
const indexOfUpdatedFilter = currentPrimaryFilters.findIndex(
(f) => f.id === primaryFilter.id
);
updatedFilters = [
...currentPrimaryFilters.slice(0, indexOfUpdatedFilter),
primaryFilter,
...currentPrimaryFilters.slice(indexOfUpdatedFilter + 1, currentPrimaryFilters.length + 1),
...currentPrimaryFilters.slice(
indexOfUpdatedFilter + 1,
currentPrimaryFilters.length + 1
),
];
return this.store.dispatch(actions.setPrimaryFilters({ filters: updatedFilters, id: processId }));
return this.store.dispatch(
actions.setPrimaryFilters({ filters: updatedFilters, id: processId })
);
}
async resetPrimaryFilters(id?: number) {
@@ -263,12 +299,19 @@ export class SearchStateFacade {
this.store.dispatch(actions.resetSelectFilters({ id: processId }));
}
async fetchResult(id?: number) {
let processId = id;
async fetchResult(data: { id?: number; isNewSearch?: boolean }) {
let processId = data.id;
if (typeof processId !== 'number') {
processId = await this.getProcessId();
}
if (data.isNewSearch) {
return this.store.dispatch(
actions.fetchResult({ id: processId, skip: 0 })
);
}
this.store.dispatch(actions.fetchResult({ id: processId }));
}

View File

@@ -24,6 +24,10 @@
text-align: right;
}
.isa-font-size-24 {
font-size: 24px;
}
//TODO: _color.scss ausglagern
.isa-font-color-customer {
color: $isa-customer;