mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
Merge branch 'development' into testing
This commit is contained in:
@@ -21,7 +21,7 @@ export class FilterService {
|
||||
if (filter.id === id) {
|
||||
return { ...filter, expanded: true };
|
||||
}
|
||||
return { ...filter, expanded: false };
|
||||
return { ...filter, expanded: false };
|
||||
});
|
||||
return of(newFilterState);
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ export class LoadFullFilters {
|
||||
export class SelectFilterById {
|
||||
static readonly type = SELECT_FILTER_BY_ID;
|
||||
|
||||
constructor(public id: string, public payload: Filter[]) {}
|
||||
constructor(public id: string) {}
|
||||
}
|
||||
|
||||
export class UnselectFilterById {
|
||||
static readonly type = UNSELECT_FILTER_BY_ID;
|
||||
|
||||
constructor(public id: string, public payload: Filter[]) {}
|
||||
constructor(public id: string) {}
|
||||
}
|
||||
|
||||
export class ToggleFilterItemById {
|
||||
@@ -36,5 +36,5 @@ export class ToggleFilterItemById {
|
||||
export class ToggleFilterItemByName {
|
||||
static readonly type = TOGGLE_FILTER_ITEM_BY_NAME;
|
||||
|
||||
constructor(public name: string, public payload: Filter[]) {}
|
||||
constructor(public name: string) {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { Filter } from '../../models/filter.model';
|
||||
import { State, Selector, Action, StateContext } from '@ngxs/store';
|
||||
import {
|
||||
State,
|
||||
Selector,
|
||||
Action,
|
||||
StateContext,
|
||||
createSelector
|
||||
} from '@ngxs/store';
|
||||
import {
|
||||
LoadFilters,
|
||||
LoadFullFilters,
|
||||
@@ -29,9 +35,26 @@ export class FilterState {
|
||||
return state.filters;
|
||||
}
|
||||
|
||||
@Selector()
|
||||
static getFilterCount(state: FilterStateModel) {
|
||||
return state.filters.length;
|
||||
}
|
||||
|
||||
static getFilterIndex(index: number) {
|
||||
const val = index;
|
||||
return createSelector(
|
||||
[FilterState],
|
||||
(state: FilterStateModel) => {
|
||||
return state.filters[val];
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Selector()
|
||||
static getFiltersJSON(state: FilterStateModel) {
|
||||
return JSON.stringify(state.filters);
|
||||
return JSON.stringify(
|
||||
state.filters.reduce((prev, curr) => [...curr.items, ...prev], [])
|
||||
);
|
||||
}
|
||||
|
||||
@Selector()
|
||||
@@ -64,15 +87,16 @@ export class FilterState {
|
||||
@Action(SelectFilterById)
|
||||
selectFilterById(
|
||||
ctx: StateContext<FilterStateModel>,
|
||||
{ id, payload }: SelectFilterById
|
||||
{ id }: SelectFilterById
|
||||
) {
|
||||
const state = ctx.getState();
|
||||
const filters = state.filters;
|
||||
this.filterService
|
||||
.selectFilterById(payload, id)
|
||||
.selectFilterById(filters, id)
|
||||
.subscribe((filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
filters: [...filters]
|
||||
filters: filters
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -80,11 +104,12 @@ export class FilterState {
|
||||
@Action(UnselectFilterById)
|
||||
unselectFilterById(
|
||||
ctx: StateContext<FilterStateModel>,
|
||||
{ id, payload }: UnselectFilterById
|
||||
{ id }: UnselectFilterById
|
||||
) {
|
||||
const state = ctx.getState();
|
||||
const filters = state.filters;
|
||||
this.filterService
|
||||
.unselectFilterById(payload, id)
|
||||
.unselectFilterById(filters, id)
|
||||
.subscribe((filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
@@ -96,11 +121,13 @@ export class FilterState {
|
||||
@Action(ToggleFilterItemById)
|
||||
toggleItemById(
|
||||
ctx: StateContext<FilterStateModel>,
|
||||
{ id, payload }: ToggleFilterItemById
|
||||
{ id }: ToggleFilterItemById
|
||||
) {
|
||||
const state = ctx.getState();
|
||||
const filters = state.filters;
|
||||
|
||||
this.filterService
|
||||
.toggleFilterItemsById(payload, id)
|
||||
.toggleFilterItemsById(filters, id)
|
||||
.subscribe((filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
@@ -112,11 +139,13 @@ export class FilterState {
|
||||
@Action(ToggleFilterItemByName)
|
||||
toggleItemByName(
|
||||
ctx: StateContext<FilterStateModel>,
|
||||
{ name, payload }: ToggleFilterItemByName
|
||||
{ name }: ToggleFilterItemByName
|
||||
) {
|
||||
const state = ctx.getState();
|
||||
const filters = state.filters;
|
||||
|
||||
this.filterService
|
||||
.toggleFilterItemsByName(payload, name)
|
||||
.toggleFilterItemsByName(filters, name)
|
||||
.subscribe((filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import {
|
||||
trigger,
|
||||
transition,
|
||||
stagger,
|
||||
animate,
|
||||
style,
|
||||
query,
|
||||
state
|
||||
} from '@angular/animations';
|
||||
|
||||
export const fadeInAnimation = trigger('fadeIn', [
|
||||
state('true', style({ opacity: 1, transform: 'translateY(0)' })),
|
||||
transition(':enter', [
|
||||
style({ opacity: 0, transform: 'translateY(-50px)' }),
|
||||
animate('200ms ease-in')
|
||||
]),
|
||||
transition(':leave', animate(200, style({ opacity: 0 })))
|
||||
]);
|
||||
@@ -1,18 +1,24 @@
|
||||
<div class="filter-item" (click)="toggleMenu(filter.id)">
|
||||
<div
|
||||
class="filter-item"
|
||||
[class.expand]="filter.expanded"
|
||||
(click)="toggleMenu(filter.id)"
|
||||
>
|
||||
<span class="filter-name">{{ filter.name }}</span>
|
||||
<img
|
||||
class="icon"
|
||||
[ngClass]="{ hide: expanded }"
|
||||
src="../../../assets/images/Arrow_Down_2.svg"
|
||||
/>
|
||||
<img
|
||||
class="icon"
|
||||
[ngClass]="{ hide: !expanded }"
|
||||
src="../../../assets/images/Arrow_Down_5.svg"
|
||||
[class.expand]="filter.expanded"
|
||||
src="/assets/images/Arrow_Down_2.svg"
|
||||
/>
|
||||
</div>
|
||||
<div class="filter-menu" [ngClass]="{ hide: !expanded }">
|
||||
<div class="filter-menu" *ngIf="filter.expanded" [@fadeIn]="filter.expanded">
|
||||
<div class="item-container">
|
||||
<div class="item" (click)="selectItem(item)" [ngClass]="{'active': item.selected}" *ngFor="let item of filter.items">{{item.name}}</div>
|
||||
<div
|
||||
class="item"
|
||||
(click)="selectItem(item)"
|
||||
[class.active]="item.selected"
|
||||
*ngFor="let item of filter.items"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,10 +9,23 @@
|
||||
.icon {
|
||||
width: 17px;
|
||||
margin-left: 5px;
|
||||
transition: all 0.2s linear;
|
||||
|
||||
&.expand {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
position: relative;
|
||||
background-color: rgba(255, 255, 255, 0);
|
||||
transition: all 0.2s linear;
|
||||
width: fit-content;
|
||||
padding: 0px 10px;
|
||||
|
||||
&.expand {
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.filter-menu {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { FilterState } from 'src/app/core/store/state/filter.state';
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Filter } from 'src/app/core/models/filter.model';
|
||||
import {
|
||||
@@ -7,33 +8,37 @@ import {
|
||||
} from 'src/app/core/store/actions/filter.actions';
|
||||
import { FilterItem } from 'src/app/core/models/filter-item.model';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { map, take } from 'rxjs/operators';
|
||||
import { fadeInAnimation } from './fadeIn.animation';
|
||||
|
||||
@Component({
|
||||
selector: 'app-filter-item',
|
||||
templateUrl: './filter-item.component.html',
|
||||
styleUrls: ['./filter-item.component.scss']
|
||||
styleUrls: ['./filter-item.component.scss'],
|
||||
animations: [fadeInAnimation]
|
||||
})
|
||||
export class FilterItemComponent implements OnInit {
|
||||
@Input()
|
||||
index: number;
|
||||
|
||||
filter: Filter;
|
||||
@Input()
|
||||
filters: Filter[];
|
||||
@Input()
|
||||
expanded: boolean;
|
||||
|
||||
constructor(private store: Store) {}
|
||||
|
||||
toggleMenu(id: string) {
|
||||
const action = this.filter.expanded
|
||||
? new UnselectFilterById(id, this.filters)
|
||||
: new SelectFilterById(id, this.filters);
|
||||
? new UnselectFilterById(id)
|
||||
: new SelectFilterById(id);
|
||||
this.store.dispatch(action);
|
||||
}
|
||||
|
||||
selectItem(item: FilterItem) {
|
||||
this.store.dispatch(new ToggleFilterItemByName(item.name, this.filters));
|
||||
this.store.dispatch(new ToggleFilterItemByName(item.name));
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select(FilterState.getFilterIndex(this.index)).subscribe(f => {
|
||||
this.filter = f;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<div class="filter-container">
|
||||
<app-filter-item *ngFor="let filter of filters"
|
||||
[filter]="filter"
|
||||
[filters]="filters"
|
||||
[expanded]="filter.expanded"></app-filter-item>
|
||||
<div *ngIf="!showMore" (click)="toggleMore()" class="more-filters-container">
|
||||
<span class="more-filters">Mehr Filter</span>
|
||||
<img class="more-icon" src="../../../assets/images/Arrow_More.svg">
|
||||
<app-filter-item
|
||||
*ngFor="let index of (filterIndexArray$ | async)"
|
||||
[index]="index"
|
||||
></app-filter-item>
|
||||
<div (click)="toggleMore()" class="more-filters-container">
|
||||
<span class="more-filters">{{ showMore ? 'Weniger' : 'Mehr' }} Filter</span>
|
||||
<img
|
||||
class="more-icon"
|
||||
[class.more]="showMore"
|
||||
src="/assets/images/Arrow_More.svg"
|
||||
/>
|
||||
</div>
|
||||
<div *ngIf="showMore" (click)="toggleMore()" class="less-filters-container">
|
||||
<img class="less-icon" src="../../../assets/images/Less_Arrow.svg">
|
||||
<span class="less-filters">Weniger Filter</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
margin-top: 5px;
|
||||
width: 80%;
|
||||
margin-left: 15%;
|
||||
line-height: 3;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1247px) {
|
||||
@@ -61,6 +61,7 @@
|
||||
.more-icon {
|
||||
width: 14px;
|
||||
margin-left: 6px;
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
|
||||
.less-filters {
|
||||
@@ -78,3 +79,7 @@
|
||||
.less-icon {
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.more {
|
||||
transform: translateX(-135px) rotate(-180deg);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Filter } from 'src/app/core/models/filter.model';
|
||||
import { LoadFilters, LoadFullFilters } from 'src/app/core/store/actions/filter.actions';
|
||||
import {
|
||||
LoadFilters,
|
||||
LoadFullFilters
|
||||
} from 'src/app/core/store/actions/filter.actions';
|
||||
import { Store, Select } from '@ngxs/store';
|
||||
import { FilterState } from 'src/app/core/store/state/filter.state';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map, distinctUntilChanged } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'app-filter',
|
||||
@@ -11,19 +15,19 @@ import { Observable } from 'rxjs';
|
||||
styleUrls: ['./filter.component.scss']
|
||||
})
|
||||
export class FilterComponent implements OnInit {
|
||||
|
||||
@Select(FilterState.getFilters) filters$: Observable<Filter[]>;
|
||||
filters: Filter[];
|
||||
@Select(FilterState.getFilterCount) filterCount$: Observable<number>;
|
||||
filterIndexArray$: Observable<number[]>;
|
||||
showMore: boolean;
|
||||
|
||||
constructor(private store: Store) { }
|
||||
constructor(private store: Store) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.dispatch(new LoadFilters());
|
||||
this.filters$.subscribe(
|
||||
(filters: Filter[]) => this.filters = filters
|
||||
);
|
||||
this.showMore = false;
|
||||
this.filterIndexArray$ = this.filterCount$.pipe(
|
||||
distinctUntilChanged(),
|
||||
map(c => Array.from(Array(c)).map((v, i) => i))
|
||||
);
|
||||
}
|
||||
|
||||
toggleMore() {
|
||||
@@ -34,5 +38,4 @@ export class FilterComponent implements OnInit {
|
||||
this.store.dispatch(new LoadFilters());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,4 +6,8 @@
|
||||
<app-barcode-scanner-scandit
|
||||
(scan)="triggerSearch($event)"
|
||||
></app-barcode-scanner-scandit>
|
||||
|
||||
<div class="recc">
|
||||
<app-recommendations></app-recommendations>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 36px;
|
||||
padding: 36px 0;
|
||||
flex-direction: column;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
border-radius: 5px;
|
||||
@@ -32,3 +32,11 @@ app-barcode-scanner-scandit {
|
||||
height: 300px;
|
||||
border: #e1ebf5 2px solid;
|
||||
}
|
||||
|
||||
.recc {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
margin-top: 60px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
box-shadow: 0px -2px 6px 0px rgba(220, 226, 233, 0.8);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import {
|
||||
AllowProductLoad,
|
||||
AddSearch,
|
||||
ChangeCurrentRoute
|
||||
ChangeCurrentRoute,
|
||||
AddProcess
|
||||
} from '../../core/store/actions/process.actions';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Search } from 'src/app/core/models/search.model';
|
||||
import { Router } from '@angular/router';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { Process } from 'src/app/core/models/process.model';
|
||||
import { getRandomPic } from 'src/app/core/utils/process.util';
|
||||
import { Breadcrumb } from 'src/app/core/models/breadcrumb.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-barcode-search',
|
||||
@@ -19,10 +23,11 @@ export class BarcodeSearchComponent implements OnInit {
|
||||
ngOnInit() {}
|
||||
|
||||
triggerSearch(barcode) {
|
||||
this.createProcess();
|
||||
const search = <Search>{
|
||||
query: barcode,
|
||||
fitlers: null,
|
||||
take: 5,
|
||||
fitlers: [],
|
||||
take: 10,
|
||||
skip: 0,
|
||||
firstLoad: true
|
||||
};
|
||||
@@ -31,4 +36,22 @@ export class BarcodeSearchComponent implements OnInit {
|
||||
this.store.dispatch(new ChangeCurrentRoute('/search-results#start'));
|
||||
this.router.navigate(['/search-results#start']);
|
||||
}
|
||||
|
||||
createProcess() {
|
||||
const newProcess = <Process>{
|
||||
id: 1,
|
||||
name: '# 1',
|
||||
selected: true,
|
||||
icon: getRandomPic(),
|
||||
breadcrumbs: <Breadcrumb[]>[
|
||||
{
|
||||
name: 'Artikelsuche',
|
||||
path: '/article-search'
|
||||
}
|
||||
],
|
||||
currentRoute: 'article-search'
|
||||
};
|
||||
|
||||
this.store.dispatch(new AddProcess(newProcess));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
import { SharedModule } from 'src/app/shared/shared.module';
|
||||
import { ScanditSdkModule } from 'scandit-sdk-angular';
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NgModule, ErrorHandler } from '@angular/core';
|
||||
import { ZXingScannerModule } from '@zxing/ngx-scanner';
|
||||
|
||||
import { BarcodeSearchComponent } from './barcode-search.component';
|
||||
import { BarcodeScannerScanditComponent } from './components/barcode-scanner-scandit/barcode-scanner-scandit.component';
|
||||
import { BarcodeScannerComponent } from './components/barcode-scanner/barcode-scanner.component';
|
||||
import { CameraErrorHandler } from './camera-error.handler';
|
||||
import { RecommendationsdModule } from '../recommendations/recommendations.module';
|
||||
|
||||
const licenseKey =
|
||||
'AejsFV7HQtsqNMrEAkQOTw02rYwJABlExVErc8Um/r+YWl/psUmXqQl5jJnrb21ZUxLaSzhxHIL8ev2+fXCre2dWtbCuKMyjvUUeeyw0UsBFbV4flF81uBZvmKTcVocCSUQAN6cgp1AbD0t5ZPe4LqiqKOs4rax8RPMStG+e+wIMlV82PlVfVGREjaYNm7qjNhXYL4zTaBUm4VHkY4Nqk+faGN6Q2Q9Ear9LVY/LQeEGd0udZdWyvpA3eCKnFz5dBPgFrhOiLOUWIgmyJECJJy8DlkdaAjk63jLekef9O7338XCNoZtwyBPVSSGjLXPtY3ppmUGUz7LI4CJg36rK/Gu3lE4NoWjkoSOb2Npn7mJCF6DZQKM9wr49FpPZ5f1A1LmKw0bvRjF52Ks0i4u3we9YUgFH0D38ljO/DEhXUZ0nFSyRBlJBkLhE9+DFNpxcqBol3AMkiuQsnfwer4PrM4+DjE86urQE86D/ZWtLIA4WwHMJEBSWgmeSi+0y/y7p6fM+ghbuyzslgII1xRF7EoMSZYDCf0yLvIY5LboD6GUZNiw6VXphJBE9hF7PjKmb0wg3riXHkG0G0UZS+NVLxMUA7O6vKhQQJq+BGrISdjJPcH6YkPXC4xURzBaeuJYICcgkEaP6c5+GOyWPUvfAQAl0o3wqCioN+mGLFug2+yiq0NU/VAeH7DspkWNK54T4ssZenDT8OdBRMw5P9KuKFd1WVWs7JrPwP9sHZoFAcu7MbMgBNQduh0mxzOr0KaCoiQRUt1EPYNL/sMjOEtIyk8KIi1HDk82G3ysvD+djMz8qugR8ZBJPQFgBXQ==';
|
||||
const engineLocation = 'assets/vendor/scandit/';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
ZXingScannerModule,
|
||||
CommonModule,
|
||||
ScanditSdkModule.forRoot(licenseKey, engineLocation)
|
||||
ScanditSdkModule.forRoot(licenseKey, engineLocation),
|
||||
SharedModule,
|
||||
RecommendationsdModule
|
||||
],
|
||||
exports: [BarcodeSearchComponent],
|
||||
declarations: [
|
||||
@@ -23,6 +29,9 @@ const engineLocation = 'assets/vendor/scandit/';
|
||||
BarcodeScannerComponent,
|
||||
BarcodeScannerScanditComponent
|
||||
],
|
||||
providers: []
|
||||
providers: [
|
||||
CameraErrorHandler,
|
||||
{ provide: ErrorHandler, useExisting: CameraErrorHandler }
|
||||
]
|
||||
})
|
||||
export class BarcodeSearchModule {}
|
||||
|
||||
22
src/app/modules/barcode-search/camera-error.handler.ts
Normal file
22
src/app/modules/barcode-search/camera-error.handler.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { ErrorHandler, Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class CameraErrorHandler extends ErrorHandler {
|
||||
public notAllowed = new BehaviorSubject<boolean>(false);
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
handleError(error: any) {
|
||||
try {
|
||||
if (
|
||||
error.message != null &&
|
||||
error.message.indexOf('NotAllowedError') !== -1
|
||||
) {
|
||||
this.notAllowed.next(true);
|
||||
} else {
|
||||
super.handleError(error);
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
<div class="w-100 loading" *ngIf="!ready">
|
||||
<app-loading loading="true" text="Scanvorgang wird ausgeführt"></app-loading>
|
||||
</div>
|
||||
<div class="w-100" *ngIf="enabled">
|
||||
<scandit-sdk-barcode-picker
|
||||
#scanner
|
||||
[scanSettings]="settings"
|
||||
(scan)="scanSuccess($event)"
|
||||
(error)="scanErrorHandler($event)"
|
||||
[guiStyle]="'none'"
|
||||
[videoFit]="'cover'"
|
||||
(ready)="isReady(scanner)"
|
||||
@@ -11,22 +13,19 @@
|
||||
></scandit-sdk-barcode-picker>
|
||||
</div>
|
||||
|
||||
<div class="scanner-controls" *ngIf="!enabled">
|
||||
<div class="result">
|
||||
<span (click)="scanToggle()" class="action" *ngIf="ready">
|
||||
<i class="icon-placeholder"></i>
|
||||
<span>Scan</span>
|
||||
</span>
|
||||
<span (click)="search()" *ngIf="code" class="action">
|
||||
<i class="icon-placeholder"></i>
|
||||
<span>Suchen</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="w-100 loading" *ngIf="!enabled">
|
||||
<app-loading loading="true" text="Suchen"></app-loading>
|
||||
<div class="scan-result">
|
||||
<span>{{ code }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-100" *ngIf="error">
|
||||
camera not detected
|
||||
<div class="scanner-controls errors" *ngIf="errorOther || errorAccess">
|
||||
<div class="error" *ngIf="errorOther">
|
||||
Scanvorgang leider nicht möglich, da keine Kamera vorhanden
|
||||
</div>
|
||||
|
||||
<div class="error" *ngIf="errorAccess">
|
||||
Kamerazugriff blockiert, daher leider kein Scanvorgang möglich
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.loading {
|
||||
margin-top: 120px;
|
||||
}
|
||||
.scanner-controls {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background: white;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
@@ -50,3 +53,16 @@
|
||||
display: block;
|
||||
padding: $buttonSize;
|
||||
}
|
||||
|
||||
.errors {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
.error {
|
||||
width: 70%;
|
||||
color: #f70300;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -3,20 +3,27 @@ import {
|
||||
OnInit,
|
||||
ViewChild,
|
||||
EventEmitter,
|
||||
Output
|
||||
Output,
|
||||
AfterViewInit
|
||||
} from '@angular/core';
|
||||
import { BarcodeFormat, Result } from '@zxing/library';
|
||||
import { ZXingScannerComponent } from '@zxing/ngx-scanner';
|
||||
import { ScanSettings, Barcode } from 'scandit-sdk';
|
||||
import { ScanSettings, Barcode, BarcodePicker } from 'scandit-sdk';
|
||||
import {
|
||||
ScanditSdkBarcodePickerComponent,
|
||||
ScanditSdkService
|
||||
} from 'scandit-sdk-angular';
|
||||
import { CameraErrorHandler } from '../../camera-error.handler';
|
||||
|
||||
@Component({
|
||||
selector: 'app-barcode-scanner-scandit',
|
||||
templateUrl: 'barcode-scanner-scandit.component.html',
|
||||
styleUrls: ['barcode-scanner-scandit.component.scss']
|
||||
})
|
||||
export class BarcodeScannerScanditComponent implements OnInit {
|
||||
export class BarcodeScannerScanditComponent implements AfterViewInit {
|
||||
public enabled = true;
|
||||
public error = false;
|
||||
public errorAccess = false;
|
||||
public errorOther = false;
|
||||
public code = '';
|
||||
public ready = false;
|
||||
@Output() scan = new EventEmitter();
|
||||
@@ -25,9 +32,23 @@ export class BarcodeScannerScanditComponent implements OnInit {
|
||||
enabledSymbologies: [Barcode.Symbology.CODE128, Barcode.Symbology.EAN13]
|
||||
});
|
||||
|
||||
constructor() {}
|
||||
@ViewChild('scanner') scanner: ScanditSdkBarcodePickerComponent;
|
||||
log = 'tst';
|
||||
constructor(private cameraError: CameraErrorHandler) {}
|
||||
|
||||
ngOnInit() {}
|
||||
ngAfterViewInit() {
|
||||
this.cameraError.notAllowed.subscribe(v => (this.errorAccess = v));
|
||||
this.scanner.error.subscribe(
|
||||
success => {
|
||||
this.scanErrorHandler(success);
|
||||
this.log = JSON.stringify(success);
|
||||
},
|
||||
error => {
|
||||
this.scanErrorHandler(error);
|
||||
this.log = JSON.stringify(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
scanSuccess(result) {
|
||||
if (result.barcodes.length > 0) {
|
||||
@@ -47,6 +68,14 @@ export class BarcodeScannerScanditComponent implements OnInit {
|
||||
|
||||
isReady(scanner) {
|
||||
this.ready = true;
|
||||
const picker = (this.scanner['scanditSdkService'] as ScanditSdkService)
|
||||
.picker as any;
|
||||
this.errorOther = !picker.scanner.isReadyToWork;
|
||||
picker.cameraManager.cameraSwitcherEnabled = false;
|
||||
picker.cameraManager.triggerFatalError = e => {
|
||||
console.error(e);
|
||||
this.errorOther = true;
|
||||
};
|
||||
|
||||
// Remove Scandit logo
|
||||
const element = scanner.pickerContainer.nativeElement as Element;
|
||||
@@ -57,6 +86,6 @@ export class BarcodeScannerScanditComponent implements OnInit {
|
||||
|
||||
scanErrorHandler($event) {
|
||||
console.error($event);
|
||||
this.error = true;
|
||||
this.errorAccess = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<div class="container">
|
||||
<div class="header" (click)="nextStage()">
|
||||
<img class="icon" src="/assets/images/Empfehlungen_Icon_blue.svg" />
|
||||
<span>Empfehlungen</span>
|
||||
</div>
|
||||
<div class="books">
|
||||
<div class="book" *ngFor="let book of books">
|
||||
<img [src]="book.image" />
|
||||
<div class="info">
|
||||
<span class="author">{{ book.author }}</span>
|
||||
<span class="title">{{ book.title }}</span>
|
||||
<span class="status">{{ book.status }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,69 @@
|
||||
:host {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding: 25px;
|
||||
}
|
||||
.header {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
color: rgba(23, 32, 98, 1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
|
||||
.icon {
|
||||
width: 22px;
|
||||
height: 20px;
|
||||
background-image: url(/assets/images/Empfehlungen_Icon.svg);
|
||||
}
|
||||
span {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 50px;
|
||||
height: 100%;
|
||||
}
|
||||
.books {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.book {
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.author {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, 1);
|
||||
text-align: left;
|
||||
line-height: 21px;
|
||||
}
|
||||
.title {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: rgba(0, 0, 0, 1);
|
||||
text-align: center;
|
||||
line-height: 21px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.status {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: rgba(247, 4, 0, 1);
|
||||
text-align: left;
|
||||
}
|
||||
28
src/app/modules/recommendations/recommendations.component.ts
Normal file
28
src/app/modules/recommendations/recommendations.component.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-recommendations',
|
||||
templateUrl: 'recommendations.component.html',
|
||||
styleUrls: ['recommendations.component.scss']
|
||||
})
|
||||
export class RecommendationsComponent implements OnInit {
|
||||
books = [
|
||||
{
|
||||
image:
|
||||
'https://produktbilder.ihugendubel.de/9783442314874_150x150.jpg?showDummy=true',
|
||||
author: 'Michele Obama',
|
||||
title: 'Becoming Meine G…',
|
||||
status: 'In den Warenkorb'
|
||||
},
|
||||
{
|
||||
image:
|
||||
'https://produktbilder.ihugendubel.de/9783328600039_150x150.jpg?showDummy=true',
|
||||
author: 'Dörte Hansen',
|
||||
title: 'Mittagsstunde',
|
||||
status: 'In den Warenkorb'
|
||||
}
|
||||
];
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
}
|
||||
12
src/app/modules/recommendations/recommendations.module.ts
Normal file
12
src/app/modules/recommendations/recommendations.module.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { SharedModule } from 'src/app/shared/shared.module';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RecommendationsComponent } from './recommendations.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, SharedModule],
|
||||
exports: [RecommendationsComponent],
|
||||
declarations: [RecommendationsComponent],
|
||||
providers: []
|
||||
})
|
||||
export class RecommendationsdModule {}
|
||||
Reference in New Issue
Block a user