#667 Add Automplete Result Styling

This commit is contained in:
Sebastian
2020-06-23 14:42:41 +02:00
parent 50694b1e26
commit ce43e0261e
25 changed files with 472 additions and 164 deletions

View File

@@ -0,0 +1,7 @@
<div class="container" *ngIf="!!results">
<app-autocomplete-result-item
*ngFor="let result of results"
[result]="result"
(clicked)="onItemClicked($event)"
></app-autocomplete-result-item>
</div>

View File

@@ -0,0 +1,9 @@
@import '../../../../../scss/variables';
.container {
background-color: $content-background-color;
border-radius: 0 0 $input-round-borders $input-round-borders;
width: 550px;
box-sizing: border-box;
box-shadow: 0px 6px 24px 0px rgba(214, 215, 217, 0.8);
}

View File

@@ -0,0 +1,59 @@
import {
Component,
AfterViewInit,
ChangeDetectionStrategy,
Input,
ViewChildren,
QueryList,
HostListener,
Output,
EventEmitter,
} from '@angular/core';
import { OrderItemListItemDTO } from '@swagger/oms/lib';
import { ActiveDescendantKeyManager } from '@angular/cdk/a11y';
import { ResultItemComponent } from './result-item';
@Component({
selector: 'app-autocomplete-results',
templateUrl: 'autocomplete-results.component.html',
styleUrls: ['./autocomplete-results.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AutocompleteResultsComponent implements AfterViewInit {
@ViewChildren(ResultItemComponent) items: QueryList<ResultItemComponent>;
@Input() results: OrderItemListItemDTO[];
@Output() selectItem = new EventEmitter<
OrderItemListItemDTO & { shouldNavigate?: boolean }
>();
private keyManager: ActiveDescendantKeyManager<ResultItemComponent>;
constructor() {}
@HostListener('window:keyup', ['$event']) onKeyDown(event: KeyboardEvent) {
if (event.key === 'ArrowDown' || 'ArrowUp') {
this.keyManager.onKeydown(event);
if (this.keyManager.activeItem) {
this.selectItem.emit(this.keyManager.activeItem.result);
}
}
}
ngAfterViewInit() {
this.keyManager = new ActiveDescendantKeyManager(this.items).withWrap();
}
onItemClicked(item: OrderItemListItemDTO) {
console.log({ item });
this.keyManager.setActiveItem(this.getItemIndex(item));
this.selectItem.emit({
...this.keyManager.activeItem.result,
shouldNavigate: true,
});
}
private getItemIndex(item: OrderItemListItemDTO): number {
return this.results.indexOf(item);
}
}

View File

@@ -0,0 +1,12 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ResultItemComponent } from './result-item';
import { AutocompleteResultsComponent } from './autocomplete-results.component';
@NgModule({
imports: [CommonModule],
exports: [AutocompleteResultsComponent, ResultItemComponent],
declarations: [AutocompleteResultsComponent, ResultItemComponent],
providers: [],
})
export class AutocompleteResultsModule {}

View File

@@ -0,0 +1,5 @@
// start:ng42.barrel
export * from './autocomplete-results.component';
export * from './autocomplete-results.module';
// end:ng42.barrel

View File

@@ -0,0 +1,4 @@
// start:ng42.barrel
export * from './result-item.component';
// end:ng42.barrel

View File

@@ -0,0 +1,3 @@
<div class="item isa-font-lightgrey" (click)="clicked.emit(result)">
{{ result.firstName }} {{ result.lastName }}
</div>

View File

@@ -0,0 +1,24 @@
@import '../../../../../../scss/variables';
.item {
font-family: $font-family;
font-size: $font-size;
color: $text-black;
line-height: 21px;
padding-bottom: 16px;
padding-top: 16px;
padding-left: 28px;
padding-right: 28px;
}
:host.active {
.item {
background-color: $isa-branch-bg;
}
&:last-of-type {
.item {
border-radius: 0 0 $input-round-borders $input-round-borders;
}
}
}

View File

@@ -0,0 +1,40 @@
import {
Component,
ChangeDetectionStrategy,
Input,
HostBinding,
Output,
EventEmitter,
} from '@angular/core';
import { OrderItemListItemDTO } from '@swagger/oms/lib';
import { Highlightable } from '@angular/cdk/a11y';
@Component({
selector: 'app-autocomplete-result-item',
templateUrl: 'result-item.component.html',
styleUrls: ['./result-item.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ResultItemComponent implements Highlightable {
@Input() result: OrderItemListItemDTO;
@Output() clicked = new EventEmitter<OrderItemListItemDTO>();
private _isActive: boolean;
@HostBinding('class.active') get isActive() {
return this._isActive;
}
set isActive(isActive: boolean) {
this._isActive = isActive;
}
constructor() {}
setActiveStyles(): void {
this.isActive = true;
}
setInactiveStyles(): void {
this.isActive = false;
}
}

View File

@@ -1,4 +1,4 @@
<div class="input-wrapper">
<div class="input-wrapper" [class.extend-for-content]="mode === 'autocomplete'">
<input
focus
autocomplete="off"
@@ -9,7 +9,8 @@
name="shelf-search"
id="shelf-search-input"
[formControl]="searchForm"
(keyup.enter)="triggerSearch()"
(keyup.enter)="triggerSearch('enter')"
(keyup)="onInput($event)"
/>
<span class="isa-input-error" *ngIf="!!errorMessage.length">{{
errorMessage
@@ -30,13 +31,7 @@
class="isa-input-submit"
[class.scan]="!errorMessage && !(searchQuery$ | async) && isIPad"
type="submit"
(click)="triggerSearch()"
(click)="triggerSearch('click')"
></button>
</ng-container>
<div
class="autocomplete-results"
*ngFor="let result of autocompleteResults$ | async"
>
<!-- Create own component using ListKey CDK -->
</div>
</div>

View File

@@ -1,4 +1,4 @@
@import '../../../../../assets/scss/variables';
@import '../../../../../scss/variables';
app-search {
width: 80vw;
@@ -11,6 +11,24 @@ app-search {
align-items: center;
width: 80vw;
max-width: 550px;
border-radius: 30px;
background-color: $content-background-color;
border-radius: $input-round-borders;
box-shadow: 0px 6px 24px 0px rgba(214, 215, 217, 0.8);
transition: border-radius 1s linear;
&.extend-for-content {
border-radius: $input-round-borders $input-round-borders 0 0;
box-shadow: 0px -7px 10px -3px rgba(214, 215, 217, 0.8);
position: relative;
&::after {
content: '';
position: absolute;
top: 60px;
left: 20px;
width: calc(100% - 40px);
border-bottom: 2px solid #e9f0f8;
}
}
}

View File

@@ -8,10 +8,6 @@ import {
ChangeDetectionStrategy,
} from '@angular/core';
import { Store } from '@ngxs/store';
import { Process } from 'apps/sales/src/app/core/models/process.model';
import { AddProcess } from 'apps/sales/src/app/core/store/actions/process.actions';
import { AddBreadcrumb } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model';
import { Subject, Observable } from 'rxjs';
import { isNullOrUndefined } from 'util';
import { FormControl } from '@angular/forms';
@@ -25,17 +21,19 @@ import { FormControl } from '@angular/forms';
export class ShelfSearchbarComponent implements OnInit, OnDestroy {
searchForm: FormControl;
searchQuery$: Observable<string>;
autocompleteResults$: Observable<any[]>;
@Input() isIPad = false;
@Input() isFetchingData = false;
@Input() mode: 'standalone' | 'autocomplete' = 'standalone';
@Input() errorMessage = '';
@Input() placeholder =
'Kundenname, Abholfach, Abholschein, Kundenkartennummer';
@Output() change = new EventEmitter<string>();
@Output() reset = new EventEmitter<void>();
@Output() search = new EventEmitter<{
type: 'scan' | 'search';
value: string;
target: 'click' | 'enter';
}>();
destroy$ = new Subject();
@@ -64,7 +62,7 @@ export class ShelfSearchbarComponent implements OnInit, OnDestroy {
this.errorMessage = message;
}
triggerSearch() {
triggerSearch(target: 'click' | 'enter') {
const isValidInput = this.validateSearchInputBeforeSubmit(
this.searchForm.value
);
@@ -76,9 +74,16 @@ export class ShelfSearchbarComponent implements OnInit, OnDestroy {
this.search.emit({
type: this.isSearch() ? 'search' : 'scan',
value: this.searchForm.value,
target,
});
}
onInput(event: KeyboardEvent) {
if (!this.isNumberOrLetter(event.key)) {
this.change.emit(this.searchForm.value);
}
}
private validateSearchInputBeforeSubmit(searchInput: string): boolean {
return !isNullOrUndefined(searchInput) && searchInput.length >= 1;
}
@@ -87,130 +92,7 @@ export class ShelfSearchbarComponent implements OnInit, OnDestroy {
return this.searchForm.value && this.searchForm.value.length;
}
/* search2(searchParams: string) {
const branchNumber = this.store.selectSnapshot(
BranchSelectors.getUserBranch
);
this.collectingShelf
.searchShelfHasResultsWithResult(searchParams, branchNumber)
.pipe(take(1))
.subscribe((reponse: ListResponseArgsOfOrderItemListItemDTO) => {
if (reponse) {
if (
reponse.hits > 1 ||
(reponse.result && reponse.result.length > 1)
) {
this.store.dispatch(
new SetShelfSearch(<ShelfSearch>{
input: searchParams,
branchnumber: branchNumber,
})
);
sessionStorage.removeItem(SHELF_SCROLL_INDEX);
this.store
.dispatch(
new SetCachedResults({
result: this.mapper.fromOrderItemListItemDTOArrayToCollectingShelfOrder(
reponse.result,
this.collectingShelf,
true
),
hits: reponse.hits,
})
)
.toPromise()
.then(() => {
// this.searchInput.stopLoading();
this.store.dispatch(new SetCollectingShelfCacheState(true));
this.navigateToRoute(
'/shelf/results',
`${searchParams} (${
reponse.hits ? reponse.hits : reponse.result.length
} Ergebnisse)`
);
});
} else if (
reponse.hits === 1 ||
(reponse.result && reponse.result.length === 1)
) {
this.details(reponse.result[0]);
this.store.dispatch(new ClearCachedResults());
} else {
// this.searchInput.stopLoading();
this.store.dispatch(new ClearCachedResults());
this.error = 'Ergibt keine Suchergebnisse';
}
} else {
// this.searchInput.stopLoading();
this.store.dispatch(new ClearCachedResults());
this.error = 'Ergibt keine Suchergebnisse';
}
});
}
details(order: OrderItemListItemDTO) {
if (order && (order.compartmentCode || order.orderId)) {
const path = `/shelf/details/${
order.compartmentCode ? order.compartmentCode : order.orderId
}/${order.orderId}/${order.processingStatus}/${
order.compartmentCode ? 'c' : 'o'
}`;
this.store.dispatch(
new AddBreadcrumb(
<Breadcrumb>{
name: order.firstName + ' ' + order.lastName,
path: path,
},
'shelf'
)
);
this.store.dispatch(new ChangeCurrentRoute(path));
this.router.navigate([path]);
}
}
private navigateToRoute(route: string, breadcrumbName: string) {
this.store.dispatch(
new AddBreadcrumb(
<Breadcrumb>{
name: breadcrumbName,
path: route,
},
'shelf'
)
);
this.store.dispatch(new ChangeCurrentRoute(route));
this.router.navigate([route]);
}
createTab() {
const processExists =
this.store.selectSnapshot(ProcessSelectors.getProcessesCount) > 0;
if (!processExists) {
this.createProcess();
}
}
clear() {
this.error = '';
} */
private createProcess() {
const newProcess = <Process>{
id: 1,
name: 'Vorgang 1',
currentRoute: '/shelf/search',
};
this.store.dispatch(new AddProcess(newProcess));
this.store.dispatch(
new AddBreadcrumb(
<Breadcrumb>{
name: 'Abholfach',
path: '/shelf/search',
},
'shelf'
)
);
private isNumberOrLetter(key: string): boolean {
return key.includes('Digit') || key.includes('Key');
}
}

View File

@@ -3,5 +3,13 @@ import { BehaviorSubject } from 'rxjs';
export abstract class ShelfSearchDeviceComponent {
isFetchingData$: BehaviorSubject<boolean>;
errorMessage$: BehaviorSubject<string>;
triggerSearch({ type, value }: { type: 'search' | 'scan'; value: string }) {}
triggerSearch({
type,
value,
target,
}: {
type: 'search' | 'scan';
value: string;
target: 'click' | 'enter';
}) {}
}

View File

@@ -2,7 +2,14 @@
<app-shelf-searchbar
[isFetchingData]="isFetchingData$ | async"
[errorMessage]="errorMessage$ | async"
[mode]="searchMode$ | async"
(change)="updateAutocomplete($event)"
(search)="triggerSearch($event)"
(reset)="reset()"
></app-shelf-searchbar>
<app-autocomplete-results
*ngIf="(searchMode$ | async) === 'autocomplete'"
[results]="autocompleteResult$ | async"
(selectItem)="selectedItem$.next($event)"
></app-autocomplete-results>
</div>

View File

@@ -1,14 +1,32 @@
import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core';
import { Subject, BehaviorSubject } from 'rxjs';
import {
Component,
ChangeDetectionStrategy,
OnDestroy,
OnInit,
} from '@angular/core';
import { Subject, BehaviorSubject, Observable, of } from 'rxjs';
import {
ShelfSearchFacadeService,
ShelfStoreFacadeService,
ShelfNavigationService,
} from '../../../shared/services';
import { ShelfSearchDeviceComponent } from '../../../defs';
import { takeUntil, first } from 'rxjs/operators';
import {
takeUntil,
first,
distinctUntilChanged,
debounceTime,
switchMap,
map,
filter,
withLatestFrom,
} from 'rxjs/operators';
import { SHELF_SCROLL_INDEX } from 'apps/sales/src/app/core/utils/app.constants';
import { ListResponseArgsOfOrderItemListItemDTO } from '@swagger/oms/lib';
import {
ListResponseArgsOfOrderItemListItemDTO,
OrderItemListItemDTO,
} from '@swagger/oms/lib';
import { isNullOrUndefined } from 'util';
@Component({
selector: 'app-shelf-search-desktop',
@@ -17,10 +35,16 @@ import { ListResponseArgsOfOrderItemListItemDTO } from '@swagger/oms/lib';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShelfSearchDesktopComponent
implements OnDestroy, ShelfSearchDeviceComponent {
implements OnInit, OnDestroy, ShelfSearchDeviceComponent {
destroy$ = new Subject();
isFetchingData$ = new BehaviorSubject<boolean>(false);
errorMessage$ = new BehaviorSubject<string>('');
autocompleteQueryString$ = new BehaviorSubject<string>('');
autocompleteResult$: Observable<OrderItemListItemDTO[]>;
searchMode$: Observable<'standalone' | 'autocomplete'>;
selectedItem$ = new BehaviorSubject<
OrderItemListItemDTO & { shouldNavigate?: boolean }
>(null);
constructor(
private shelfSearchService: ShelfSearchFacadeService,
@@ -28,6 +52,12 @@ export class ShelfSearchDesktopComponent
private shelfNavigationService: ShelfNavigationService
) {}
ngOnInit() {
this.setupAutocompletion();
this.setUpSearchMode();
this.setUpNavigationToDetailsPage();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
@@ -35,13 +65,26 @@ export class ShelfSearchDesktopComponent
reset() {
this.setIsFetchingData(false);
this.autocompleteQueryString$.next('');
this.resetError();
}
triggerSearch({ value }: { value: string }) {
triggerSearch({
value,
target,
}: {
value: string;
target: 'click' | 'enter';
}) {
this.setIsFetchingData(true);
this.resetError();
if (this.shouldNavigateToSelectedItem(target)) {
return this.shelfNavigationService.navigateToDetails(
this.selectedItem$.value
);
}
this.shelfSearchService
.search(value)
.pipe(takeUntil(this.destroy$), first())
@@ -51,6 +94,46 @@ export class ShelfSearchDesktopComponent
);
}
updateAutocomplete(value: string) {
this.autocompleteQueryString$.next(value);
}
private setupAutocompletion() {
this.autocompleteResult$ = this.autocompleteQueryString$.pipe(
distinctUntilChanged(),
debounceTime(250),
switchMap((queryString: string) => {
if (this.isValidQuery(queryString)) {
return this.shelfSearchService
.search(queryString)
.pipe(map((result) => result.result && result.result.slice(0, 5)));
}
return of([]);
})
);
}
private setUpSearchMode() {
this.searchMode$ = this.autocompleteResult$.pipe(
map((result) =>
!!result && !!result.length ? 'autocomplete' : 'standalone'
)
);
}
private setUpNavigationToDetailsPage() {
this.selectedItem$
.pipe(
takeUntil(this.destroy$),
filter((item) => !isNullOrUndefined(item)),
distinctUntilChanged(),
filter(({ shouldNavigate }) => !!shouldNavigate),
map(({ shouldNavigate, ...item }) => item)
)
.subscribe((item) => this.shelfNavigationService.navigateToDetails(item));
}
private handleSearchResult(
result: ListResponseArgsOfOrderItemListItemDTO,
value: string
@@ -104,4 +187,12 @@ export class ShelfSearchDesktopComponent
private setErrorMessage(message: string) {
this.errorMessage$.next(message);
}
private isValidQuery(queryString): boolean {
return !!queryString && queryString.length > 3;
}
private shouldNavigateToSelectedItem(target: 'click' | 'enter'): boolean {
return !!this.selectedItem$.value && target === 'enter';
}
}

View File

@@ -2,9 +2,10 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ShelfSearchDesktopComponent } from './shelf-search-desktop.component';
import { ShelfSearchBarModule } from '../../../components';
import { AutocompleteResultsModule } from '../../../components/autocomplete-results';
@NgModule({
imports: [CommonModule, ShelfSearchBarModule],
imports: [CommonModule, ShelfSearchBarModule, AutocompleteResultsModule],
exports: [ShelfSearchDesktopComponent],
declarations: [ShelfSearchDesktopComponent],
providers: [],

View File

@@ -3,9 +3,16 @@
[isFetchingData]="isFetchingData$ | async"
[errorMessage]="errorMessage$ | async"
[isIPad]="true"
[mode]="searchMode$ | async"
(change)="updateAutocomplete($event)"
(search)="triggerSearch($event)"
(reset)="reset()"
></app-shelf-searchbar>
<app-autocomplete-results
*ngIf="(searchMode$ | async) === 'autocomplete'"
[results]="autocompleteResult$ | async"
(selectItem)="selectedItem$.next($event)"
></app-autocomplete-results>
<lib-collecting-shelf-scanner
#scanner

View File

@@ -1,20 +1,31 @@
import {
Component,
OnDestroy,
OnInit,
ChangeDetectionStrategy,
ViewChild,
} from '@angular/core';
import { BarcodeScannerScanditComponent } from 'shared/lib/barcode-scanner';
import { ShelfSearchFacadeService } from '../../../shared/services/shelf-search.facade.service';
import { ListResponseArgsOfOrderItemListItemDTO } from 'apps/swagger/oms/src/lib';
import { Observable, Subject, BehaviorSubject } from 'rxjs';
import { first, takeUntil } from 'rxjs/operators';
import { Observable, Subject, BehaviorSubject, of } from 'rxjs';
import {
first,
takeUntil,
distinctUntilChanged,
debounceTime,
switchMap,
map,
filter,
} from 'rxjs/operators';
import {
ShelfStoreFacadeService,
ShelfNavigationService,
} from '../../../shared/services';
import { SHELF_SCROLL_INDEX } from 'apps/sales/src/app/core/utils/app.constants';
import { ShelfSearchDeviceComponent } from '../../../defs';
import { OrderItemListItemDTO } from '@swagger/oms/lib';
import { isNullOrUndefined } from 'util';
@Component({
selector: 'app-shelf-search-ipad',
@@ -23,12 +34,18 @@ import { ShelfSearchDeviceComponent } from '../../../defs';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShelfSearchIpadComponent
implements OnDestroy, ShelfSearchDeviceComponent {
implements OnInit, OnDestroy, ShelfSearchDeviceComponent {
@ViewChild('scanner', { static: false })
scanner: BarcodeScannerScanditComponent;
destroy$ = new Subject();
isFetchingData$ = new BehaviorSubject<boolean>(false);
errorMessage$ = new BehaviorSubject<string>('');
autocompleteQueryString$ = new BehaviorSubject<string>('');
autocompleteResult$: Observable<OrderItemListItemDTO[]>;
searchMode$: Observable<'standalone' | 'autocomplete'>;
selectedItem$ = new BehaviorSubject<
OrderItemListItemDTO & { shouldNavigate?: boolean }
>(null);
constructor(
private shelfSearchService: ShelfSearchFacadeService,
@@ -36,6 +53,12 @@ export class ShelfSearchIpadComponent
private shelfNavigationService: ShelfNavigationService
) {}
ngOnInit() {
this.setupAutocompletion();
this.setUpSearchMode();
this.setUpNavigationToDetailsPage();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
@@ -43,18 +66,33 @@ export class ShelfSearchIpadComponent
reset() {
this.setIsFetchingData(false);
this.autocompleteQueryString$.next('');
this.resetError();
}
triggerBarcodeSearch(barcode: string) {
this.triggerSearch({ type: 'scan', value: barcode });
this.triggerSearch({ type: 'scan', value: barcode, target: 'click' });
}
triggerSearch({ type, value }: { type: 'search' | 'scan'; value: string }) {
triggerSearch({
type,
value,
target,
}: {
type: 'search' | 'scan';
value: string;
target: 'click' | 'enter';
}) {
let result$: Observable<ListResponseArgsOfOrderItemListItemDTO>;
this.setIsFetchingData(true);
this.resetError();
if (this.shouldNavigateToSelectedItem(target)) {
return this.shelfNavigationService.navigateToDetails(
this.selectedItem$.value
);
}
if (type === 'search') {
result$ = this.shelfSearchService.search(value);
} else if (type === 'scan') {
@@ -69,6 +107,46 @@ export class ShelfSearchIpadComponent
);
}
updateAutocomplete(value: string) {
this.autocompleteQueryString$.next(value);
}
private setupAutocompletion() {
this.autocompleteResult$ = this.autocompleteQueryString$.pipe(
distinctUntilChanged(),
debounceTime(250),
switchMap((queryString: string) => {
if (this.isValidQuery(queryString)) {
return this.shelfSearchService
.search(queryString)
.pipe(map((result) => result.result && result.result.slice(0, 5)));
}
return of([]);
})
);
}
private setUpSearchMode() {
this.searchMode$ = this.autocompleteResult$.pipe(
map((result) =>
!!result && !!result.length ? 'autocomplete' : 'standalone'
)
);
}
private setUpNavigationToDetailsPage() {
this.selectedItem$
.pipe(
takeUntil(this.destroy$),
filter((item) => !isNullOrUndefined(item)),
distinctUntilChanged(),
filter(({ shouldNavigate }) => !!shouldNavigate),
map(({ shouldNavigate, ...item }) => item)
)
.subscribe((item) => this.shelfNavigationService.navigateToDetails(item));
}
private handleSearchResult(
result: ListResponseArgsOfOrderItemListItemDTO,
value: string
@@ -122,4 +200,12 @@ export class ShelfSearchIpadComponent
private setErrorMessage(message: string) {
this.errorMessage$.next(message);
}
private isValidQuery(queryString): boolean {
return !!queryString && queryString.length > 3;
}
private shouldNavigateToSelectedItem(target: 'click' | 'enter'): boolean {
return !!this.selectedItem$.value && target === 'enter';
}
}

View File

@@ -4,9 +4,15 @@ import { CommonModule } from '@angular/common';
import { CollectingShelfScannerModule } from 'shared/public_api';
import { ShelfSearchIpadComponent } from './shelf-search-ipad.component';
import { ShelfSearchBarModule } from '../../../components';
import { AutocompleteResultsModule } from '../../../components/autocomplete-results';
@NgModule({
imports: [CommonModule, CollectingShelfScannerModule, ShelfSearchBarModule],
imports: [
CommonModule,
CollectingShelfScannerModule,
ShelfSearchBarModule,
AutocompleteResultsModule,
],
exports: [ShelfSearchIpadComponent],
declarations: [ShelfSearchIpadComponent],
providers: [],

View File

@@ -3,9 +3,15 @@ import { NgModule } from '@angular/core';
import { ShelfSearchComponent } from './shelf-search.component';
import { ShelfSearchIpadModule } from './shelf-search-ipad';
import { ShelfSearchDesktopModule } from './shelf-search-desktop';
import { AutocompleteResultsModule } from '../../components/autocomplete-results';
@NgModule({
imports: [CommonModule, ShelfSearchIpadModule, ShelfSearchDesktopModule],
imports: [
CommonModule,
ShelfSearchIpadModule,
ShelfSearchDesktopModule,
AutocompleteResultsModule,
],
exports: [ShelfSearchComponent],
declarations: [ShelfSearchComponent],
providers: [],

View File

@@ -2,15 +2,21 @@ import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Store } from '@ngxs/store';
import { AddBreadcrumb } from 'apps/sales/src/app/core/store/actions/breadcrumb.actions';
import { ChangeCurrentRoute } from 'apps/sales/src/app/core/store/actions/process.actions';
import {
ChangeCurrentRoute,
AddProcess,
} from 'apps/sales/src/app/core/store/actions/process.actions';
import { Breadcrumb } from 'apps/sales/src/app/core/models/breadcrumb.model';
import { OrderItemListItemDTO } from '@swagger/oms/lib';
import { ProcessSelectors } from 'apps/sales/src/app/core/store/selectors/process.selectors';
import { Process } from 'apps/sales/src/app/core/models/process.model';
@Injectable({ providedIn: 'root' })
export class ShelfNavigationService {
constructor(private store: Store, private router: Router) {}
navigateToDetails(order: OrderItemListItemDTO) {
this.createTab();
const path = this.getDetailsPath(order);
const breadcrumb = this.getDetailsBreadcrumb(order);
@@ -24,9 +30,9 @@ export class ShelfNavigationService {
searchQuery: string;
numberOfHits: number;
}) {
this.createTab();
const path = '/shelf/results';
const breadcrumb = this.getResultListBreadcrumb(searchQuery, numberOfHits);
console.log('navigateo');
this.navigateToRoute(path, breadcrumb);
}
@@ -62,4 +68,31 @@ export class ShelfNavigationService {
order.compartmentCode ? 'c' : 'o'
}`;
}
private createTab() {
const processExists =
this.store.selectSnapshot(ProcessSelectors.getProcessesCount) > 0;
if (!processExists) {
this.createProcess();
}
}
private createProcess() {
const newProcess = <Process>{
id: 1,
name: 'Vorgang 1',
currentRoute: '/shelf/search',
};
this.store.dispatch(new AddProcess(newProcess));
this.store.dispatch(
new AddBreadcrumb(
<Breadcrumb>{
name: 'Abholfach',
path: '/shelf/search',
},
'shelf'
)
);
}
}

View File

@@ -13,10 +13,7 @@ export class ShelfSearchFacadeService {
string
>;
constructor(
private store: Store,
private collectingShelfService: CollectingShelfService
) {}
constructor(private collectingShelfService: CollectingShelfService) {}
search(queryString: string) {
const searchParams = queryString.trim();

View File

@@ -9,7 +9,9 @@ $max-content-width: 916px;
/* COLORS */
$text-light: #fff;
$text-black: #000000;
$isa-red: #f70400;
$isa-branch-bg: #e6eff9;
$text-grey: #596470;
$text-lightgrey: #596470;
@@ -30,11 +32,13 @@ $content-border-radius: 5px;
/* HEADLINE */
$headline-font-size-l: 26px;
$headline-font-size-m: 22px;
$headline-font-size-s: 20px;
/* INPUT */
$input-height-size-l: 60px;
$input-font-size: 21px;
$input-letter-spacing: -0.01rem;
$input-round-borders: 30px;
/* BUTTON */
$button-font-weight: bold;

View File

@@ -3,6 +3,10 @@
font-weight: $font-weight-bold;
font-size: $headline-font-size-l;
text-align: center;
@include mq-desktop() {
margin-bottom: 12px;
}
}
.isa-content-subline {

View File

@@ -14,7 +14,7 @@ body {
width: 100%;
position: fixed;
overflow: hidden;
background-color: #e6eff9;
background-color: $isa-branch-bg;
&.branch {
background-color: #edeff0;