Merged PR 1167: #2989 Scanner Refactoring

#2989  Scanner Refactoring
This commit is contained in:
Lorenz Hilpert
2022-04-06 10:18:20 +00:00
committed by Andreas Schickinger
parent ec97d1e84a
commit af8a3d89af
45 changed files with 69 additions and 347 deletions

View File

@@ -23,12 +23,12 @@ export class DevScanAdapter implements ScanAdapter {
return new Observable((observer) => {
const modalRef = this._modal.open({
content: UiPromptModalComponent,
title: 'Anmeldung',
title: 'Scannen',
data: {
message: 'Bitte geben Sie Ihren Login Code ein',
placeholder: 'Login Code',
message: 'Diese Eingabemaske dient nur zu Entwicklungs und Testzwecken.',
placeholder: 'Scan Code',
confirmText: 'weiter',
cancelText: 'Anmeldung mit Benutzername und Passwort',
cancelText: 'abbrechen',
} as PromptModalData,
});

View File

@@ -16,6 +16,10 @@ export class ScanAdapterService {
return this.scanners().find((scanner) => scanner.isPrimary()) || this.scanners().find(() => true);
}
isReady() {
return this.scanAdapters.some((adapter) => adapter.isReady());
}
scan() {
const primaryScanner = this.scanner();
if (primaryScanner) {

View File

@@ -1,13 +1,13 @@
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { UiFilterAutocompleteProvider, UiFilterScanProvider } from '@ui/filter';
import { UiFilterAutocompleteProvider } from '@ui/filter';
import { isEqual } from 'lodash';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { filter, first, map, takeUntil, withLatestFrom } from 'rxjs/operators';
import { ArticleSearchService } from './article-search.store';
import { FocusSearchboxEvent } from './focus-searchbox.event';
import { ArticleSearchMainAutocompleteProvider, ArticleSearchMainScanProviderService } from './providers';
import { ArticleSearchMainAutocompleteProvider } from './providers';
@Component({
selector: 'page-article-search',
@@ -21,11 +21,6 @@ import { ArticleSearchMainAutocompleteProvider, ArticleSearchMainScanProviderSer
useClass: ArticleSearchMainAutocompleteProvider,
multi: true,
},
{
provide: UiFilterScanProvider,
useClass: ArticleSearchMainScanProviderService,
multi: true,
},
],
changeDetection: ChangeDetectionStrategy.OnPush,
})

View File

@@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { UiFilterScanProvider } from '@ui/filter';
import { NativeContainerService } from 'native-container';
import { Observable } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators';
@Injectable()
export class ArticleSearchMainScanProviderService extends UiFilterScanProvider {
for = 'main';
constructor(private nativeContainer: NativeContainerService) {
super();
}
scan(): Observable<string> {
return this.nativeContainer.openScanner('scanBook').pipe(
filter((result) => result.status !== 'IN_PROGRESS'),
map((result) => result?.data),
catchError((err) => {
return '';
})
);
}
}

View File

@@ -1,4 +1,3 @@
// start:ng42.barrel
export * from './article-search-main-autocomplete.provider';
export * from './article-search-main-scan.provider';
// end:ng42.barrel

View File

@@ -12,6 +12,7 @@
(search)="applyFilter(filter)"
[hint]="searchboxHint$ | async"
resizeInputOptionsToElement="page-article-search-filter .cta-wrapper"
[scanner]="true"
></ui-filter>
</div>
</div>

View File

@@ -11,6 +11,7 @@
[inputGroup]="filter?.input | group: 'main'"
(search)="search(filter)"
[showDescription]="false"
[scanner]="true"
></ui-filter-input-group-main>
<div class="recent-searches-wrapper">

View File

@@ -1,20 +0,0 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator';
import { NativeContainerService } from 'native-container';
import { CheckoutDummyScanProvider } from './checkout-dummy-scan.provider';
describe('GoodsInSearchMainScanProvider', () => {
let spectator: SpectatorService<CheckoutDummyScanProvider>;
const naticeContainerMock = jasmine.createSpyObj<NativeContainerService>(['openScanner', 'isUiWebview']);
const createProvider = createServiceFactory({
service: CheckoutDummyScanProvider,
});
beforeEach(() => {
spectator = createProvider();
});
it('should create', () => {
expect(spectator.service).toBeTruthy();
});
});

View File

@@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { UiFilterScanProvider } from '@ui/filter';
import { NativeContainerService } from 'native-container';
import { Observable } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators';
@Injectable()
export class CheckoutDummyScanProvider extends UiFilterScanProvider {
for = 'dummy';
constructor(private nativeContainer: NativeContainerService) {
super();
}
scan(): Observable<string> {
return this.nativeContainer.openScanner('scanBook').pipe(
filter((result) => result.status !== 'IN_PROGRESS'),
map((result) => result?.data),
catchError((err) => {
return '';
})
);
}
}

View File

@@ -19,9 +19,9 @@
(search)="search($event)"
(scan)="search($event)"
[loading]="loading$ | async"
[scanProvider]="scanProvider"
[hint]="message$ | async"
tabindex="0"
[scanner]="true"
>
</ui-searchbox>
</ui-form-control>

View File

@@ -1,29 +1,19 @@
import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit, Optional } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { ApplicationService } from '@core/application';
import { ItemDTO } from '@swagger/cat';
import { DateAdapter } from '@ui/common';
import { UiFilterScanProvider } from '@ui/filter';
import { UiErrorModalComponent, UiModalRef, UiModalService } from '@ui/modal';
import { Subject } from 'rxjs';
import { first, shareReplay, takeUntil } from 'rxjs/operators';
import { CheckoutDummyScanProvider } from './checkout-dummy-scan.provider';
import { CheckoutDummyStore } from './checkout-dummy.store';
@Component({
selector: 'page-checkout-dummy',
templateUrl: 'checkout-dummy.component.html',
styleUrls: ['checkout-dummy.component.scss'],
providers: [
CheckoutDummyStore,
{
provide: UiFilterScanProvider,
useClass: CheckoutDummyScanProvider,
multi: true,
},
FormBuilder,
],
providers: [CheckoutDummyStore, FormBuilder],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CheckoutDummyComponent implements OnInit, OnDestroy {
@@ -35,11 +25,6 @@ export class CheckoutDummyComponent implements OnInit, OnDestroy {
message$ = this._store.message$;
loading$ = this._store.fetching$.pipe(shareReplay());
private _scanProvider: UiFilterScanProvider;
get scanProvider() {
return this._scanProvider;
}
// Datepicker
minDate = this._dateAdapter.addCalendarDays(new Date(), -1);
estimatedShippingDate$ = this._store.estimatedShippingDate$.pipe(shareReplay());
@@ -51,7 +36,6 @@ export class CheckoutDummyComponent implements OnInit, OnDestroy {
_onDestroy$ = new Subject<void>();
constructor(
@Inject(UiFilterScanProvider) @Optional() private scanProviders: UiFilterScanProvider[],
private _router: Router,
private _fb: FormBuilder,
private _dateAdapter: DateAdapter,
@@ -62,7 +46,6 @@ export class CheckoutDummyComponent implements OnInit, OnDestroy {
) {}
ngOnInit() {
this._scanProvider = this.scanProviders?.find((provider) => provider.for === 'dummy');
this.initForm();
this._store.item$.pipe(takeUntil(this._onDestroy$)).subscribe((item) => {

View File

@@ -12,6 +12,7 @@
(search)="applyFilter(filter)"
[hint]="store.message$ | async"
resizeInputOptionsToElement="page-customer-search-filter .sticky-cta-wrapper"
[scanner]="true"
></ui-filter>
<div class="sticky-cta-wrapper">

View File

@@ -18,6 +18,7 @@
[inputGroup]="filter?.input | group: 'main'"
[loading]="fetching$ | async"
(search)="search(filter)"
[scanner]="true"
>
</ui-filter-input-group-main>
</ng-container>

View File

@@ -11,6 +11,7 @@
(search)="applyFilter()"
[hint]="message"
resizeInputOptionsToElement="page-goods-in-search-filter .cta-wrapper"
[scanner]="true"
></ui-filter>
</div>
</div>

View File

@@ -3,14 +3,13 @@ import { Component, ChangeDetectionStrategy, OnInit, OnDestroy } from '@angular/
import { ActivatedRoute } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { UiFilterAutocompleteProvider, UiFilterScanProvider } from '@ui/filter';
import { UiFilterAutocompleteProvider } from '@ui/filter';
import { isEqual } from 'lodash';
import { Subject } from 'rxjs';
import { filter, first, map, takeUntil, withLatestFrom } from 'rxjs/operators';
import { GoodsInSearchStore } from './goods-in-search.store';
import { GoodsInSearchMainAutocompleteProvider } from './providers/goods-in-search-main-autocomplete.provider';
import { GoodsInSearchMainScanProvider } from './providers/goods-in-search-main-scan.provider';
@Component({
selector: 'page-goods-in-search',
@@ -24,11 +23,6 @@ import { GoodsInSearchMainScanProvider } from './providers/goods-in-search-main-
useClass: GoodsInSearchMainAutocompleteProvider,
multi: true,
},
{
provide: UiFilterScanProvider,
useClass: GoodsInSearchMainScanProvider,
multi: true,
},
],
animations: [
trigger('slideInOut', [

View File

@@ -1,20 +0,0 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator';
import { NativeContainerService } from 'native-container';
import { GoodsInSearchMainScanProvider } from './goods-in-search-main-scan.provider';
describe('GoodsInSearchMainScanProvider', () => {
let spectator: SpectatorService<GoodsInSearchMainScanProvider>;
const naticeContainerMock = jasmine.createSpyObj<NativeContainerService>(['openScanner', 'isUiWebview']);
const createProvider = createServiceFactory({
service: GoodsInSearchMainScanProvider,
});
beforeEach(() => {
spectator = createProvider();
});
it('should create', () => {
expect(spectator.service).toBeTruthy();
});
});

View File

@@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { UiFilterScanProvider } from '@ui/filter';
import { NativeContainerService } from 'native-container';
import { Observable } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators';
@Injectable()
export class GoodsInSearchMainScanProvider extends UiFilterScanProvider {
for = 'main';
constructor(private nativeContainer: NativeContainerService) {
super();
}
scan(): Observable<string> {
return this.nativeContainer.openScanner('scanBook').pipe(
filter((result) => result.status !== 'IN_PROGRESS'),
map((result) => result?.data),
catchError((err) => {
return '';
})
);
}
}

View File

@@ -24,6 +24,7 @@
[loading]="loading$ | async"
(search)="search()"
[hint]="message"
[scanner]="true"
></ui-filter-input-group-main>
</ng-container>
</div>

View File

@@ -11,6 +11,7 @@
(search)="applyFilter()"
[hint]="message"
resizeInputOptionsToElement="page-goods-out-search-filter .cta-wrapper"
[scanner]="true"
></ui-filter>
</div>
</div>

View File

@@ -3,13 +3,12 @@ import { Component, ChangeDetectionStrategy, OnInit, OnDestroy } from '@angular/
import { ActivatedRoute } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { UiFilterAutocompleteProvider, UiFilterScanProvider } from '@ui/filter';
import { UiFilterAutocompleteProvider } from '@ui/filter';
import { isEqual } from 'lodash';
import { Subject } from 'rxjs';
import { filter, first, map, takeUntil, withLatestFrom } from 'rxjs/operators';
import { GoodsOutSearchStore } from './goods-out-search.store';
import { GoodsOutSearchMainAutocompleteProvider } from './providers/goods-out-search-main-autocomplete.provider';
import { GoodsOutSearchMainScanProvider } from './providers/goods-out-search-main-scan.provider';
@Component({
selector: 'page-goods-out-search',
@@ -23,11 +22,6 @@ import { GoodsOutSearchMainScanProvider } from './providers/goods-out-search-mai
useClass: GoodsOutSearchMainAutocompleteProvider,
multi: true,
},
{
provide: UiFilterScanProvider,
useClass: GoodsOutSearchMainScanProvider,
multi: true,
},
],
animations: [
trigger('slideInOut', [

View File

@@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { UiFilterScanProvider } from '@ui/filter';
import { NativeContainerService } from 'native-container';
import { Observable } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators';
@Injectable()
export class GoodsOutSearchMainScanProvider extends UiFilterScanProvider {
for = 'main';
constructor(private nativeContainer: NativeContainerService) {
super();
}
scan(): Observable<string> {
return this.nativeContainer.openScanner('scanBook').pipe(
filter((result) => result.status !== 'IN_PROGRESS'),
map((result) => result?.data),
catchError((err) => {
return '';
})
);
}
}

View File

@@ -14,6 +14,7 @@
[loading]="loading$ | async"
(search)="search()"
[hint]="message"
[scanner]="true"
></ui-filter-input-group-main>
</ng-container>
</div>

View File

@@ -10,9 +10,9 @@
placeholder="ISBN / EAN"
class="mx-auto mt-12 w-5/6"
(search)="search($event)"
(scan)="search($event)"
[loading]="loading$ | async"
[hint]="hint$ | async"
(scan)="search($event)"
[scanProvider]="scanProvider"
[scanner]="true"
></ui-searchbox>
</div>

View File

@@ -3,7 +3,6 @@ import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { DomainRemissionService } from '@domain/remission';
import { UiFilterScanProvider } from '@ui/filter';
import { UiModalService } from '@ui/modal';
import { NEVER, Subject } from 'rxjs';
import { catchError, switchMap, takeUntil, tap } from 'rxjs/operators';
@@ -24,13 +23,7 @@ export class AddProductComponent implements OnInit, OnDestroy {
hint$ = new Subject<string>();
private _scanProvider: UiFilterScanProvider;
get scanProvider() {
return this._scanProvider;
}
constructor(
@Inject(UiFilterScanProvider) @Optional() private scanProviders: UiFilterScanProvider[],
private _remiService: DomainRemissionService,
private _modal: UiModalService,
private _breadcrumb: BreadcrumbService,
@@ -40,7 +33,6 @@ export class AddProductComponent implements OnInit, OnDestroy {
) {}
ngOnInit() {
this._scanProvider = this.scanProviders?.find((provider) => provider.for === 'add-product');
this.addBreadcrumbIfNotExists();
this.initSearch();
}

View File

@@ -27,7 +27,7 @@
[loading]="loading$ | async"
[hint]="hint$ | async"
(scan)="startRemission($event)"
[scanProvider]="scanProvider"
[scanner]="true"
></ui-searchbox>
</div>
</div>

View File

@@ -1,10 +1,9 @@
import { Component, Inject, OnInit, Optional, ViewChild } from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { DomainRemissionService } from '@domain/remission';
import { ReturnDTO } from '@swagger/remi';
import { UiFilterScanProvider } from '@ui/filter';
import { UiErrorModalComponent, UiModalService } from '@ui/modal';
import { UiSearchboxNextComponent } from '@ui/searchbox';
import { Subject } from 'rxjs';
@@ -22,17 +21,11 @@ export class CreateRemissionComponent implements OnInit {
hint$ = new Subject<string>();
private _scanProvider: UiFilterScanProvider;
get scanProvider() {
return this._scanProvider;
}
get supplierId(): number {
return +this._activatedRoute?.snapshot?.queryParams?.supplierId;
}
constructor(
@Inject(UiFilterScanProvider) @Optional() private scanProviders: UiFilterScanProvider[],
private _activatedRoute: ActivatedRoute,
private readonly _domainRemissionService: DomainRemissionService,
private readonly _modal: UiModalService,
@@ -42,7 +35,6 @@ export class CreateRemissionComponent implements OnInit {
) {}
ngOnInit(): void {
this._scanProvider = this.scanProviders?.find((provider) => provider.for === 'create');
this.addBreadcrumbIfNotExists();
}

View File

@@ -10,6 +10,6 @@
[loading]="loading$ | async"
[hint]="hint$ | async"
(scan)="search($event)"
[scanProvider]="scanProvider"
[scanner]="true"
></ui-searchbox>
</div>

View File

@@ -1,9 +1,8 @@
import { ChangeDetectionStrategy, Component, Inject, OnDestroy, OnInit, Optional, ViewChild } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { DomainRemissionService } from '@domain/remission';
import { UiFilterScanProvider } from '@ui/filter';
import { UiDialogModalComponent, UiErrorModalComponent, UiModalService } from '@ui/modal';
import { UiSearchboxNextComponent } from '@ui/searchbox';
import { Subject } from 'rxjs';
@@ -25,13 +24,7 @@ export class FinishShippingDocumentComponent implements OnInit, OnDestroy {
hint$ = new Subject<string>();
private _scanProvider: UiFilterScanProvider;
get scanProvider() {
return this._scanProvider;
}
constructor(
@Inject(UiFilterScanProvider) @Optional() private scanProviders: UiFilterScanProvider[],
private _activatedRoute: ActivatedRoute,
private _modal: UiModalService,
private _remissionService: DomainRemissionService,
@@ -41,7 +34,6 @@ export class FinishShippingDocumentComponent implements OnInit, OnDestroy {
) {}
ngOnInit() {
this._scanProvider = this.scanProviders?.find((provider) => provider.for === 'shipping-document');
this.removeBreadcrumbs();
this.addBreadcrumbIfNotExists();
}

View File

@@ -3,5 +3,4 @@ export * from './remission-routing.module';
export * from './remission.component';
export * from './remission.module';
export * from './remission-list';
export * from './providers';
// end:ng42.barrel

View File

@@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { UiFilterScanProvider } from '@ui/filter';
import { NativeContainerService } from 'native-container';
import { Observable } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators';
@Injectable()
export class AddProductScanProviderService extends UiFilterScanProvider {
for = 'add-product';
constructor(private nativeContainer: NativeContainerService) {
super();
}
scan(): Observable<string> {
return this.nativeContainer.openScanner('remissionProduct').pipe(
filter((result) => result.status !== 'IN_PROGRESS'),
map((result) => result?.data),
catchError((err) => {
return '';
})
);
}
}

View File

@@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { UiFilterScanProvider } from '@ui/filter';
import { NativeContainerService } from 'native-container';
import { Observable } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators';
@Injectable()
export class CreateRemissionScanProviderService extends UiFilterScanProvider {
for = 'create';
constructor(private nativeContainer: NativeContainerService) {
super();
}
scan(): Observable<string> {
return this.nativeContainer.openScanner('remissionContainer').pipe(
filter((result) => result.status !== 'IN_PROGRESS'),
map((result) => result?.data),
catchError((err) => {
return '';
})
);
}
}

View File

@@ -1,24 +0,0 @@
import { Injectable } from '@angular/core';
import { UiFilterScanProvider } from '@ui/filter';
import { NativeContainerService } from 'native-container';
import { Observable } from 'rxjs';
import { catchError, filter, map } from 'rxjs/operators';
@Injectable()
export class FinishShippingDocumentScanProviderService extends UiFilterScanProvider {
for = 'shipping-document';
constructor(private nativeContainer: NativeContainerService) {
super();
}
scan(): Observable<string> {
return this.nativeContainer.openScanner('shippingDocument').pipe(
filter((result) => result.status !== 'IN_PROGRESS'),
map((result) => result?.data),
catchError((err) => {
return '';
})
);
}
}

View File

@@ -1,5 +0,0 @@
// start:ng42.barrel
export * from './add-product-scan.provider';
export * from './create-remission-scan.provider';
export * from './finish-shipping-document-scan.provider';
// end:ng42.barrel

View File

@@ -3,32 +3,13 @@ import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { ApplicationService } from '@core/application';
import { BreadcrumbService } from '@core/breadcrumb';
import { Config } from '@core/config';
import { UiFilterScanProvider } from '@ui/filter';
import { Subject } from 'rxjs';
import { filter, first, takeUntil } from 'rxjs/operators';
import { AddProductScanProviderService, CreateRemissionScanProviderService, FinishShippingDocumentScanProviderService } from './providers';
@Component({
selector: 'page-remission',
templateUrl: './remission.component.html',
styleUrls: ['./remission.component.scss'],
providers: [
{
provide: UiFilterScanProvider,
useClass: AddProductScanProviderService,
multi: true,
},
{
provide: UiFilterScanProvider,
useClass: CreateRemissionScanProviderService,
multi: true,
},
{
provide: UiFilterScanProvider,
useClass: FinishShippingDocumentScanProviderService,
multi: true,
},
],
})
export class RemissionComponent implements OnInit, OnDestroy {
private _onDestroy$ = new Subject();

View File

@@ -3,11 +3,11 @@
[query]="uiInput?.value"
(queryChange)="uiInput?.setValue($event)"
(complete)="complete.next($event)"
(search)="search.emit($event)"
(scan)="search.emit($event)"
(search)="emitSearch($event)"
(scan)="emitSearch($event)"
[loading]="loading"
[hint]="hint"
[scanProvider]="scanProvider"
[scanner]="scanner"
>
<ui-autocomplete *ngIf="autocompleteProvider">
<button *ngFor="let item of autocompleteResults$ | async" [uiAutocompleteItem]="item.query">

View File

@@ -15,7 +15,7 @@ import {
import { UiAutocompleteComponent } from '@ui/autocomplete';
import { Observable, Subject, Subscription } from 'rxjs';
import { debounceTime, distinctUntilChanged, filter, switchMap, tap } from 'rxjs/operators';
import { UiFilterAutocomplete, UiFilterAutocompleteProvider, UiFilterScanProvider } from '../../providers';
import { UiFilterAutocomplete, UiFilterAutocompleteProvider } from '../../providers';
import { IUiInputGroup, UiInput, UiInputGroup } from '../../tree';
@Component({
@@ -40,6 +40,9 @@ export class UiFilterInputGroupMainComponent implements OnInit, OnDestroy, After
@Input()
showDescription: boolean = true;
@Input()
scanner = false;
private _inputGroup: UiInputGroup;
@Input()
@@ -57,11 +60,6 @@ export class UiFilterInputGroupMainComponent implements OnInit, OnDestroy, After
return this._inputGroup?.input?.find((f) => f);
}
private _scanProvider: UiFilterScanProvider;
get scanProvider() {
return this._scanProvider;
}
private _autocompleteProvider: UiFilterAutocompleteProvider;
get autocompleteProvider() {
return this._autocompleteProvider;
@@ -75,13 +73,11 @@ export class UiFilterInputGroupMainComponent implements OnInit, OnDestroy, After
constructor(
@Inject(UiFilterAutocompleteProvider) @Optional() private autocompleteProviders: UiFilterAutocompleteProvider[],
@Inject(UiFilterScanProvider) @Optional() private scanProviders: UiFilterScanProvider[],
private cdr: ChangeDetectorRef
) {}
ngOnInit() {
this._autocompleteProvider = this.autocompleteProviders?.find((provider) => !!provider);
this._scanProvider = this.scanProviders?.find((provider) => provider.for === 'main');
}
ngAfterViewInit() {
@@ -148,4 +144,10 @@ export class UiFilterInputGroupMainComponent implements OnInit, OnDestroy, After
}
return debounceTimeMilliseconds;
}
emitSearch(query: string) {
setTimeout(() => {
this.search.emit(query);
}, 1);
}
}

View File

@@ -1,4 +1,3 @@
// start:ng42.barrel
export * from './ui-filter-autocomplete.provider';
export * from './ui-filter-scan.provider';
// end:ng42.barrel

View File

@@ -1,5 +0,0 @@
import { UiSearchboxScanProvider } from '@ui/searchbox';
export abstract class UiFilterScanProvider extends UiSearchboxScanProvider {
abstract readonly for: string;
}

View File

@@ -2,8 +2,9 @@
<ui-filter-input-group-main
*ngIf="uiFilter?.input | group: 'main'; let inputGroupMain"
[inputGroup]="inputGroupMain"
(search)="search.emit($event)"
(search)="emitSearch($event)"
[loading]="loading"
[hint]="hint"
[scanner]="scanner"
></ui-filter-input-group-main>
<ui-filter-filter-group-filter [inputGroup]="uiFilter?.filter | group: 'filter'"></ui-filter-filter-group-filter>

View File

@@ -37,6 +37,9 @@ export class UiFilterComponent implements OnChanges, AfterViewInit {
@Input()
resizeInputOptionsToElement: string | HTMLElement;
@Input()
scanner = false;
get uiFilter() {
return this.filter instanceof UiFilter && this.filter;
}
@@ -80,4 +83,10 @@ export class UiFilterComponent implements OnChanges, AfterViewInit {
return Math.abs(rect1.top - rect2.top);
}
emitSearch(query: string) {
setTimeout(() => {
this.search.emit(query);
}, 1);
}
}

View File

@@ -8,7 +8,14 @@ import { PromptModalData } from './prompt-modal.data';
<p class="message">
{{ modalRef.data.message }}
</p>
<input type="text" #promptInput [placeholder]="modalRef.data.placeholder ?? ''" [value]="modalRef.data.defaultValue ?? ''" />
<input
type="text"
#promptInput
[placeholder]="modalRef.data.placeholder ?? ''"
[value]="modalRef.data.defaultValue ?? ''"
(keyup.enter)="modalRef.close(promptInput.value)"
(keyup.esc)="modalRef.close()"
/>
<div class="actions">
<button class="cancel" (click)="modalRef.close()">{{ modalRef.data.cancelText || 'abbrechen' }}</button>
<button class="confirm" (click)="modalRef.close(promptInput.value)">{{ modalRef.data.confirmText || 'weiter' }}</button>

View File

@@ -1,5 +1,4 @@
// start:ng42.barrel
export * from './providers';
export * from './searchbox.component';
export * from './searchbox.module';
// end:ng42.barrel

View File

@@ -1,3 +0,0 @@
// start:ng42.barrel
export * from './ui-searchbox-scan.provider';
// end:ng42.barrel

View File

@@ -1,7 +0,0 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable()
export abstract class UiSearchboxScanProvider {
abstract scan(): Observable<string>;
}

View File

@@ -14,14 +14,14 @@ import {
AfterContentInit,
HostListener,
forwardRef,
Optional,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { UiAutocompleteComponent } from '@ui/autocomplete';
import { UiFormControlDirective } from '@ui/form-control';
import { containsElement } from '@utils/common';
import { NativeContainerService } from 'native-container';
import { Subscription } from 'rxjs';
import { UiSearchboxScanProvider } from './providers';
import { ScanAdapterService } from '@adapter/scan';
// TODO: @ui/searchbox mit dieser implementierung ersetzen
@@ -68,7 +68,7 @@ export class UiSearchboxNextComponent extends UiFormControlDirective<any>
loading = false;
@Input()
scanProvider: UiSearchboxScanProvider;
scanner = false;
@Input()
hint: string = '';
@@ -90,7 +90,7 @@ export class UiSearchboxNextComponent extends UiFormControlDirective<any>
}
get canScan() {
return this.nativeContainer.isUiWebview().isNative && !this.query && !!this.scanProvider;
return !this.query && this.scanner && this.scanAdapterService?.isReady();
}
get canClear() {
@@ -108,9 +108,9 @@ export class UiSearchboxNextComponent extends UiFormControlDirective<any>
onTouched = () => {};
constructor(
private nativeContainer: NativeContainerService,
private cdr: ChangeDetectorRef,
private elementRef: ElementRef<HTMLElement>
private elementRef: ElementRef<HTMLElement>,
@Optional() private scanAdapterService: ScanAdapterService
) {
super();
}
@@ -154,9 +154,9 @@ export class UiSearchboxNextComponent extends UiFormControlDirective<any>
}
startScan() {
if (!!this.scanProvider) {
if (!!this.scanAdapterService?.isReady()) {
this.subscriptions.add(
this.scanProvider.scan().subscribe((result) => {
this.scanAdapterService.scan().subscribe((result) => {
this.scan.emit(result);
this.setQuery(result);
this.autocomplete?.close();