Merge branch 'development' into HIMA-38
@@ -19,10 +19,7 @@
|
||||
"@angular/platform-browser": "~7.2.0",
|
||||
"@angular/platform-browser-dynamic": "~7.2.0",
|
||||
"@angular/router": "~7.2.0",
|
||||
"@ngrx/effects": "^7.0.0",
|
||||
"@ngrx/router-store": "^7.1.0",
|
||||
"@ngrx/store": "^7.0.0",
|
||||
"@ngrx/store-devtools": "^7.1.0",
|
||||
"@ngxs/store": "^3.3.4",
|
||||
"core-js": "^2.5.4",
|
||||
"rxjs": "~6.3.3",
|
||||
"tslib": "^1.9.0",
|
||||
@@ -34,6 +31,8 @@
|
||||
"@angular/cli": "~7.2.1",
|
||||
"@angular/compiler-cli": "~7.2.0",
|
||||
"@angular/language-service": "~7.2.0",
|
||||
"@ngxs/devtools-plugin": "^3.3.4",
|
||||
"@ngxs/logger-plugin": "^3.3.4",
|
||||
"@types/jasmine": "~2.8.8",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "~8.9.4",
|
||||
|
||||
@@ -4,40 +4,33 @@ import { NgModule, APP_INITIALIZER } from '@angular/core';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { ComponentsModule } from './modules/components.module';
|
||||
import { processReducer } from './core/reducers/process.reducer';
|
||||
import { StoreModule } from '@ngrx/store';
|
||||
import { breadcrumbReducer } from './core/reducers/breadcrumb.reducer';
|
||||
import { feedReducer } from './core/reducers/feed.reducer';
|
||||
import { recentArticleSearchReducer } from './core/reducers/recent-article-search.reducer';
|
||||
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import { effects } from './core/effects';
|
||||
import { productReducer } from './core/reducers/product.reducer';
|
||||
import { filterReducer } from './core/reducers/filter.reducer';
|
||||
import { BasicAuthorizationInterceptor, BasicAuthorizationOptions } from './core/interceptors';
|
||||
import { SearchResultsComponent } from './components/search-results/search-results.component';
|
||||
import * as fromRouter from '@ngrx/router-store';
|
||||
import { StoreRouterConnectingModule, RouterStateSerializer } from '@ngrx/router-store';
|
||||
import { CustomSerializer } from './core/reducers/router.reducer';
|
||||
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
|
||||
import { CatServiceModule } from 'cat-service';
|
||||
import { ProductCardComponent } from './components/product-card/product-card.component';
|
||||
import { ConfigService } from './core/services/config.service';
|
||||
import { ProductDetailsComponent } from './components/product-details/product-details.component';
|
||||
import { FeedServiceModule, FeedService, FeedMockService } from 'feed-service';
|
||||
import { NgxsModule } from '@ngxs/store';
|
||||
import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin';
|
||||
import { NgxsLoggerPluginModule } from '@ngxs/logger-plugin';
|
||||
import { FeedState } from './core/store/state/feed.state';
|
||||
import { ProcessState } from './core/store/state/process.state';
|
||||
import { ProductsState } from './core/store/state/products.state';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { BreadcrumbsState } from './core/store/state/breadcrumbs.state';
|
||||
import { FilterState } from './core/store/state/filter.state';
|
||||
import { CheckoutComponent } from './components/checkout/checkout.component';
|
||||
import { ModalComponent } from './shared/components/modal/modal.component';
|
||||
import { ShoppingCartFeedbackComponent } from './components/shopping-cart-feedback/shopping-cart-feedback.component';
|
||||
|
||||
const rootReducer = {
|
||||
processes: processReducer,
|
||||
breadcrumbs: breadcrumbReducer,
|
||||
feed: feedReducer,
|
||||
recentArticleSearch: recentArticleSearchReducer,
|
||||
itemsDTO: productReducer,
|
||||
filters: filterReducer,
|
||||
router: fromRouter.routerReducer
|
||||
};
|
||||
const states = [
|
||||
FeedState,
|
||||
ProcessState,
|
||||
ProductsState,
|
||||
BreadcrumbsState,
|
||||
FilterState
|
||||
];
|
||||
|
||||
export function _configInitializer(conf: ConfigService) {
|
||||
// load config from /assets/config.json
|
||||
@@ -56,28 +49,23 @@ export function _basicAuthorizationInterceptorFactory(conf: ConfigService) {
|
||||
ProductDetailsComponent,
|
||||
CheckoutComponent,
|
||||
ModalComponent,
|
||||
ShoppingCartFeedbackComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
ComponentsModule,
|
||||
StoreModule.forRoot(rootReducer),
|
||||
HttpClientModule,
|
||||
EffectsModule.forRoot(effects),
|
||||
StoreRouterConnectingModule,
|
||||
StoreDevtoolsModule.instrument({
|
||||
maxAge: 25
|
||||
}),
|
||||
NgxsModule.forRoot(states, { developmentMode: !environment.production }),
|
||||
NgxsReduxDevtoolsPluginModule,
|
||||
NgxsLoggerPluginModule,
|
||||
CatServiceModule.forRoot('https://catsearch.paragon-data.de'),
|
||||
FeedServiceModule.forRoot('')
|
||||
],
|
||||
providers: [
|
||||
{ provide: APP_INITIALIZER, useFactory: _configInitializer, multi: true, deps: [ ConfigService ] },
|
||||
{ provide: RouterStateSerializer, useClass: CustomSerializer },
|
||||
{ provide: HTTP_INTERCEPTORS, useFactory: _basicAuthorizationInterceptorFactory, deps: [ConfigService], multi: true },
|
||||
// { provide: CatSearchService, useClass: CatSearchMockService } // Uncomment if u want to use the CatSearchMockService
|
||||
{ provide: FeedService, useClass: FeedMockService } // Uncomment if u want to use the FeedMockService
|
||||
{ provide: FeedService, useClass: FeedMockService } // Uncomment if u want to use the FeedMockService
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Process } from './core/models/process.model';
|
||||
import { Breadcrumb } from './core/models/breadcrumb.model';
|
||||
import { FeedCard } from './core/models/feed-card.model';
|
||||
import { RecentArticleSearch } from './core/models/recent-article-search.model';
|
||||
import { Product } from './core/models/product.model';
|
||||
import { Filter } from './core/models/filter.model';
|
||||
import { ItemDTO } from 'cat-service';
|
||||
import { RouterStateUrl } from './core/reducers/router.reducer';
|
||||
import * as fromRouter from '@ngrx/router-store';
|
||||
|
||||
export class AppState {
|
||||
readonly processes: Process[];
|
||||
readonly breadcrumbs: Breadcrumb[];
|
||||
readonly feed: FeedCard[];
|
||||
readonly recentArticleSearch: RecentArticleSearch[];
|
||||
readonly products: Product[];
|
||||
readonly itemsDTO: ItemDTO[];
|
||||
readonly error: string;
|
||||
readonly filters: Filter[];
|
||||
readonly router: fromRouter.RouterReducerState<RouterStateUrl>;
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { Store, Select } from '@ngxs/store';
|
||||
import { Observable } from 'rxjs';
|
||||
import { RecentArticleSearch } from 'src/app/core/models/recent-article-search.model';
|
||||
import { Product } from 'src/app/core/models/product.model';
|
||||
import { LoadRecentArticle } from 'src/app/core/actions/recent-article-search.actions';
|
||||
import { Router } from '@angular/router';
|
||||
import { AddSearch } from 'src/app/core/actions/search.actions';
|
||||
import { Search } from 'src/app/core/models/search.model';
|
||||
import { Filter } from 'src/app/core/models/filter.model';
|
||||
import { ChangeCurrentRoute, AddProcess, ADD_PROCESS } from 'src/app/core/actions/process.actions';
|
||||
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';
|
||||
import { ProcessState } from 'src/app/core/store/state/process.state';
|
||||
import { AddProcess, ChangeCurrentRoute, AddSearch } from 'src/app/core/store/actions/process.actions';
|
||||
import { ProductsState } from 'src/app/core/store/state/products.state';
|
||||
import { LoadRecentProducts } from 'src/app/core/store/actions/product.actions';
|
||||
|
||||
@Component({
|
||||
selector: 'app-article-search',
|
||||
@@ -21,18 +21,19 @@ import { Breadcrumb } from 'src/app/core/models/breadcrumb.model';
|
||||
})
|
||||
export class ArticleSearchComponent implements OnInit {
|
||||
|
||||
recentArticles$: Observable<RecentArticleSearch[]>;
|
||||
@Select(ProductsState.getRecentProducts) recentArticles$: Observable<RecentArticleSearch[]>;
|
||||
recentArticles: RecentArticleSearch[];
|
||||
products$: Observable<Product[]>;
|
||||
products: Product[];
|
||||
filters: Filter[];
|
||||
@Select(ProcessState.getProcesses) processes$: Observable<Process[]>;
|
||||
processes: Process[];
|
||||
|
||||
@Input()
|
||||
searchParams = '';
|
||||
|
||||
constructor(
|
||||
private store: Store<AppState>,
|
||||
private store: Store,
|
||||
private router: Router
|
||||
) { }
|
||||
|
||||
@@ -81,8 +82,8 @@ export class ArticleSearchComponent implements OnInit {
|
||||
}
|
||||
|
||||
loadRecentArticles() {
|
||||
this.store.dispatch(new LoadRecentArticle());
|
||||
this.store.select('recentArticleSearch').subscribe(
|
||||
this.store.dispatch(new LoadRecentProducts());
|
||||
this.recentArticles$.subscribe(
|
||||
(data: RecentArticleSearch[]) => this.recentArticles = data
|
||||
);
|
||||
}
|
||||
@@ -95,32 +96,31 @@ export class ArticleSearchComponent implements OnInit {
|
||||
|
||||
loadSelectedFilters() {
|
||||
// TODO filter selected filters
|
||||
this.store.select('filters').subscribe(
|
||||
(data: Filter[]) => this.filters = data
|
||||
);
|
||||
// this.store.select('filters').subscribe(
|
||||
// (data: Filter[]) => this.filters = data
|
||||
// );
|
||||
}
|
||||
|
||||
loadProcesses() {
|
||||
this.store.select(state => state.processes).subscribe(
|
||||
this.processes$.subscribe(
|
||||
(data: Process[]) => this.processes = data
|
||||
);
|
||||
}
|
||||
|
||||
createProcess() {
|
||||
this.store.dispatch({
|
||||
type: ADD_PROCESS,
|
||||
payload: <Process>{
|
||||
id: 1,
|
||||
name: '# 1',
|
||||
selected: true,
|
||||
icon: getRandomPic(),
|
||||
breadcrumbs: <Breadcrumb[]>[{
|
||||
name: 'Artikelsuche',
|
||||
path: '/article-search'
|
||||
}],
|
||||
currentRoute: 'article-search'
|
||||
}
|
||||
});
|
||||
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));
|
||||
}
|
||||
|
||||
createProcessIfDosntExists() {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Breadcrumb } from 'src/app/core/models/breadcrumb.model';
|
||||
import { Process } from 'src/app/core/models/process.model';
|
||||
import { Store, Select } from '@ngxs/store';
|
||||
import { ProcessState } from 'src/app/core/store/state/process.state';
|
||||
|
||||
@Component({
|
||||
selector: 'app-breadcrumbs',
|
||||
@@ -12,11 +12,10 @@ import { Process } from 'src/app/core/models/process.model';
|
||||
})
|
||||
export class BreadcrumbsComponent implements OnInit {
|
||||
|
||||
processesObs: Observable<Process[]>;
|
||||
@Select(ProcessState.getProcesses) processes$: Observable<Process[]>;
|
||||
breadcrumbs: Breadcrumb[];
|
||||
constructor(private store: Store<AppState>) {
|
||||
this.processesObs = store.select('processes');
|
||||
this.processesObs.subscribe(
|
||||
constructor(private store: Store) {
|
||||
this.processes$.subscribe(
|
||||
(data: Process[]) => this.getBreadcrumbsFromCurentProcess(data)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,38 +1,97 @@
|
||||
<app-modal id="checkout-modal">
|
||||
<div class="modal">
|
||||
<div class="modal__header">
|
||||
|
||||
<div class="modal-step-1" *ngIf="stepOne">
|
||||
<div class="header">
|
||||
<h1>Wie möchten Sie den Artikel erhalten?</h1>
|
||||
<img (click)="closeModal()" class="close-icon" src="../../../assets/images/close.svg" alt="close">
|
||||
</div>
|
||||
<div class="modal__body">
|
||||
<div class="modal__body__option">
|
||||
<img class="modal__body__option__img" src="../../../assets/images/Take_now.svg" alt="take now">
|
||||
<h2 class="modal__body__option__title__take_now">Jetzt mitnehmen</h2>
|
||||
<span class="modal__body__option__description modal__body__option__description__take_now">Möchten Sie den Artikel jetzt gleich mit nach Hause nehmen?</span>
|
||||
<span class="modal__body__option__price modal__body__option__price__take_now">16,95 EUR</span>
|
||||
<a class="modal__body__option__btn modal__body__option__btn__active" (click)="selectedAction('mitnehmen')">Auswählen</a>
|
||||
<div class="body">
|
||||
<div class="option">
|
||||
<img class="img" src="../../../assets/images/Take_now.svg" alt="take now">
|
||||
<h2 class="title-take-now">Jetzt mitnehmen</h2>
|
||||
<span class="description description-take-now">Möchten Sie den Artikel jetzt gleich mit nach Hause nehmen?</span>
|
||||
<span class="price price-take-now">16,95 EUR</span>
|
||||
<a class="btn btn-active" (click)="selectedAction('mitnehmen')">Auswählen</a>
|
||||
</div>
|
||||
<div class="modal__body__option">
|
||||
<img class="modal__body__option__img" src="../../../assets/images/Package_Icon.svg" alt="package">
|
||||
<div class="option">
|
||||
<img class="img" src="../../../assets/images/Package_Icon.svg" alt="package">
|
||||
<h2>Abholung</h2>
|
||||
<span class="modal__body__option__description modal__body__option__description__take_away">Möchten Sie den Artikel in einer unserer Fillialen abholen?</span>
|
||||
<div class="modal__body__option__location modal__body__option__location__take_away" (click)="openDropdown(dropdown)">{{ currentLocation.name }} <img class="" src="../../../assets/images/Arrow_Down_2.svg" alt="arrow"></div>
|
||||
<span class="modal__body__option__location__date modal__body__option__location__date__take_away">Lieferdatum {{ currentPickUpDate }}</span>
|
||||
<div class="modal__body__option__location__dropdown" #dropdown>
|
||||
<span *ngFor="let item of locations; let i = index" (click)="selectLocation(i, dropdown)">{{ item.name }}</span>
|
||||
<span class="description description-take-away">Möchten Sie den Artikel in einer unserer Fillialen abholen?</span>
|
||||
|
||||
<div class="dropdown-select-text" (click)="openDropdown(dropdown)" #selectedText [class.dropdown-select-text-active]="displayDropdown">
|
||||
<span class="location location-take-away">{{ currentLocation.name }}</span>
|
||||
<img class="dropdown-icon" src="../../../assets/images/Arrow_Down_2.svg" alt="arrow" *ngIf="!displayDropdown">
|
||||
<img class="dropdown-icon" src="../../../assets/images/Arrow_Up.svg" alt="arrow" *ngIf="displayDropdown">
|
||||
</div>
|
||||
<span class="modal__body__option__price modal__body__option__price__take_away">16,95 EUR</span>
|
||||
<a class="modal__body__option__btn" (click)="selectedAction('abholung')">Auswählen</a>
|
||||
|
||||
<span class="location location-date-take-away">Lieferdatum {{ currentPickUpDate }}</span>
|
||||
<div class="location location-dropdown" #dropdown>
|
||||
<ul>
|
||||
<li *ngFor="let item of locations; let i = index" (click)="selectLocation(i, dropdown)">{{ item.name }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<span class="price price-take-away">16,95 EUR</span>
|
||||
<a class="btn" (click)="selectedAction('abholung')">Auswählen</a>
|
||||
</div>
|
||||
<div class="modal__body__option">
|
||||
<img class="modal__body__option__img" src="../../../assets/images/truck_Icon.svg" alt="truck">
|
||||
<div class="option">
|
||||
<img class="img" src="../../../assets/images/truck_Icon.svg" alt="truck">
|
||||
<h2>Versand</h2>
|
||||
<span class="modal__body__option__description modal__body__option__description__delivery">Möchten Sie den Artikel nach Hause geliefert bekommen?</span>
|
||||
<div class="modal__body__option__delivery" (click)="openDropdown(dropdown)"><img class="modal__body__option__img__check" src="../../../assets/images/Check-green.svg" alt="arrow">Versandkostenfrei</div>
|
||||
<span class="modal__body__option__delivery__date">Lieferdatum {{ currentPickUpDate }}</span>
|
||||
<span class="modal__body__option__price modal__body__option__price__order">16,95 EUR</span>
|
||||
<a class="modal__body__option__btn" (click)="selectedAction('versand')">Auswählen</a>
|
||||
<span class="description description-delivery">Möchten Sie den Artikel nach Hause geliefert bekommen?</span>
|
||||
<div class="delivery" (click)="openDropdown(dropdown)"><img class="check" src="../../../assets/images/Check-green.svg" alt="arrow">Versandkostenfrei</div>
|
||||
<span class="delivery-date">Lieferdatum {{ currentPickUpDate }}</span>
|
||||
<span class="price price-order">16,95 EUR</span>
|
||||
<a class="btn" (click)="selectedAction('versand')">Auswählen</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-step-2" *ngIf="!stepOne">
|
||||
<div class="header">
|
||||
<h1>Artikel wurde dem Warenkorb hinzugefügt</h1>
|
||||
<img (click)="closeModal()" class="close-icon" src="../../../assets/images/close.svg" alt="close">
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="body-heading">
|
||||
<img (click)="closeModal()" class="close-icon" src="../../../assets/images/{{ stepTwoImgType }}" alt="truck">
|
||||
<h1>Versand</h1>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="body-content">
|
||||
<img src="../../../assets/images/Book-2x.png" alt="book">
|
||||
<span class="book-title">Silberfischchtsy</span>
|
||||
<div class="order-details">
|
||||
<span><img class="order-book-icon" src="../../../assets/images/Book_Icon.svg" alt="book-icon"> TB I Inger-Maria Mahlke</span>
|
||||
<span class="order-details-delivery-info">DHL I Lieferung 18.01.</span>
|
||||
</div>
|
||||
<span class="price">{{ currentPrice }} EUR</span>
|
||||
<div class="dropdown_container">
|
||||
<div (click)="openDropdown(dropdown)" class="dropdown-selected-text" [class.dropdown-selected-text-active]="displayDropdown">
|
||||
<span class="">{{ currentNumberOfItems }}</span>
|
||||
<img class="dropdown-icon" src="../../../assets/images/Arrow_Down_2.svg" alt="arrow" *ngIf="!displayDropdown">
|
||||
<img class="dropdown-icon" src="../../../assets/images/Arrow_Up.svg" alt="arrow" *ngIf="displayDropdown">
|
||||
</div>
|
||||
<div class="dropdown-options" #dropdown>
|
||||
<ul>
|
||||
<li *ngFor="let item of possibleItems" (click)="setNumberOfItems(item, dropdown)">{{ item }}</li>
|
||||
</ul>
|
||||
<!-- <span *ngFor="let item of possibleItems" (click)="setNumberOfItems(item, dropdown)">{{ item }}</span> -->
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn" (click)="switchSteps(true)">Ändern</a>
|
||||
</div>
|
||||
<div class="line bottom-line"></div>
|
||||
<div class="overview">
|
||||
<span class="items">{{ displayItemsNumber }} Artikel I {{ currentPoints }} Lesepunkte</span>
|
||||
<div class="overview-price-container">
|
||||
<span class="overview-price">Zwischensumme {{ currentPrice }} EUR</span>
|
||||
<span class="overview-tax">ohne Versandkosten</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn secondary" (click)="updateCart()">Weiter einkaufen</a>
|
||||
<a class="btn active" (click)="itemsConfirmed()">Bezahlen</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</app-modal>
|
||||
|
||||
@@ -1,24 +1,19 @@
|
||||
.modal {
|
||||
// COMMON STYLES
|
||||
.modal-step-1,
|
||||
.modal-step-2 {
|
||||
font-family: 'Open Sans';
|
||||
line-height: 21px;
|
||||
margin: 16px 0;
|
||||
height: 479px;
|
||||
width: 728px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
font-family: 'Open Sans';
|
||||
line-height: 21px;
|
||||
|
||||
&__header {
|
||||
padding-top: 20px;
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
}
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header {
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
@@ -30,8 +25,19 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__body {
|
||||
// FIRST STEP DESIGN
|
||||
.modal-step-1 {
|
||||
height: 479px;
|
||||
width: 728px;
|
||||
justify-content: center;
|
||||
|
||||
.header {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
@@ -39,29 +45,29 @@
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
|
||||
&__option {
|
||||
.option {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
|
||||
&__description {
|
||||
.description {
|
||||
font-size: 16px;
|
||||
max-width: 193px;
|
||||
margin-bottom: 25px;
|
||||
|
||||
&__take_away {
|
||||
&-take-away {
|
||||
position: relative;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
&__take_now {
|
||||
&-take-now {
|
||||
position: relative;
|
||||
top: 15px;
|
||||
}
|
||||
|
||||
&__delivery {
|
||||
&-delivery {
|
||||
position: relative;
|
||||
top: 9px;
|
||||
}
|
||||
@@ -74,44 +80,49 @@
|
||||
top: 156px;
|
||||
}
|
||||
|
||||
&__title__take_now {
|
||||
.title-take-now {
|
||||
width: 153px;
|
||||
}
|
||||
|
||||
&__img {
|
||||
.img {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 112px;
|
||||
|
||||
&__check {
|
||||
height: 12px;
|
||||
width: 16px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&__price {
|
||||
.dropdown-icon {
|
||||
height: 9px;
|
||||
width: 17px;
|
||||
}
|
||||
|
||||
.check {
|
||||
height: 12px;
|
||||
width: 16px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
// margin-bottom: 20px;
|
||||
|
||||
&__take_away {
|
||||
&-take-away {
|
||||
position: relative;
|
||||
top: 32px;
|
||||
}
|
||||
|
||||
&__take_now {
|
||||
&-take-now {
|
||||
position: relative;
|
||||
top: 57px;
|
||||
}
|
||||
|
||||
&__order {
|
||||
&-order {
|
||||
position: relative;
|
||||
top: 33px;
|
||||
}
|
||||
}
|
||||
|
||||
&__btn {
|
||||
.btn {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
@@ -123,7 +134,7 @@
|
||||
bottom: 25px;
|
||||
|
||||
|
||||
&__active, &:hover {
|
||||
&-active, &:hover {
|
||||
background-color: #f70400;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
@@ -131,7 +142,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__delivery {
|
||||
.delivery {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
@@ -143,73 +154,357 @@
|
||||
position: relative;
|
||||
top: 7px;
|
||||
|
||||
&__date {
|
||||
&-date {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
width: 165px;
|
||||
|
||||
position: relative;
|
||||
top: 4px;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&__location {
|
||||
.location {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 165px;
|
||||
width: 135px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
|
||||
&__take_away{
|
||||
position: relative;
|
||||
top: 8px;
|
||||
&-take-away {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
}
|
||||
|
||||
&__date {
|
||||
&-date-take-away {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
cursor: default;
|
||||
width: 165px;
|
||||
text-align: left;
|
||||
padding-top: 3px;
|
||||
|
||||
&__take_away{
|
||||
position: relative;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
&__order{
|
||||
position: relative;
|
||||
top: 5px;
|
||||
}
|
||||
|
||||
|
||||
position: relative;
|
||||
top: 5px;
|
||||
left: 7px;
|
||||
}
|
||||
|
||||
&__dropdown {
|
||||
&-dropdown {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 165px;
|
||||
position: fixed;
|
||||
top: 330px;
|
||||
top: 344px;
|
||||
left: 224px;
|
||||
z-index: 10;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
width: 225px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px -2px 24px 0px #dce2e9;
|
||||
overflow: hidden;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
width: 100%;
|
||||
padding: 15px 10px;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
// padding: 5px 0 5px 20px;
|
||||
padding: 7px 10px;
|
||||
font-weight: 300;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
|
||||
&:hover {
|
||||
background-color: #E9EDF9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
padding: 5px 0;
|
||||
background-color: #E9EDF9;
|
||||
padding: 5px 0 5px 20px;
|
||||
font-weight: 300;
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
background-color: #acbcce;
|
||||
background-color: #E9EDF9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-select-text {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
top: 9px;
|
||||
padding: 5px;
|
||||
|
||||
&-active {
|
||||
background-color: #E9EDF9;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SECOND STEP DESIGN
|
||||
|
||||
.modal-step-2 {
|
||||
height: 394px;
|
||||
width: 728px;
|
||||
justify-content: flex-start;
|
||||
|
||||
.header {
|
||||
h1 {
|
||||
margin-top: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
margin-top: 15px;
|
||||
|
||||
.body-heading {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
|
||||
img {
|
||||
height: 16px;
|
||||
width: 26px;
|
||||
margin-right: 13px;
|
||||
margin-top: 3px;
|
||||
margin-left: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
background-image: url('../../../assets/images/Line.svg');
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.body-content {
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
width: 97%;
|
||||
text-align: left;
|
||||
|
||||
img {
|
||||
height: 39px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.book-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
width: 112px;
|
||||
}
|
||||
|
||||
.order-details {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
height: 50px;
|
||||
width: 215px;
|
||||
position: relative;
|
||||
top: 13px;
|
||||
|
||||
.order-book-icon {
|
||||
height: 18px;
|
||||
width: 13px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
line-height: 25px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-delivery-info {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.dropdown_container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 35px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 9px;
|
||||
width: 17px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.dropdown-selected-text {
|
||||
padding: 5px;
|
||||
|
||||
&-active {
|
||||
background-color: #E9EDF9;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
top: 220px;
|
||||
z-index: 10;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
right: 115px;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 15px 10px;
|
||||
margin: 0;
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px -2px 24px 0px #dce2e9;
|
||||
padding: 15px 0;
|
||||
width: 60px;
|
||||
|
||||
li {
|
||||
padding: 7px 10px;
|
||||
font-weight: 300;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
|
||||
&:hover {
|
||||
background-color: #E9EDF9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #f70400;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-line {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.overview {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
justify-items: center;
|
||||
width: 93%;
|
||||
margin-top: 30px;
|
||||
|
||||
.items {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: rgba(167, 185, 203, 1);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.overview-price-container {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
justify-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.overview-price {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.overview-tax {
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
width: 93%;
|
||||
margin-top: 30px;
|
||||
|
||||
.btn {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #f70400;
|
||||
cursor: pointer;
|
||||
padding: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.secondary {
|
||||
width: 160px;
|
||||
|
||||
&:hover {
|
||||
background-color: #f70400;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: #f70400;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
color: #ffffff;
|
||||
margin-left: 30px;
|
||||
width: 121px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,11 @@
|
||||
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
|
||||
import { ModalService } from '../../core/services/modal.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { ChangeCurrentRoute } from 'src/app/core/store/actions/process.actions';
|
||||
|
||||
const points = 60;
|
||||
const price = 16.95;
|
||||
|
||||
@Component({
|
||||
selector: 'app-checkout',
|
||||
@@ -8,27 +14,87 @@ import { ModalService } from '../../core/services/modal.service';
|
||||
})
|
||||
export class CheckoutComponent implements OnInit {
|
||||
id = 'checkout-modal';
|
||||
|
||||
// Mocked data
|
||||
stepOne = true;
|
||||
stepTwoImgType = '';
|
||||
|
||||
// Step one mock data
|
||||
locations = [
|
||||
{ name: 'Filliale Stachus', date:'18.02.2019'},
|
||||
{ name: 'Filliale Berlin', date:'20.02.2019'},
|
||||
{ name: 'Filliale Frankfurt', date:'22.02.2019'}
|
||||
{ name: 'Filliale Stachus', date: '18.02.2019'},
|
||||
{ name: 'Filliale Berlin', date: '20.02.2019'},
|
||||
{ name: 'Filliale Frankfurt', date: '22.02.2019'}
|
||||
];
|
||||
currentLocation = this.locations[0];
|
||||
currentPickUpDate = this.locations[0].date;
|
||||
|
||||
|
||||
// Step two mock data
|
||||
currentNumberOfItems = 1;
|
||||
possibleItems = [1, 2, 3, 4];
|
||||
displayItemsNumber = 1;
|
||||
currentPrice = price.toLocaleString().replace('.', ',');
|
||||
currentPoints = points;
|
||||
|
||||
// Toggle for dropdown
|
||||
displayDropdown = false;
|
||||
|
||||
// Trigger other functionality if needed
|
||||
@Output() closed: EventEmitter<boolean> = new EventEmitter();
|
||||
|
||||
constructor(private modalService: ModalService) { }
|
||||
constructor(
|
||||
private modalService: ModalService,
|
||||
private store: Store,
|
||||
private router: Router
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
// STEP ONE
|
||||
selectLocation (locationIndx: number, dropdown: any) {
|
||||
this.currentLocation = this.locations[locationIndx];
|
||||
this.currentPickUpDate = this.currentLocation.date;
|
||||
this.toggleDropdown(dropdown);
|
||||
}
|
||||
|
||||
selectedAction(action: string) {
|
||||
if (action === 'mitnehmen') {
|
||||
this.stepTwoImgType = 'Take_now.svg';
|
||||
} else if (action === 'abholung') {
|
||||
this.stepTwoImgType = 'Package_Icon.svg';
|
||||
} else {
|
||||
this.stepTwoImgType = 'truck_Icon.svg';
|
||||
}
|
||||
this.switchSteps();
|
||||
|
||||
// Logic later
|
||||
}
|
||||
|
||||
// STEP TWO
|
||||
setNumberOfItems (numberOfItems: number, element: any) {
|
||||
this.currentNumberOfItems = numberOfItems;
|
||||
this.displayItemsNumber = numberOfItems;
|
||||
this.currentPoints = numberOfItems * points;
|
||||
this.currentPrice = (Math.round((numberOfItems * price) * 100) / 100).toLocaleString().replace('.', ',');
|
||||
this.toggleDropdown(element);
|
||||
}
|
||||
|
||||
updateCart() {
|
||||
// Save item to store
|
||||
|
||||
this.store.dispatch(new ChangeCurrentRoute('article-search'));
|
||||
this.router.navigate(['article-search']);
|
||||
this.closeModal();
|
||||
}
|
||||
|
||||
itemsConfirmed () {
|
||||
// Redirect to 'Kundensuche'
|
||||
this.closeModal();
|
||||
}
|
||||
|
||||
// COMMON
|
||||
openDropdown(element: any) {
|
||||
this.toggleDropdown(element);
|
||||
}
|
||||
|
||||
openDialog() {
|
||||
this.modalService.open(this.id);
|
||||
}
|
||||
@@ -36,21 +102,16 @@ export class CheckoutComponent implements OnInit {
|
||||
closeModal(dialogSubmited: boolean = false) {
|
||||
this.closed.emit(dialogSubmited);
|
||||
this.modalService.close(this.id);
|
||||
this.defaultValues();
|
||||
}
|
||||
|
||||
selectedAction(action: string) {
|
||||
// Logic later
|
||||
this.closeModal(true);
|
||||
}
|
||||
switchSteps(reset: boolean = false) {
|
||||
if (reset) {
|
||||
this.defaultValues();
|
||||
}
|
||||
|
||||
selectLocation (locationIndx: number, element: any) {
|
||||
this.currentLocation = this.locations[locationIndx];
|
||||
this.currentPickUpDate = this.currentLocation.date;
|
||||
this.toggleDropdown(element);
|
||||
}
|
||||
|
||||
openDropdown(element: any) {
|
||||
this.toggleDropdown(element);
|
||||
this.displayDropdown = false;
|
||||
this.stepOne = !this.stepOne;
|
||||
}
|
||||
|
||||
private toggleDropdown(element: any) {
|
||||
@@ -58,4 +119,11 @@ export class CheckoutComponent implements OnInit {
|
||||
this.displayDropdown = !this.displayDropdown;
|
||||
}
|
||||
|
||||
private defaultValues() {
|
||||
this.currentNumberOfItems = 1;
|
||||
this.displayItemsNumber = 1;
|
||||
this.currentPoints = points;
|
||||
this.currentPrice = price.toLocaleString().replace('.', ',');
|
||||
this.stepOne = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div *ngFor="let card of feed">
|
||||
<div *ngFor="let card of feed$ | async">
|
||||
<app-book-card *ngIf="card.type === 'BOOK'" [card]="card"></app-book-card>
|
||||
<app-event-card *ngIf="card.type === 'EVENT'" [card]="card"></app-event-card>
|
||||
<app-news-card *ngIf="card.type === 'NEWS'" [card]="card"></app-news-card>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Store, Select } from '@ngxs/store';
|
||||
import { FeedCard } from 'src/app/core/models/feed-card.model';
|
||||
import { FeedService } from 'feed-service';
|
||||
import { LoadFeed } from 'src/app/core/store/actions/feed.actions';
|
||||
import { FeedState } from 'src/app/core/store/state/feed.state';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
@@ -12,22 +12,12 @@ import { FeedService } from 'feed-service';
|
||||
})
|
||||
export class DashboardComponent implements OnInit {
|
||||
|
||||
feed$: Observable<FeedCard[]>;
|
||||
feed: FeedCard[];
|
||||
@Select(FeedState.getFeed) feed$: Observable<FeedCard[]>;
|
||||
constructor(
|
||||
private store: Store<AppState>,
|
||||
private feedService: FeedService
|
||||
) { }
|
||||
private store: Store
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
// this.store.dispatch(new LoadFeed());
|
||||
this.feed$ = this.store.select('feed');
|
||||
this.feed$.subscribe(
|
||||
(data: any) => this.feed = data
|
||||
);
|
||||
this.feedService.info().subscribe(
|
||||
(data: any) => console.log(data)
|
||||
);
|
||||
this.store.dispatch(new LoadFeed());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Filter } from 'src/app/core/models/filter.model';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { SelectFilterById, UnselectFilterById, ToggleFilterItemById } from 'src/app/core/actions/filter.actions';
|
||||
import { SelectFilterById, UnselectFilterById, ToggleFilterItemById } from 'src/app/core/store/actions/filter.actions';
|
||||
import { FilterItem } from 'src/app/core/models/filter-item.model';
|
||||
import { Store } from '@ngxs/store';
|
||||
|
||||
@Component({
|
||||
selector: 'app-filter-item',
|
||||
@@ -19,7 +18,7 @@ export class FilterItemComponent implements OnInit {
|
||||
@Input()
|
||||
expanded: boolean;
|
||||
|
||||
constructor(private store: Store<AppState>) { }
|
||||
constructor(private store: Store) { }
|
||||
|
||||
toggleMenu(id: number) {
|
||||
const action = this.filter.expanded ?
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Filter } from 'src/app/core/models/filter.model';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { LoadFilters, LoadFullFilters } from 'src/app/core/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';
|
||||
|
||||
@Component({
|
||||
selector: 'app-filter',
|
||||
@@ -11,16 +12,16 @@ import { LoadFilters, LoadFullFilters } from 'src/app/core/actions/filter.action
|
||||
})
|
||||
export class FilterComponent implements OnInit {
|
||||
|
||||
@Select(FilterState.getFilters) filters$: Observable<Filter[]>;
|
||||
filters: Filter[];
|
||||
showMore: boolean;
|
||||
|
||||
constructor(private store: Store<AppState>) { }
|
||||
constructor(private store: Store) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.store.dispatch(new LoadFilters());
|
||||
this.store.select('filters').subscribe(
|
||||
(data: Filter[]) => this.filters = data,
|
||||
(error: any) => console.error(error)
|
||||
this.filters$.subscribe(
|
||||
(filters: Filter[]) => this.filters = filters
|
||||
);
|
||||
this.showMore = false;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ import { Component, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Process } from 'src/app/core/models/process.model';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { Store, Select } from '@ngxs/store';
|
||||
import { ProcessState } from 'src/app/core/store/state/process.state';
|
||||
|
||||
@Component({
|
||||
selector: 'app-menu',
|
||||
@@ -12,11 +12,11 @@ import { AppState } from 'src/app/app.state';
|
||||
})
|
||||
export class MenuComponent implements OnInit {
|
||||
|
||||
processesObs: Observable<Process[]>;
|
||||
@Select(ProcessState.getProcesses) processes$: Observable<Process[]>;
|
||||
processes: Process[];
|
||||
|
||||
constructor(public router: Router,
|
||||
private store: Store<AppState>) { }
|
||||
private store: Store) { }
|
||||
activeMenu = '';
|
||||
|
||||
routeToMenu(menuPath: string, menuTag: string): void {
|
||||
@@ -25,8 +25,7 @@ export class MenuComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.processesObs = this.store.select('processes');
|
||||
this.processesObs.subscribe(
|
||||
this.processes$.subscribe(
|
||||
(data: Process[]) => this.processes = data
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Process } from 'src/app/core/models/process.model';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { reduce } from 'rxjs/operators';
|
||||
import { ADD_PROCESS } from 'src/app/core/actions/process.actions';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Breadcrumb } from 'src/app/core/models/breadcrumb.model';
|
||||
import { getRandomPic } from 'src/app/core/utils/process.util';
|
||||
import { Store, Select } from '@ngxs/store';
|
||||
import { AddProcess } from 'src/app/core/store/actions/process.actions';
|
||||
import { ProcessState } from 'src/app/core/store/state/process.state';
|
||||
|
||||
@Component({
|
||||
selector: 'app-process-header',
|
||||
@@ -16,41 +15,33 @@ import { getRandomPic } from 'src/app/core/utils/process.util';
|
||||
export class ProcessHeaderComponent implements OnInit {
|
||||
|
||||
startProcessLabel = 'VORGANG STARTEN';
|
||||
processObs: Observable<Process[]>;
|
||||
@Select(ProcessState.getProcesses) process$: Observable<Process[]>;
|
||||
processes: Process[];
|
||||
|
||||
constructor(private store: Store<AppState>) {
|
||||
this.processObs = store.select('processes');
|
||||
this.processObs.subscribe(
|
||||
(data: any) => this.loadProcesses(data),
|
||||
constructor(private store: Store) { }
|
||||
|
||||
addProcess() {
|
||||
const itemNo = this.processes.length === 0 ? 1 : this.processes[this.processes.length - 1].id + 1;
|
||||
const newProcess = <Process>{
|
||||
id: itemNo,
|
||||
name: '# ' + itemNo,
|
||||
selected: this.processes.length === 0 ? true : false,
|
||||
icon: getRandomPic(),
|
||||
breadcrumbs: <Breadcrumb[]>[{
|
||||
name: 'Artikelsuche',
|
||||
path: '/article-search'
|
||||
}],
|
||||
currentRoute: 'article-search'
|
||||
};
|
||||
|
||||
this.store.dispatch(new AddProcess(newProcess));
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.process$.subscribe(
|
||||
(data: any) => this.processes = data,
|
||||
(err) => console.log(err)
|
||||
);
|
||||
}
|
||||
|
||||
loadProcesses(data: Process[]) {
|
||||
this.processes = data;
|
||||
}
|
||||
|
||||
addProcess() {
|
||||
// find the next bigest id
|
||||
const itemNo = this.processes.length === 0 ? 1 : this.processes[this.processes.length - 1].id + 1;
|
||||
this.store.dispatch({
|
||||
type: ADD_PROCESS,
|
||||
payload: <Process>{
|
||||
id: itemNo,
|
||||
name: '# ' + itemNo,
|
||||
selected: this.processes.length === 0 ? true : false,
|
||||
icon: getRandomPic(),
|
||||
breadcrumbs: <Breadcrumb[]>[{
|
||||
name: 'Artikelsuche',
|
||||
path: '/article-search'
|
||||
}],
|
||||
currentRoute: 'article-search'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="grid-item">
|
||||
<div class="grid-item" id="{{process.id}}">
|
||||
<div class="grid-container" [ngClass]="{'selected-process': process.selected}">
|
||||
<div (click)="selectProcess(process)">
|
||||
<img class="process-leading-icon" src="/assets/images/{{process.icon}}.png">
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Process } from 'src/app/core/models/process.model';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { DELETE_PROCESS, SELECT_PROCESS } from 'src/app/core/actions/process.actions';
|
||||
import { Router } from '@angular/router';
|
||||
import { routerNgProbeToken } from '@angular/router/src/router_module';
|
||||
import { Store } from '@ngxs/store';
|
||||
import { DeleteProcess, SelectProcess } from 'src/app/core/store/actions/process.actions';
|
||||
|
||||
@Component({
|
||||
selector: 'app-process-tab',
|
||||
@@ -17,22 +15,16 @@ export class ProcessTabComponent implements OnInit {
|
||||
@Input() processes: Array<Process>;
|
||||
|
||||
constructor(
|
||||
private store: Store<AppState>,
|
||||
private store: Store,
|
||||
private router: Router
|
||||
) { }
|
||||
|
||||
deleteProcess(process: Process) {
|
||||
this.store.dispatch({
|
||||
type: DELETE_PROCESS,
|
||||
payload: process
|
||||
});
|
||||
this.store.dispatch(new DeleteProcess(process));
|
||||
}
|
||||
|
||||
selectProcess(process: Process): void {
|
||||
this.store.dispatch({
|
||||
type: SELECT_PROCESS,
|
||||
payload: process
|
||||
});
|
||||
this.store.dispatch(new SelectProcess(process));
|
||||
this.router.navigate([process.currentRoute]);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<div class="type-stock">
|
||||
<div class="type align-left">
|
||||
<div class="type-icon-container align-left">
|
||||
<img class="type-icon" src="../../../assets/images/{{productTypeIcon}}.svg">
|
||||
<img class="type-icon" src="../../../assets/images/Icon_{{product.typeIcon}}.svg">
|
||||
</div>
|
||||
<div class="type-text align-left">
|
||||
<span>{{product.type}}</span>
|
||||
|
||||
@@ -121,4 +121,8 @@
|
||||
.order span {
|
||||
font-size: 16px;
|
||||
color: #a7b9cb;
|
||||
}
|
||||
|
||||
.type-icon-container {
|
||||
padding-top: 3px;
|
||||
}
|
||||
@@ -20,7 +20,6 @@ export class ProductCardComponent implements OnInit {
|
||||
if (val !== this.product) {
|
||||
this._product = val;
|
||||
this.eanChangedSub.next(!!val ? val.ean : '');
|
||||
this.productTypeIcon = getProductTypeIcon(val.typeIcon);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
</p>
|
||||
<button class="btn" (click)="openModal()">Open checkout</button>
|
||||
|
||||
<app-checkout #checkout (closed)="openFeedbackModal($event)"></app-checkout>
|
||||
<app-shopping-cart-feedback #feedback></app-shopping-cart-feedback>
|
||||
<app-checkout #checkout (closed)="cartActionCompleted($event)"></app-checkout>
|
||||
<!-- <app-shopping-cart-feedback #feedback></app-shopping-cart-feedback> -->
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { CheckoutComponent } from '../checkout/checkout.component';
|
||||
import { ShoppingCartFeedbackComponent } from '../shopping-cart-feedback/shopping-cart-feedback.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-product-details',
|
||||
@@ -11,16 +9,14 @@ import { ShoppingCartFeedbackComponent } from '../shopping-cart-feedback/shoppin
|
||||
})
|
||||
export class ProductDetailsComponent implements OnInit {
|
||||
@ViewChild('checkout') checkoutDialog: CheckoutComponent;
|
||||
@ViewChild('feedback') feedbackDialog: ShoppingCartFeedbackComponent;
|
||||
|
||||
id: number;
|
||||
|
||||
constructor(
|
||||
private store: Store<AppState>) { }
|
||||
constructor(private route: ActivatedRoute) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select(state => state.router).subscribe(
|
||||
(data: any) => this.id = data.state.params.id
|
||||
this.route.params.subscribe(
|
||||
params => this.id = params['id']
|
||||
);
|
||||
}
|
||||
|
||||
@@ -28,13 +24,7 @@ export class ProductDetailsComponent implements OnInit {
|
||||
this.checkoutDialog.openDialog();
|
||||
}
|
||||
|
||||
openCheckoutModal() {
|
||||
this.checkoutDialog.openDialog();
|
||||
}
|
||||
|
||||
openFeedbackModal(open: boolean) {
|
||||
if (open) {
|
||||
this.feedbackDialog.openDialog();
|
||||
}
|
||||
cartActionCompleted(open: boolean) {
|
||||
// Logic if needed
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from 'src/app/app.state';
|
||||
import { Search } from 'src/app/core/models/search.model';
|
||||
import { Process } from 'src/app/core/models/process.model';
|
||||
import { Product } from 'src/app/core/models/product.model';
|
||||
import { GetProducts } from 'src/app/core/actions/product.actions';
|
||||
import { Router } from '@angular/router';
|
||||
import { ProductMapping } from '../../core/mappings/product.mapping';
|
||||
import { map, filter } from 'rxjs/operators';
|
||||
import { Select, Store } from '@ngxs/store';
|
||||
import { ProductsState } from 'src/app/core/store/state/products.state';
|
||||
import { ItemDTO } from 'dist/cat-service/lib/dtos';
|
||||
import { Observable } from 'rxjs';
|
||||
import { GetProducts } from 'src/app/core/store/actions/product.actions';
|
||||
|
||||
@Component({
|
||||
selector: 'app-search-results',
|
||||
@@ -18,9 +20,10 @@ export class SearchResultsComponent implements OnInit {
|
||||
|
||||
currentSearch: Search;
|
||||
products: Product[];
|
||||
@Select(ProductsState.getProducts) products$: Observable<ItemDTO[]>;
|
||||
|
||||
constructor(
|
||||
private store: Store<AppState>,
|
||||
private store: Store,
|
||||
private router: Router,
|
||||
private productMapping: ProductMapping
|
||||
) { }
|
||||
@@ -37,8 +40,8 @@ export class SearchResultsComponent implements OnInit {
|
||||
|
||||
loadCurrentSearch() {
|
||||
this.store.select(state => state.processes).subscribe(
|
||||
(data: Process[]) => {
|
||||
const process = data
|
||||
(data: any) => {
|
||||
const process = data.processes
|
||||
.find(t => t.selected === true);
|
||||
if (process) {
|
||||
this.currentSearch = process.search;
|
||||
@@ -48,10 +51,9 @@ export class SearchResultsComponent implements OnInit {
|
||||
}
|
||||
|
||||
loadProducts() {
|
||||
this.store.select(state => state.itemsDTO).pipe(
|
||||
this.products$.pipe(
|
||||
filter(f => Array.isArray(f)),
|
||||
map(items => items.map(item => this.productMapping.fromItemDTO(item)))
|
||||
).subscribe(data => this.products = data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
<app-modal id="feedback-modal">
|
||||
<div class="modal">
|
||||
<div class="header">
|
||||
<h1>Artikel wurde dem Warenkorb hinzugefügt</h1>
|
||||
<img (click)="closeModal()" class="close-icon" src="../../../assets/images/close.svg" alt="close">
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="body-heading">
|
||||
<img (click)="closeModal()" class="close-icon" src="../../../assets/images/truck_Icon.svg" alt="truck">
|
||||
<h1>Versand</h1>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="body-content">
|
||||
<img src="../../../assets/images/Book-2x.png" alt="book">
|
||||
<span class="book-title">Silberfischchtsy</span>
|
||||
<div class="order-details">
|
||||
<span><img class="order-book-icon" src="../../../assets/images/Book_Icon.svg" alt="book-icon"> TB I Inger-Maria Mahlke</span>
|
||||
<span class="bold">DHL I Lieferung 18.01.</span>
|
||||
</div>
|
||||
<span class="price">{{ currentPrice }} EUR</span>
|
||||
<div class="dropdown_container">
|
||||
<div (click)="openDropdown(dropdown)">
|
||||
<span class="">{{ currentNumberOfItems }}</span>
|
||||
<img class="dropdown-arrow" src="../../../assets/images/Arrow_Down_2.svg" alt="arrow">
|
||||
</div>
|
||||
<div class="dropdown-options" #dropdown>
|
||||
<span *ngFor="let item of possibleItems" (click)="setNumberOfItems(item, dropdown)">{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn" (click)="setDisplayNumber()">Ändern</a>
|
||||
</div>
|
||||
<div class="line bottom-line"></div>
|
||||
<div class="overview">
|
||||
<span class="items">{{ displayItemsNumber }} Artikel I {{ currentPoints }} Lesepunkte</span>
|
||||
<div class="overview-price-container">
|
||||
<span class="overview-price">Zwischensumme {{ currentPrice }} EUR</span>
|
||||
<span class="overview-tax">ohne Versandkosten</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn secondary" (click)="closeModal()">Weiter einkaufen</a>
|
||||
<a class="btn active" (click)="itemsConfirmed()">Bezahlen</a>
|
||||
</div>
|
||||
</div>
|
||||
</app-modal>
|
||||
@@ -1,247 +0,0 @@
|
||||
.modal {
|
||||
margin: 16px 0;
|
||||
height: 394px;
|
||||
width: 728px;
|
||||
font-family: 'Open Sans';
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
line-height: 21px;
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header {
|
||||
flex-grow: 0;
|
||||
|
||||
h1 {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
right: 25px;
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
.close-icon:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
margin-top: 15px;
|
||||
|
||||
.body-heading {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
|
||||
img {
|
||||
height: 16px;
|
||||
width: 26px;
|
||||
margin-right: 13px;
|
||||
margin-top: 3px;
|
||||
margin-left: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
background-image: url('../../../assets/images/Line.svg');
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.body-content {
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
width: 97%;
|
||||
text-align: left;
|
||||
|
||||
img {
|
||||
height: 39px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.book-title {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
width: 112px;
|
||||
}
|
||||
|
||||
.order-details {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
height: 50px;
|
||||
width: 215px;
|
||||
position: relative;
|
||||
top: 13px;
|
||||
|
||||
.order-book-icon {
|
||||
height: 18px;
|
||||
width: 13px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
line-height: 25px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.dropdown_container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 35px;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 9px;
|
||||
width: 17px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.dropdown-options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 38px;
|
||||
position: fixed;
|
||||
top: 205px;
|
||||
z-index: 10;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
padding: 5px 0;
|
||||
background-color: #E9EDF9;
|
||||
|
||||
&:hover {
|
||||
background-color: #acbcce;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #f70400;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-line {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.overview {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
justify-items: center;
|
||||
width: 93%;
|
||||
margin-top: 30px;
|
||||
|
||||
.items {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: rgba(167, 185, 203, 1);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.overview-price-container {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
justify-items: center;
|
||||
flex-direction: column;
|
||||
|
||||
.overview-price {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.overview-tax {
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
width: 93%;
|
||||
margin-top: 30px;
|
||||
|
||||
.btn {
|
||||
font-family: 'Open Sans';
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #f70400;
|
||||
cursor: pointer;
|
||||
padding: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.secondary {
|
||||
width: 160px;
|
||||
|
||||
&:hover {
|
||||
background-color: #f70400;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: #f70400;
|
||||
border: none;
|
||||
border-radius: 25px;
|
||||
color: #ffffff;
|
||||
margin-left: 30px;
|
||||
width: 121px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ShoppingCartFeedbackComponent } from './shopping-cart-feedback.component';
|
||||
|
||||
describe('ShoppingCartFeedbackComponent', () => {
|
||||
let component: ShoppingCartFeedbackComponent;
|
||||
let fixture: ComponentFixture<ShoppingCartFeedbackComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ShoppingCartFeedbackComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ShoppingCartFeedbackComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,64 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ModalService } from '../../core/services/modal.service';
|
||||
|
||||
const points = 60;
|
||||
const price = 16.95;
|
||||
|
||||
@Component({
|
||||
selector: 'app-shopping-cart-feedback',
|
||||
templateUrl: './shopping-cart-feedback.component.html',
|
||||
styleUrls: ['./shopping-cart-feedback.component.scss']
|
||||
})
|
||||
export class ShoppingCartFeedbackComponent implements OnInit {
|
||||
id = 'feedback-modal';
|
||||
|
||||
// Mocked data
|
||||
currentNumberOfItems = 1;
|
||||
possibleItems = [1, 2, 3, 4, 5];
|
||||
displayItemsNumber = 1;
|
||||
currentPrice = price.toLocaleString().replace('.', ',');
|
||||
currentPoints = points;
|
||||
|
||||
// Toggle for dropdown
|
||||
displayDropdown = false;
|
||||
|
||||
|
||||
constructor(private modalService: ModalService) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
openDialog() {
|
||||
this.modalService.open(this.id);
|
||||
}
|
||||
|
||||
closeModal() {
|
||||
this.modalService.close(this.id);
|
||||
}
|
||||
|
||||
setNumberOfItems (numberOfItems: number, element: any) {
|
||||
this.currentNumberOfItems = numberOfItems;
|
||||
this.toggleDropdown(element);
|
||||
}
|
||||
|
||||
openDropdown(element: any) {
|
||||
this.toggleDropdown(element);
|
||||
}
|
||||
|
||||
setDisplayNumber() {
|
||||
this.displayItemsNumber = this.currentNumberOfItems;
|
||||
this.currentPoints = this.currentNumberOfItems * points;
|
||||
this.currentPrice = (Math.round((this.currentNumberOfItems * price) * 100) / 100).toLocaleString().replace('.', ',');
|
||||
}
|
||||
|
||||
itemsConfirmed () {
|
||||
// Logic to be
|
||||
this.closeModal();
|
||||
}
|
||||
|
||||
private toggleDropdown(element: any) {
|
||||
console.log(element);
|
||||
element.style.display = this.displayDropdown ? 'none' : 'flex';
|
||||
this.displayDropdown = !this.displayDropdown;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { Breadcrumb } from '../models/breadcrumb.model';
|
||||
|
||||
export const ADD_BREADCRUMB = 'ADD_BREADCRUMB';
|
||||
|
||||
export class AddBreadcrumb implements Action {
|
||||
type: string;
|
||||
|
||||
constructor(public payload: Breadcrumb) {}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { FeedDTO } from 'feed-service';
|
||||
|
||||
export const LOAD_FEED = 'LOAD_FEED';
|
||||
export const LOAD_FEED_SUCCESS = 'LOAD_FEED_SUCCESS';
|
||||
export const LOAD_FEED_FAIL = 'LOAD_FEED_FAIL';
|
||||
|
||||
export class LoadFeed implements Action {
|
||||
readonly type = LOAD_FEED;
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
export class LoadFeedSuccess implements Action {
|
||||
readonly type = LOAD_FEED_SUCCESS;
|
||||
|
||||
constructor(public payload: FeedDTO) {}
|
||||
}
|
||||
|
||||
export class LoadFeedFail implements Action {
|
||||
readonly type = LOAD_FEED_FAIL;
|
||||
|
||||
constructor(public payload: string) {}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { Filter } from '../models/filter.model';
|
||||
|
||||
export const LOAD_FILTERS = 'LOAD_FILTERS';
|
||||
export const LOAD_FILTERS_SUCCESS = 'LOAD_FILTERS_SUCCESS';
|
||||
export const LOAD_FILTERS_FAIL = 'LOAD_FILTERS_FAIL';
|
||||
export const LOAD_FULL_FILTERS = 'LOAD_FULL_FILTERS';
|
||||
export const LOAD_FULL_FILTERS_SUCCESS = 'LOAD_FULL_FILTERS_SUCCESS';
|
||||
export const LOAD_FULL_FILTERS_FAIL = 'LOAD_FULL_FILTERS_FAIL';
|
||||
export const SELECT_FILTER_BY_ID = 'SELECT_FILTER_BY_ID';
|
||||
export const SELECT_FILTER_BY_ID_SUCCESS = 'SELECT_FILTER_BY_ID_SUCCESS';
|
||||
export const UNSELECT_FILTER_BY_ID = 'UNSELECT_FILTER_BY_ID';
|
||||
export const UNSELECT_FILTER_BY_ID_SUCCESS = 'UNSELECT_FILTER_BY_ID_SUCCESS';
|
||||
export const TOGGLE_FILTER_ITEM_BY_ID = 'TOGLE_FILTER_ITEM_BY_ID';
|
||||
export const TOGGLE_FILTER_ITEM_BY_ID_SUCCESS = 'TOGLE_FILTER_ITEM_BY_ID_SUCCESS';
|
||||
|
||||
export class LoadFilters implements Action {
|
||||
readonly type = LOAD_FILTERS;
|
||||
}
|
||||
|
||||
export class LoadFiltersSuccess implements Action {
|
||||
readonly type = LOAD_FILTERS_SUCCESS;
|
||||
|
||||
constructor(public payload: Filter[]) {}
|
||||
}
|
||||
|
||||
export class LoadFiltersFail implements Action {
|
||||
readonly type = LOAD_FILTERS_FAIL;
|
||||
|
||||
constructor(public payload: string) {}
|
||||
}
|
||||
|
||||
export class LoadFullFilters implements Action {
|
||||
readonly type = LOAD_FULL_FILTERS;
|
||||
}
|
||||
|
||||
export class LoadFullFiltersSuccess implements Action {
|
||||
readonly type = LOAD_FULL_FILTERS_SUCCESS;
|
||||
|
||||
constructor(public payload: Filter[]) {}
|
||||
}
|
||||
|
||||
export class LoadFullFiltersFail implements Action {
|
||||
readonly type = LOAD_FULL_FILTERS_FAIL;
|
||||
|
||||
constructor(public payload: string) {}
|
||||
}
|
||||
|
||||
export class SelectFilterById implements Action {
|
||||
readonly type = SELECT_FILTER_BY_ID;
|
||||
|
||||
constructor(public payload: number, public filters: Filter[]) {}
|
||||
}
|
||||
|
||||
export class SelectFilterByIdSuccess implements Action {
|
||||
readonly type = SELECT_FILTER_BY_ID_SUCCESS;
|
||||
|
||||
constructor(public payload: Filter[]) {}
|
||||
}
|
||||
|
||||
export class UnselectFilterById implements Action {
|
||||
readonly type = UNSELECT_FILTER_BY_ID;
|
||||
|
||||
constructor(public payload: number, public filters: Filter[]) {}
|
||||
}
|
||||
|
||||
export class UnselectFilterByIdSuccess implements Action {
|
||||
readonly type = UNSELECT_FILTER_BY_ID_SUCCESS;
|
||||
|
||||
constructor(public payload: Filter[]) {}
|
||||
}
|
||||
|
||||
export class ToggleFilterItemById implements Action {
|
||||
readonly type = TOGGLE_FILTER_ITEM_BY_ID;
|
||||
|
||||
constructor(public payload: number, public filters: Filter[]) {}
|
||||
}
|
||||
|
||||
export class ToggleFilterItemByIdSuccess implements Action {
|
||||
readonly type = TOGGLE_FILTER_ITEM_BY_ID_SUCCESS;
|
||||
|
||||
constructor(public payload: Filter[]) {}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { Process } from '../models/process.model';
|
||||
|
||||
export const ADD_PROCESS = 'ADD_PROCESS';
|
||||
export const DELETE_PROCESS = 'DELETE_PROCESS';
|
||||
export const SELECT_PROCESS = 'SELECT_PROCESS';
|
||||
export const CHANGE_CURRENT_ROUTE = 'CHANGE_CURRENT_ROUTE';
|
||||
|
||||
export class AddProcess implements Action {
|
||||
public type: string;
|
||||
|
||||
constructor(public payload: Process) {}
|
||||
}
|
||||
|
||||
export class DeleteProcess implements Action {
|
||||
public type: string;
|
||||
|
||||
constructor(public payload: Process) {}
|
||||
}
|
||||
|
||||
export class SelectProcess implements Action {
|
||||
public type: string;
|
||||
|
||||
constructor(public payload: Process) {}
|
||||
}
|
||||
|
||||
export class ChangeCurrentRoute implements Action {
|
||||
readonly type = CHANGE_CURRENT_ROUTE;
|
||||
|
||||
constructor(public payload: string) {}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { ItemDTO } from 'cat-service';
|
||||
|
||||
export const GET_PRODUCTS = 'GET_PRODUCTS';
|
||||
export const GET_PRODUCTS_SUCCESS = 'GET_PRODUCTS_SUCCESS';
|
||||
export const GET_PRODUCTS_FAIL = 'GET_PRODUCTS_FAIL';
|
||||
|
||||
export class GetProducts implements Action {
|
||||
readonly type = GET_PRODUCTS;
|
||||
|
||||
constructor(public payload: string) {}
|
||||
}
|
||||
|
||||
export class GetProductsSuccess implements Action {
|
||||
readonly type = GET_PRODUCTS_SUCCESS;
|
||||
|
||||
constructor(public payload: ItemDTO[]) {}
|
||||
}
|
||||
|
||||
export class GetProductsFail implements Action {
|
||||
readonly type = GET_PRODUCTS_FAIL;
|
||||
|
||||
constructor(public payload: string) {}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { RecentArticleSearch } from '../models/recent-article-search.model';
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
export const LOAD_RECENT_ARTICLES = 'LOAD_RECENT_ARTICLES';
|
||||
export const LOAD_RECENT_ARTICLES_SUCCESS = 'LOAD_RECENT_ARTICLES_SUCCESS';
|
||||
|
||||
export class LoadRecentArticle implements Action {
|
||||
readonly type = LOAD_RECENT_ARTICLES;
|
||||
}
|
||||
|
||||
export class LoadRecentArticleSuccess implements Action {
|
||||
readonly type = LOAD_RECENT_ARTICLES_SUCCESS;
|
||||
|
||||
constructor(public payload: RecentArticleSearch[]) {}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { Search } from '../models/search.model';
|
||||
|
||||
export const ADD_SEARCH = 'ADD_SEARCH';
|
||||
|
||||
export class AddSearch implements Action {
|
||||
readonly type = ADD_SEARCH;
|
||||
|
||||
constructor(public payload: Search) {}
|
||||
}
|
||||
|
||||
export type SearchActions = AddSearch;
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Actions, Effect, ofType } from '@ngrx/effects';
|
||||
import { FeedService, FeedDTO } from 'feed-service';
|
||||
import { LoadFeed, LOAD_FEED, LoadFeedSuccess } from '../actions/feed.actions';
|
||||
import { switchMap, map } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class FeedEffects {
|
||||
constructor(
|
||||
private action$: Actions,
|
||||
private feedService: FeedService
|
||||
) { }
|
||||
|
||||
// @Effect()
|
||||
// loadFeed = this.action$.pipe(
|
||||
// ofType<LoadFeed>(LOAD_FEED),
|
||||
// switchMap(() => {
|
||||
// console.log('test ');
|
||||
// return this.feedService.info().pipe(
|
||||
// map(feed => {
|
||||
// console.log(feed);
|
||||
// return new LoadFeedSuccess(<FeedDTO>{});
|
||||
// })
|
||||
// );
|
||||
// })
|
||||
// );
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
import { Effect, Actions, ofType } from '@ngrx/effects';
|
||||
import { FilterService } from '../services/filter.service';
|
||||
import { LoadFilters, LOAD_FILTERS, LoadFiltersSuccess, LOAD_FULL_FILTERS, LoadFullFiltersSuccess} from '../actions/filter.actions';
|
||||
import { LoadFiltersFail, SELECT_FILTER_BY_ID, SelectFilterById, SelectFilterByIdSuccess } from '../actions/filter.actions';
|
||||
import { UnselectFilterById, UNSELECT_FILTER_BY_ID, UnselectFilterByIdSuccess, LoadFullFilters } from '../actions/filter.actions';
|
||||
import { ToggleFilterItemById, TOGGLE_FILTER_ITEM_BY_ID, ToggleFilterItemByIdSuccess } from '../actions/filter.actions';
|
||||
import { LoadFullFiltersFail } from '../actions/filter.actions';
|
||||
|
||||
import { switchMap, map, catchError } from 'rxjs/operators';
|
||||
import { of } from 'rxjs';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class FilterEffects {
|
||||
constructor(
|
||||
private action$: Actions,
|
||||
private filterService: FilterService
|
||||
) {}
|
||||
|
||||
@Effect()
|
||||
getFilters$ = this.action$.pipe(
|
||||
ofType<LoadFilters>(LOAD_FILTERS),
|
||||
switchMap(() => {
|
||||
return this.filterService.getFilters().pipe(
|
||||
map(filters => new LoadFiltersSuccess(filters)),
|
||||
catchError(error => of(new LoadFiltersFail(error)))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@Effect()
|
||||
getFullFilters$ = this.action$.pipe(
|
||||
ofType<LoadFullFilters>(LOAD_FULL_FILTERS),
|
||||
switchMap(() => {
|
||||
return this.filterService.getFullFilter().pipe(
|
||||
map(filters => new LoadFullFiltersSuccess(filters)),
|
||||
catchError(error => of(new LoadFullFiltersFail(error)))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@Effect()
|
||||
selectFilterById$ = this.action$.pipe(
|
||||
ofType<SelectFilterById>(SELECT_FILTER_BY_ID),
|
||||
switchMap((action) => {
|
||||
return this.filterService.selectFilterById(action.filters, action.payload).pipe(
|
||||
map(filters => new SelectFilterByIdSuccess(filters))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@Effect()
|
||||
unselectFilterById$ = this.action$.pipe(
|
||||
ofType<UnselectFilterById>(UNSELECT_FILTER_BY_ID),
|
||||
switchMap((action) => {
|
||||
return this.filterService.unselectFilterById(action.filters, action.payload).pipe(
|
||||
map(filters => new UnselectFilterByIdSuccess(filters))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@Effect()
|
||||
toggleFilterItemById$ = this.action$.pipe(
|
||||
ofType<ToggleFilterItemById>(TOGGLE_FILTER_ITEM_BY_ID),
|
||||
switchMap((action) => {
|
||||
return this.filterService.toggleFilterItemsById(action.filters, action.payload).pipe(
|
||||
map(filters => new ToggleFilterItemByIdSuccess(filters))
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import { ProductEffects } from './product.effect';
|
||||
import { FilterEffects } from './filter.effect';
|
||||
|
||||
export const effects: any[] = [ProductEffects, FilterEffects];
|
||||
@@ -1,41 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Effect, Actions, ofType } from '@ngrx/effects';
|
||||
import { ProductService } from '../services/product.service';
|
||||
import { GET_PRODUCTS, GetProductsSuccess, GetProducts, GetProductsFail } from '../actions/product.actions';
|
||||
import { switchMap, map, catchError } from 'rxjs/operators';
|
||||
import { of } from 'rxjs';
|
||||
import { LoadRecentArticle, LOAD_RECENT_ARTICLES, LoadRecentArticleSuccess } from '../actions/recent-article-search.actions';
|
||||
|
||||
@Injectable()
|
||||
export class ProductEffects {
|
||||
constructor(
|
||||
private actions$: Actions,
|
||||
private productService: ProductService
|
||||
) { }
|
||||
|
||||
@Effect()
|
||||
getProducts$ = this.actions$.pipe(
|
||||
ofType<GetProducts>(GET_PRODUCTS),
|
||||
switchMap((action) => {
|
||||
return this.productService.searchItems(action.payload).pipe(
|
||||
map(items => new GetProductsSuccess(items)),
|
||||
catchError(error => of(new GetProductsFail(error)))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
@Effect()
|
||||
getRecentProducts$ = this.actions$.pipe(
|
||||
ofType<LoadRecentArticle>(LOAD_RECENT_ARTICLES),
|
||||
switchMap((action) => {
|
||||
return this.productService.getRecentSearches().pipe(
|
||||
map(products => {
|
||||
if (products) {
|
||||
return products.reverse().slice(0, 5);
|
||||
}
|
||||
}),
|
||||
map(searches => new LoadRecentArticleSuccess(searches))
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Breadcrumb } from '../models/breadcrumb.model';
|
||||
import { ADD_BREADCRUMB } from '../actions/breadcrumb.actions';
|
||||
|
||||
const initialBreadcrumbs = [
|
||||
<Breadcrumb>{
|
||||
name: 'Artikelsuche',
|
||||
path: 'article-search'
|
||||
}
|
||||
];
|
||||
|
||||
export function breadcrumbReducer(breadcrumbs: Breadcrumb[] = initialBreadcrumbs, action: any) {
|
||||
switch (action.type) {
|
||||
case ADD_BREADCRUMB:
|
||||
return [...breadcrumbs, action.payload];
|
||||
default:
|
||||
return breadcrumbs;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { FeedCard } from '../models/feed-card.model';
|
||||
import { feedMock } from 'mocks/feed.mock';
|
||||
import { LOAD_FEED, LOAD_FEED_SUCCESS, LOAD_FEED_FAIL } from '../actions/feed.actions';
|
||||
|
||||
export function feedReducer(feed: FeedCard[] = feedMock, action: any) {
|
||||
switch (action.type) {
|
||||
case LOAD_FEED:
|
||||
return;
|
||||
case LOAD_FEED_SUCCESS:
|
||||
return action.payload;
|
||||
case LOAD_FEED_FAIL:
|
||||
return action.payload;
|
||||
default:
|
||||
return feed;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { Filter } from '../models/filter.model';
|
||||
import { LOAD_FILTERS_SUCCESS, LOAD_FILTERS_FAIL, LOAD_FULL_FILTERS, LOAD_FULL_FILTERS_FAIL, } from '../actions/filter.actions';
|
||||
import { LOAD_FILTERS, SELECT_FILTER_BY_ID, SELECT_FILTER_BY_ID_SUCCESS } from '../actions/filter.actions';
|
||||
import { UNSELECT_FILTER_BY_ID, UNSELECT_FILTER_BY_ID_SUCCESS, LOAD_FULL_FILTERS_SUCCESS } from '../actions/filter.actions';
|
||||
import { TOGGLE_FILTER_ITEM_BY_ID, TOGGLE_FILTER_ITEM_BY_ID_SUCCESS } from '../actions/filter.actions';
|
||||
|
||||
export function filterReducer (filter: Filter[] = [], action: any) {
|
||||
switch (action.type) {
|
||||
case LOAD_FILTERS:
|
||||
return;
|
||||
case LOAD_FILTERS_SUCCESS:
|
||||
return [...action.payload];
|
||||
case LOAD_FILTERS_FAIL:
|
||||
// TODO: implement fail reducer
|
||||
return;
|
||||
case LOAD_FULL_FILTERS:
|
||||
return;
|
||||
case LOAD_FULL_FILTERS_SUCCESS:
|
||||
return [...action.payload];
|
||||
case LOAD_FULL_FILTERS_FAIL:
|
||||
// TODO: implement fail reducer
|
||||
return;
|
||||
case SELECT_FILTER_BY_ID:
|
||||
return;
|
||||
case SELECT_FILTER_BY_ID_SUCCESS:
|
||||
return [...action.payload];
|
||||
case UNSELECT_FILTER_BY_ID:
|
||||
return;
|
||||
case UNSELECT_FILTER_BY_ID_SUCCESS:
|
||||
return [...action.payload];
|
||||
case TOGGLE_FILTER_ITEM_BY_ID:
|
||||
return;
|
||||
case TOGGLE_FILTER_ITEM_BY_ID_SUCCESS:
|
||||
return [...action.payload];
|
||||
default:
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import { Process } from '../models/process.model';
|
||||
import { ADD_PROCESS, DELETE_PROCESS, SELECT_PROCESS, CHANGE_CURRENT_ROUTE } from '../actions/process.actions';
|
||||
import { ADD_SEARCH } from '../actions/search.actions';
|
||||
import { Search } from '../models/search.model';
|
||||
|
||||
export function processReducer(processes: Process[] = [], action: any) {
|
||||
switch (action.type) {
|
||||
case ADD_PROCESS:
|
||||
return [...processes, action.payload];
|
||||
case DELETE_PROCESS:
|
||||
return deleteProcessHandler(processes, action.payload);
|
||||
case SELECT_PROCESS:
|
||||
return selectProcessHandler(processes, action.payload);
|
||||
case ADD_SEARCH:
|
||||
return addSearchToCurrentProcessHandler(processes, action.payload);
|
||||
case CHANGE_CURRENT_ROUTE:
|
||||
return changeCurrentRouteHandler(processes, action.payload);
|
||||
default:
|
||||
return processes;
|
||||
}
|
||||
}
|
||||
|
||||
function deleteProcessHandler(currentProcessesState: Process[], process: Process): Process[] {
|
||||
const processes = [...currentProcessesState];
|
||||
processes.splice(processes.indexOf(process), 1);
|
||||
// if deleted process is selected set first process as selected
|
||||
if (process.selected === true && processes.length > 0) {
|
||||
processes[0].selected = true;
|
||||
}
|
||||
return processes;
|
||||
}
|
||||
|
||||
function selectProcessHandler(currentProcessesState: Process[], process: Process): Process[] {
|
||||
const processes = [...currentProcessesState];
|
||||
// remove previous process selection
|
||||
processes.find(function(p): boolean {
|
||||
return p.selected === true;
|
||||
}).selected = false;
|
||||
processes[processes.indexOf(process)].selected = true;
|
||||
return processes;
|
||||
}
|
||||
|
||||
function addSearchToCurrentProcessHandler(currentProcessesState: Process[], search: Search): Process[] {
|
||||
const processes = [...currentProcessesState];
|
||||
processes.find(t => t.selected === true).search = search;
|
||||
return processes;
|
||||
}
|
||||
|
||||
function changeCurrentRouteHandler(currentProcessesState: Process[], route: string): Process[] {
|
||||
const processes = [...currentProcessesState];
|
||||
processes.find(t => t.selected === true).currentRoute = route;
|
||||
return processes;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { GET_PRODUCTS, GET_PRODUCTS_SUCCESS, GET_PRODUCTS_FAIL } from '../actions/product.actions';
|
||||
import { ItemDTO } from 'cat-service';
|
||||
|
||||
export function productReducer(products: ItemDTO[] = [], action: any) {
|
||||
switch (action.type) {
|
||||
case GET_PRODUCTS:
|
||||
return;
|
||||
case GET_PRODUCTS_SUCCESS:
|
||||
return [...action.payload];
|
||||
case GET_PRODUCTS_FAIL:
|
||||
return { error: action.payload };
|
||||
default:
|
||||
return products;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { RecentArticleSearch } from '../models/recent-article-search.model';
|
||||
import { LOAD_RECENT_ARTICLES, LOAD_RECENT_ARTICLES_SUCCESS } from '../actions/recent-article-search.actions';
|
||||
|
||||
export function recentArticleSearchReducer(recentArticles: RecentArticleSearch[] = [], action: any) {
|
||||
switch (action.type) {
|
||||
case LOAD_RECENT_ARTICLES:
|
||||
return;
|
||||
case LOAD_RECENT_ARTICLES_SUCCESS:
|
||||
return action.payload;
|
||||
default:
|
||||
return recentArticles;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import * as fromRouter from '@ngrx/router-store';
|
||||
import { Params, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
|
||||
import { createFeatureSelector } from '@ngrx/store';
|
||||
|
||||
export interface RouterStateUrl {
|
||||
url: string;
|
||||
queryParams: Params;
|
||||
params: Params;
|
||||
}
|
||||
|
||||
export interface RouterState {
|
||||
routerReducer: fromRouter.RouterReducerState<RouterStateUrl>;
|
||||
}
|
||||
|
||||
export const getRouterState = createFeatureSelector<
|
||||
fromRouter.RouterReducerState<RouterStateUrl>
|
||||
>('routerReducer');
|
||||
|
||||
export class CustomSerializer implements fromRouter.RouterStateSerializer<RouterStateUrl> {
|
||||
serialize(routerState: RouterStateSnapshot): RouterStateUrl {
|
||||
const { url } = routerState;
|
||||
const { queryParams } = routerState.root;
|
||||
let state: ActivatedRouteSnapshot = routerState.root;
|
||||
while (state.firstChild) {
|
||||
state = state.firstChild;
|
||||
}
|
||||
const { params } = state;
|
||||
return { url, queryParams, params};
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ import { Observable, of } from 'rxjs';
|
||||
import { Filter } from '../models/filter.model';
|
||||
import { filterMock } from 'mocks/filters.mock';
|
||||
import { CatSearchService, ApiResponse, UISettingsDTO } from 'cat-service';
|
||||
import { expand } from 'rxjs/operators';
|
||||
import { FilterItem } from '../models/filter-item.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -12,21 +14,51 @@ export class FilterService {
|
||||
constructor(private service: CatSearchService) { }
|
||||
|
||||
selectFilterById(filters: Filter[], id: number): Observable<Filter[]> {
|
||||
filters.filter(t => t.expanded === true).forEach(t => t.expanded = false);
|
||||
filters.filter(t => t.id === id).forEach(t => t.expanded = true);
|
||||
return of(filters);
|
||||
const newFilterState = filters.map(
|
||||
(filter: Filter) => {
|
||||
if (filter.id === id) {
|
||||
return {...filter, expanded: true};
|
||||
}
|
||||
return {...filter, expanded: false };
|
||||
}
|
||||
);
|
||||
return of(newFilterState);
|
||||
}
|
||||
|
||||
unselectFilterById(filters: Filter[], id: number): Observable<Filter[]> {
|
||||
filters.filter(t => t.expanded === true).forEach(t => t.expanded = false);
|
||||
return of(filters);
|
||||
const newFilterState = filters.map(
|
||||
(filter: Filter) => {
|
||||
if (filter.id === id) {
|
||||
return {...filter, expanded: false};
|
||||
}
|
||||
return {...filter };
|
||||
}
|
||||
);
|
||||
return of(newFilterState);
|
||||
}
|
||||
|
||||
toggleFilterItemsById(filters: Filter[], id: number): Observable<Filter[]> {
|
||||
filters.filter(t => t.expanded === true)
|
||||
.forEach(t => t.items.filter(i => i.id === id)
|
||||
.forEach(d => d.selected = !d.selected));
|
||||
return of(filters);
|
||||
const newFilterState = filters.map(
|
||||
(filter: Filter) => {
|
||||
if (filter.expanded === true) {
|
||||
const newItemsState = this.toggleItem(filter.items, id);
|
||||
return { ...filter, items: newItemsState };
|
||||
}
|
||||
return { ...filter };
|
||||
}
|
||||
);
|
||||
return of(newFilterState);
|
||||
}
|
||||
|
||||
private toggleItem(items: FilterItem[], id: number): FilterItem[] {
|
||||
return items.map(
|
||||
(item: FilterItem) => {
|
||||
if (item.id === id) {
|
||||
return {...item, selected: !item.selected};
|
||||
}
|
||||
return { ...item };
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// service method to get the first 3 filters
|
||||
@@ -36,7 +68,6 @@ export class FilterService {
|
||||
// (data: ApiResponse<UISettingsDTO>) =>
|
||||
// console.log(data.result.filter, data.result.orderBy, data)
|
||||
// );
|
||||
console.log(filterMock);
|
||||
return of(filterMock.slice(0, 3));
|
||||
}
|
||||
|
||||
|
||||
@@ -77,4 +77,16 @@ export class ProductService {
|
||||
map(response => response.result)
|
||||
);
|
||||
}
|
||||
|
||||
getItemById(id: number): Observable<ItemDTO> {
|
||||
return this.searchService.getById(id).pipe(
|
||||
map(response => {
|
||||
if (response.error) {
|
||||
throw new Error(response.message);
|
||||
}
|
||||
return response;
|
||||
}),
|
||||
map(response => response.result)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
9
src/app/core/store/actions/breadcrumb.actions.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Breadcrumb } from '../../models/breadcrumb.model';
|
||||
|
||||
export const ADD_BREADCRUMB = '[BREADCRUMB] Add';
|
||||
|
||||
export class AddBreadcrumb {
|
||||
static readonly type = ADD_BREADCRUMB;
|
||||
|
||||
constructor(public payload: Breadcrumb) {}
|
||||
}
|
||||
5
src/app/core/store/actions/feed.actions.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const LOAD_FEED = '[FEED] Load';
|
||||
|
||||
export class LoadFeed {
|
||||
static readonly type = LOAD_FEED;
|
||||
}
|
||||
33
src/app/core/store/actions/filter.actions.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Filter } from '../../models/filter.model';
|
||||
|
||||
export const LOAD_FILTERS = '[FILTERS] Load';
|
||||
export const LOAD_FULL_FILTERS = '[FILTERS] Load full';
|
||||
export const SELECT_FILTER_BY_ID = '[FILTERS] Select by id';
|
||||
export const UNSELECT_FILTER_BY_ID = '[FILTERS] Unselect by id';
|
||||
export const TOGGLE_FILTER_ITEM_BY_ID = '[FILTERS] Toggle item by id';
|
||||
|
||||
export class LoadFilters {
|
||||
static readonly type = LOAD_FILTERS;
|
||||
}
|
||||
|
||||
export class LoadFullFilters {
|
||||
static readonly type = LOAD_FULL_FILTERS;
|
||||
}
|
||||
|
||||
export class SelectFilterById {
|
||||
static readonly type = SELECT_FILTER_BY_ID;
|
||||
|
||||
constructor(public id: number, public payload: Filter[]) {}
|
||||
}
|
||||
|
||||
export class UnselectFilterById {
|
||||
static readonly type = UNSELECT_FILTER_BY_ID;
|
||||
|
||||
constructor(public id: number, public payload: Filter[]) {}
|
||||
}
|
||||
|
||||
export class ToggleFilterItemById {
|
||||
static readonly type = TOGGLE_FILTER_ITEM_BY_ID;
|
||||
|
||||
constructor(public id: number, public payload: Filter[]) {}
|
||||
}
|
||||
38
src/app/core/store/actions/process.actions.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Process } from '../../models/process.model';
|
||||
import { Search } from '../../models/search.model';
|
||||
|
||||
export const ADD_PROCESS = '[PROCESS] Add';
|
||||
export const DELETE_PROCESS = '[PROCESS] Delete';
|
||||
export const SELECT_PROCESS = '[PROCESS] Select';
|
||||
export const CHANGE_CURRENT_ROUTE = '[PROCESS] Change current route';
|
||||
export const ADD_SEARCH = '[PROCESS] Add search';
|
||||
|
||||
export class AddProcess {
|
||||
static readonly type = ADD_PROCESS;
|
||||
|
||||
constructor(public payload: Process) {}
|
||||
}
|
||||
|
||||
export class DeleteProcess {
|
||||
static readonly type = DELETE_PROCESS;
|
||||
|
||||
constructor(public payload: Process) {}
|
||||
}
|
||||
|
||||
export class SelectProcess {
|
||||
static readonly type = SELECT_PROCESS;
|
||||
|
||||
constructor(public payload: Process) {}
|
||||
}
|
||||
|
||||
export class ChangeCurrentRoute {
|
||||
static readonly type = CHANGE_CURRENT_ROUTE;
|
||||
|
||||
constructor(public payload: string) {}
|
||||
}
|
||||
|
||||
export class AddSearch {
|
||||
static readonly type = ADD_SEARCH;
|
||||
|
||||
constructor(public payload: Search) {}
|
||||
}
|
||||
14
src/app/core/store/actions/product.actions.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export const LOAD_RECENT_PRODUCTS = '[PRODUCTS] Load recent';
|
||||
export const GET_PRODUCTS = '[PRODUCTS] Get';
|
||||
|
||||
export class LoadRecentProducts {
|
||||
static readonly type = LOAD_RECENT_PRODUCTS;
|
||||
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
export class GetProducts {
|
||||
static readonly type = GET_PRODUCTS;
|
||||
|
||||
constructor(public payload: string) {}
|
||||
}
|
||||
29
src/app/core/store/state/breadcrumbs.state.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Breadcrumb } from '../../models/breadcrumb.model';
|
||||
import { State, Selector, Action, StateContext } from '@ngxs/store';
|
||||
import { AddBreadcrumb } from '../actions/breadcrumb.actions';
|
||||
|
||||
export class BreadcrumbsStateModel {
|
||||
breadcrumbs: Breadcrumb[];
|
||||
}
|
||||
|
||||
@State<BreadcrumbsStateModel>({
|
||||
name: 'breadcrumbs',
|
||||
defaults: {
|
||||
breadcrumbs: []
|
||||
}
|
||||
})
|
||||
export class BreadcrumbsState {
|
||||
@Selector()
|
||||
static getBreadcrumbs(state: BreadcrumbsStateModel) {
|
||||
return state.breadcrumbs;
|
||||
}
|
||||
|
||||
@Action(AddBreadcrumb)
|
||||
add(ctx: StateContext<BreadcrumbsStateModel>, { payload }: AddBreadcrumb) {
|
||||
const state = ctx.getState();
|
||||
ctx.patchState({
|
||||
...state,
|
||||
breadcrumbs: [...state.breadcrumbs, payload]
|
||||
});
|
||||
}
|
||||
}
|
||||
38
src/app/core/store/state/feed.state.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { State, Selector, Action, StateContext } from '@ngxs/store';
|
||||
import { LoadFeed } from '../actions/feed.actions';
|
||||
import { feedMock } from 'mocks/feed.mock';
|
||||
import { FeedCard } from '../../models/feed-card.model';
|
||||
import { FeedService } from 'feed-service';
|
||||
|
||||
export class FeedStateModel {
|
||||
feed: FeedCard[];
|
||||
}
|
||||
|
||||
@State<FeedStateModel>({
|
||||
name: 'feed',
|
||||
defaults: {
|
||||
feed: []
|
||||
}
|
||||
})
|
||||
export class FeedState {
|
||||
|
||||
constructor(private feedService: FeedService) {}
|
||||
|
||||
@Selector()
|
||||
static getFeed(state: FeedStateModel) {
|
||||
return state.feed;
|
||||
}
|
||||
|
||||
@Action(LoadFeed)
|
||||
load(ctx: StateContext<FeedStateModel>) {
|
||||
const state = ctx.getState();
|
||||
// TODO: implement api call to state
|
||||
// this.feedService.info().subscribe(
|
||||
// (feed: any) => console.log(feed)
|
||||
// );
|
||||
ctx.patchState({
|
||||
...state,
|
||||
feed: [...feedMock]
|
||||
});
|
||||
}
|
||||
}
|
||||
90
src/app/core/store/state/filter.state.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Filter } from '../../models/filter.model';
|
||||
import { State, Selector, Action, StateContext } from '@ngxs/store';
|
||||
import { LoadFilters, LoadFullFilters, SelectFilterById, UnselectFilterById, ToggleFilterItemById } from '../actions/filter.actions';
|
||||
import { load } from '@angular/core/src/render3';
|
||||
import { FilterService } from '../../services/filter.service';
|
||||
|
||||
export class FilterStateModel {
|
||||
filters: Filter[];
|
||||
}
|
||||
|
||||
@State<FilterStateModel>({
|
||||
name: 'filters',
|
||||
defaults: {
|
||||
filters: []
|
||||
}
|
||||
})
|
||||
export class FilterState {
|
||||
|
||||
constructor(private filterService: FilterService) {}
|
||||
|
||||
@Selector()
|
||||
static getFilters(state: FilterStateModel) {
|
||||
return state.filters;
|
||||
}
|
||||
|
||||
@Action(LoadFilters)
|
||||
load(ctx: StateContext<FilterStateModel>) {
|
||||
const state = ctx.getState();
|
||||
this.filterService.getFilters().subscribe(
|
||||
(filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
filters: [...filters]
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Action(LoadFullFilters)
|
||||
loadFullFilters(ctx: StateContext<FilterStateModel>) {
|
||||
const state = ctx.getState();
|
||||
this.filterService.getFullFilter().subscribe(
|
||||
(filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
filters: [...filters]
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Action(SelectFilterById)
|
||||
selectFilterById(ctx: StateContext<FilterStateModel>, { id, payload }: SelectFilterById) {
|
||||
const state = ctx.getState();
|
||||
this.filterService.selectFilterById(payload, id).subscribe(
|
||||
(filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
filters: [...filters]
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Action(UnselectFilterById)
|
||||
unselectFilterById(ctx: StateContext<FilterStateModel>, { id, payload }: UnselectFilterById) {
|
||||
const state = ctx.getState();
|
||||
this.filterService.unselectFilterById(payload, id).subscribe(
|
||||
(filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
filters: [...filters]
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Action(ToggleFilterItemById)
|
||||
toggleItemById(ctx: StateContext<FilterStateModel>, { id, payload }: ToggleFilterItemById) {
|
||||
const state = ctx.getState();
|
||||
this.filterService.toggleFilterItemsById(payload, id).subscribe(
|
||||
(filters: Filter[]) => {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
filters: [...filters]
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
120
src/app/core/store/state/process.state.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { Process } from '../../models/process.model';
|
||||
import { State, Selector, Action, StateContext } from '@ngxs/store';
|
||||
import * as actions from '../actions/process.actions';
|
||||
|
||||
export class ProcessStateModel {
|
||||
processes: Process[];
|
||||
}
|
||||
|
||||
@State<ProcessStateModel>({
|
||||
name: 'processes',
|
||||
defaults: {
|
||||
processes: []
|
||||
}
|
||||
})
|
||||
export class ProcessState {
|
||||
@Selector()
|
||||
static getProcesses(state: ProcessStateModel) {
|
||||
return state.processes;
|
||||
}
|
||||
|
||||
@Action(actions.AddProcess)
|
||||
add(ctx: StateContext<ProcessStateModel>, { payload }: actions.AddProcess) {
|
||||
const state = ctx.getState();
|
||||
ctx.patchState({
|
||||
...state,
|
||||
processes: [...state.processes, payload]
|
||||
});
|
||||
}
|
||||
|
||||
@Action(actions.DeleteProcess)
|
||||
delete(ctx: StateContext<ProcessStateModel>, { payload }: actions.DeleteProcess) {
|
||||
const state = ctx.getState();
|
||||
const firstHalfProcesses = [...state.processes];
|
||||
const lastHalfProcesses = [...state.processes];
|
||||
const indexOfProcessToDelete = state.processes.indexOf(payload);
|
||||
const firstProcessIndexOfSecondHalf = indexOfProcessToDelete + 1;
|
||||
const newProcessState = [
|
||||
...firstHalfProcesses.splice(0, indexOfProcessToDelete).map(
|
||||
(process: Process) => {
|
||||
if (payload.selected === true && state.processes.length > 0 && process.id === state.processes[0].id) {
|
||||
return { ...process, selected: true };
|
||||
} else {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
),
|
||||
...lastHalfProcesses.splice(firstProcessIndexOfSecondHalf, lastHalfProcesses.length - indexOfProcessToDelete).map(
|
||||
(process: Process) => {
|
||||
if (payload.selected === true && state.processes.length > 0
|
||||
&& process.id === state.processes[firstProcessIndexOfSecondHalf].id
|
||||
&& indexOfProcessToDelete === 0) {
|
||||
return { ...process, selected: true };
|
||||
} else {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
)
|
||||
];
|
||||
ctx.patchState({
|
||||
...state,
|
||||
processes: newProcessState
|
||||
});
|
||||
}
|
||||
|
||||
@Action(actions.SelectProcess)
|
||||
select(ctx: StateContext<ProcessStateModel>, { payload }: actions.SelectProcess) {
|
||||
const state = ctx.getState();
|
||||
const newProcessState = state.processes.map(
|
||||
(process: Process) => {
|
||||
if (process.selected === true && process.id !== payload.id) {
|
||||
return { ...process, selected: false };
|
||||
} else if (process === payload) {
|
||||
return { ...process, selected: true };
|
||||
} else {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
);
|
||||
ctx.patchState({
|
||||
...state,
|
||||
processes: [...newProcessState]
|
||||
});
|
||||
}
|
||||
|
||||
@Action(actions.AddSearch)
|
||||
addSearch(ctx: StateContext<ProcessStateModel>, { payload }: actions.AddSearch) {
|
||||
const state = ctx.getState();
|
||||
const newProcessState = state.processes.map(
|
||||
(process: Process) => {
|
||||
if (process.selected === true) {
|
||||
return { ...process, search: payload };
|
||||
} else {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
);
|
||||
ctx.patchState({
|
||||
...state,
|
||||
processes: [...newProcessState]
|
||||
});
|
||||
}
|
||||
|
||||
@Action(actions.ChangeCurrentRoute)
|
||||
changeCurrentRoute(ctx: StateContext<ProcessStateModel>, { payload }: actions.ChangeCurrentRoute) {
|
||||
const state = ctx.getState();
|
||||
const newProcessState = state.processes.map(
|
||||
(process: Process) => {
|
||||
if (process.selected === true) {
|
||||
return { ...process, currentRoute: payload };
|
||||
} else {
|
||||
return process;
|
||||
}
|
||||
}
|
||||
);
|
||||
ctx.patchState({
|
||||
...state,
|
||||
processes: [...newProcessState]
|
||||
});
|
||||
}
|
||||
}
|
||||
63
src/app/core/store/state/products.state.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { RecentArticleSearch } from '../../models/recent-article-search.model';
|
||||
import { State, Selector, Action, StateContext } from '@ngxs/store';
|
||||
import { LoadRecentProducts, GetProducts } from '../actions/product.actions';
|
||||
import { ProductService } from '../../services/product.service';
|
||||
import { ItemDTO } from 'cat-service';
|
||||
|
||||
export class ProductsStateModel {
|
||||
recentArticles: RecentArticleSearch[];
|
||||
itemsDTO: ItemDTO[];
|
||||
}
|
||||
|
||||
@State<ProductsStateModel>({
|
||||
name: 'products',
|
||||
defaults: {
|
||||
recentArticles: [],
|
||||
itemsDTO: []
|
||||
}
|
||||
})
|
||||
export class ProductsState {
|
||||
|
||||
constructor(private productService: ProductService) {}
|
||||
|
||||
@Selector()
|
||||
static getRecentProducts(state: ProductsStateModel) {
|
||||
return state.recentArticles;
|
||||
}
|
||||
|
||||
@Selector()
|
||||
static getProducts(state: ProductsStateModel) {
|
||||
return state.itemsDTO;
|
||||
}
|
||||
|
||||
@Action(LoadRecentProducts)
|
||||
loadRecentProducts(ctx: StateContext<ProductsStateModel>) {
|
||||
const state = ctx.getState();
|
||||
this.productService.getRecentSearches().subscribe(
|
||||
(products: RecentArticleSearch[]) => {
|
||||
if (products) {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
recentArticles: products.reverse().slice(0, 5)
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Action(GetProducts)
|
||||
GetProducts(ctx: StateContext<ProductsStateModel>, { payload }: GetProducts) {
|
||||
const state = ctx.getState();
|
||||
this.productService.searchItems(payload).subscribe(
|
||||
(items: ItemDTO[]) => {
|
||||
if (items) {
|
||||
ctx.patchState({
|
||||
...state,
|
||||
itemsDTO: items
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
11
src/assets/images/Arrow_Up.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="18px" height="11px" viewBox="0 0 18 11" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Arrow_Down Copy 8</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||
<g id="Hugendubel_PoC_Dropdown" transform="translate(-1186.000000, -267.000000)" stroke="#B3C3D4" stroke-width="2.3">
|
||||
<polyline id="Arrow_Down-Copy-8" transform="translate(1195.000000, 272.500000) rotate(-180.000000) translate(-1195.000000, -272.500000) " points="1188 269 1195 276 1202 269"></polyline>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 824 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
11
src/assets/images/Icon_HC.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="22px" height="18px" viewBox="0 0 22 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Icon_HC</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Hugendubel_Icons" transform="translate(-29.000000, -177.000000)" fill="#000000" fill-rule="nonzero" stroke="#000000" stroke-width="0.3">
|
||||
<path d="M32.725699,178.000628 C32.7430505,177.999791 32.7604307,177.999791 32.7777823,178.000628 L37.5260449,178.000628 C38.53109,178.000628 39.44018,178.547926 40.0000026,179.340692 C40.5598253,178.547926 41.4689153,178.000628 42.4739603,178.000628 L47.222223,178.000628 C47.529035,178.00066 47.7777477,178.256627 47.7777784,178.572389 L47.7777784,179.71591 L49.4444446,179.71591 C49.7512567,179.715942 49.9999694,179.971909 50,180.287671 L50,192.008763 C49.9999694,192.324524 49.7512567,192.580492 49.4444446,192.580523 L42.4739603,192.580523 C41.4766486,192.580523 40.8524541,192.949423 40.4947942,193.688309 C40.3998428,193.879608 40.208727,194 40.0000026,194 C39.7912783,194 39.6001624,193.879608 39.5052111,193.688309 C39.1475512,192.949423 38.5233566,192.580523 37.5260449,192.580523 L30.5555607,192.580523 C30.2487486,192.580492 30.0000359,192.324524 30.0000053,192.008763 L30.0000053,180.287671 C29.9987652,179.991708 30.2171687,179.743681 30.5034773,179.71591 C30.5208289,179.715072 30.5382091,179.715072 30.5555607,179.71591 L32.2222269,179.71591 L32.2222269,178.572389 C32.2209869,178.276426 32.4393904,178.028399 32.725699,178.000628 Z M33.3333377,179.14415 L33.3333377,189.43584 L36.6232674,189.43584 C37.6190746,189.43584 38.5547188,189.729711 39.2621556,190.356017 C39.3270606,190.413476 39.3849347,190.480265 39.4444472,190.543626 L39.4444472,180.957703 C39.4433388,180.936873 39.4433388,180.915996 39.4444472,180.895166 C39.4444472,180.068361 38.4768339,179.14415 37.5260449,179.14415 L33.3333377,179.14415 Z M42.4739603,179.14415 C41.5231714,179.14415 40.555558,180.068361 40.555558,180.895166 C40.5555806,180.898144 40.5555806,180.901122 40.555558,180.9041 L40.555558,190.543626 C40.6150705,190.480265 40.6729447,190.413476 40.7378497,190.356017 C41.4452864,189.729711 42.3809306,189.43584 43.3767379,189.43584 L46.6666675,189.43584 L46.6666675,179.14415 L42.4739603,179.14415 Z M31.1111161,180.859431 L31.1111161,191.437002 L37.5260449,191.437002 C38.0365968,191.437002 38.5189494,191.531483 38.9496557,191.713949 C38.8273679,191.527334 38.6888269,191.36055 38.5329891,191.222592 C38.0547048,190.799175 37.405738,190.579361 36.6232674,190.579361 L32.7777823,190.579361 C32.4709702,190.57933 32.2222575,190.323362 32.2222269,190.007601 L32.2222269,180.859431 L31.1111161,180.859431 Z M47.7777784,180.859431 L47.7777784,190.007601 C47.7777477,190.323362 47.529035,190.57933 47.222223,190.579361 L43.3767379,190.579361 C42.5942672,190.579361 41.9453004,190.799175 41.4670161,191.222592 C41.3107359,191.360944 41.1725734,191.526903 41.0503496,191.713949 C41.4810558,191.531483 41.9634085,191.437002 42.4739603,191.437002 L48.8888892,191.437002 L48.8888892,180.859431 L47.7777784,180.859431 Z M35.5,182.116677 L37.5,182.116677 C37.7761424,182.116677 38,182.340535 38,182.616677 L38,182.645847 C38,182.921989 37.7761424,183.145847 37.5,183.145847 L35.5,183.145847 C35.2238576,183.145847 35,182.921989 35,182.645847 L35,182.616677 C35,182.340535 35.2238576,182.116677 35.5,182.116677 Z M35.5,184.175016 L37.5,184.175016 C37.7761424,184.175016 38,184.398874 38,184.675016 L38,184.704185 C38,184.980328 37.7761424,185.204185 37.5,185.204185 L35.5,185.204185 C35.2238576,185.204185 35,184.980328 35,184.704185 L35,184.675016 C35,184.398874 35.2238576,184.175016 35.5,184.175016 Z M35.5,186.233355 L37.5,186.233355 C37.7761424,186.233355 38,186.457212 38,186.733355 L38,186.762524 C38,187.038666 37.7761424,187.262524 37.5,187.262524 L35.5,187.262524 C35.2238576,187.262524 35,187.038666 35,186.762524 L35,186.733355 C35,186.457212 35.2238576,186.233355 35.5,186.233355 Z M42.5,182.116677 L44.5,182.116677 C44.7761424,182.116677 45,182.340535 45,182.616677 L45,182.645847 C45,182.921989 44.7761424,183.145847 44.5,183.145847 L42.5,183.145847 C42.2238576,183.145847 42,182.921989 42,182.645847 L42,182.616677 C42,182.340535 42.2238576,182.116677 42.5,182.116677 Z M42.5,184.175016 L44.5,184.175016 C44.7761424,184.175016 45,184.398874 45,184.675016 L45,184.704185 C45,184.980328 44.7761424,185.204185 44.5,185.204185 L42.5,185.204185 C42.2238576,185.204185 42,184.980328 42,184.704185 L42,184.675016 C42,184.398874 42.2238576,184.175016 42.5,184.175016 Z M42.5,186.233355 L44.5,186.233355 C44.7761424,186.233355 45,186.457212 45,186.733355 L45,186.762524 C45,187.038666 44.7761424,187.262524 44.5,187.262524 L42.5,187.262524 C42.2238576,187.262524 42,187.038666 42,186.762524 L42,186.733355 C42,186.457212 42.2238576,186.233355 42.5,186.233355 Z" id="Icon_HC"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
11
src/assets/images/Icon_MA.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Icon_MA</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Hugendubel_Icons" transform="translate(-30.000000, -64.000000)" fill="#000000" fill-rule="nonzero" stroke="#000000" stroke-width="0.6">
|
||||
<path d="M45.4,77 L45.4,67 C45.4,65.89536 44.50464,65 43.4,65 C43.38432,65 33,65 33,65 C31.89536,65 31,65.89536 31,67 L31,69 L34.2,69 C34.2,69.77104 34.2,79 34.2,79 C34.2,80.10464 35.09536,81 36.2,81 L45,81 C46.10464,81 47,80.10464 47,79 L47,77 L45.4,77 Z M34.2,68.2 L31.8,68.2 L31.8,67 C31.8,66.33824 32.33824,65.8 33,65.8 C33.66176,65.8 34.2,66.33824 34.2,67 L34.2,68.2 Z M37.4,79 C37.4,79.66176 36.86176,80.2 36.2,80.2 C35.53824,80.2 35,79.66176 35,79 L35,67 C35,66.54768 34.84448,66.1352 34.59056,65.8 L43.4,65.8 C44.06176,65.8 44.6,66.33824 44.6,67 L44.6,77 L37.4,77 L37.4,79 Z M46.2,79 C46.2,79.66176 45.66176,80.2 45,80.2 L37.79056,80.2 C38.04448,79.8648 38.2,79.45232 38.2,79 L38.2,77.8 L46.2,77.8 L46.2,79 Z" id="Icon_MA"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
11
src/assets/images/Icon_NB.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="14px" height="20px" viewBox="0 0 14 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Icon_NB</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Hugendubel_Icons" transform="translate(-33.000000, -138.000000)" fill="#000000" fill-rule="nonzero" stroke="#000000" stroke-width="0.9">
|
||||
<path d="M37.4137931,139.163636 L35.9655172,142.027273 L35.9655172,144.359091 C34.6827586,144.788636 34,145.381818 34,146.056818 L34,154.709091 C34,155.997727 36.6275862,157 40,157 C43.3724138,157 46,155.997727 46,154.729545 L46,146.077273 C46,145.484091 45.4413793,144.931818 44.4482759,144.522727 L44.4482759,139 L41.5517241,139 L41.5517241,143.868182 C40.6578753,143.780758 39.758215,143.767074 38.862069,143.827273 L38.862069,142.027273 L37.4137931,139.163636 Z M37.4137931,140.084091 L38.4482759,142.129545 L38.4482759,147.877273 C37.7478333,147.81206 37.0551354,147.681943 36.3793103,147.488636 L36.3793103,142.109091 L37.4137931,140.084091 Z M35.9655172,144.809091 L35.9655172,147.365909 C34.9724138,147.018182 34.4137931,146.547727 34.4137931,146.077273 C34.4137931,145.606818 34.9931034,145.156818 35.9655172,144.809091 Z M40,156.590909 C36.6482759,156.590909 34.4137931,155.629545 34.4137931,154.729545 L34.4137931,146.915909 C35.2827586,147.754545 37.4344828,148.347727 40,148.347727 C42.5655172,148.347727 44.7172414,147.754545 45.5862069,146.915909 L45.5862069,154.709091 C45.5862069,155.629545 43.3517241,156.590909 40,156.590909 Z M44.0344828,147.365909 C43.3639001,147.595667 42.6702492,147.753394 41.9655172,147.836364 L41.9655172,141.863636 L44.0344828,141.863636 L44.0344828,147.365909 Z M45.5862069,146.077273 C45.5862069,146.465909 45.1724138,146.854545 44.4482759,147.181818 L44.4482759,144.972727 C45.1724138,145.3 45.5862069,145.688636 45.5862069,146.077273 Z M44.0344828,139.409091 L44.0344828,141.454545 L41.9655172,141.454545 L41.9655172,139.409091 L44.0344828,139.409091 Z M41.5517241,144.277273 L41.5517241,147.877273 C41.0758621,147.918182 40.5586207,147.959091 40,147.959091 L38.862069,147.918182 L38.862069,144.256818 C39.7575696,144.187775 40.6574039,144.194618 41.5517241,144.277273 Z" id="Icon_NB"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
11
src/assets/images/Icon_SW.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Icon_SW</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Hugendubel_Icons" transform="translate(-30.000000, -29.000000)" fill="#000100" stroke="#000000" stroke-width="0.8">
|
||||
<path d="M44.2965531,35.7000934 C43.7251245,34.4563959 42.783948,33.3807656 41.573864,32.7421102 L41.8091581,32.3051354 C43.1200825,33.0110177 44.1620993,34.1538749 44.7671413,35.4984127 L44.2965531,35.7000934 Z M39,46 C34.581722,46 31,42.418278 31,38 C31,33.581722 34.581722,30 39,30 C43.418278,30 47,33.581722 47,38 C47,42.418278 43.418278,46 39,46 Z M39,45.4621849 C43.1212509,45.4621849 46.4621849,42.1212509 46.4621849,38 C46.4621849,33.8787491 43.1212509,30.5378151 39,30.5378151 C34.8787491,30.5378151 31.5378151,33.8787491 31.5378151,38 C31.5378151,42.1212509 34.8787491,45.4621849 39,45.4621849 Z M38.9930984,41.0222222 C37.2779986,41.0222222 35.8819873,39.6262108 35.8819873,37.9111111 C35.8819873,36.1960114 37.2779986,34.8 38.9930984,34.8 C40.7081981,34.8 42.1042095,36.1960114 42.1042095,37.9111111 C42.1042095,39.6262108 40.7081981,41.0222222 38.9930984,41.0222222 Z M38.9930984,35.3584046 C37.597087,35.3584046 36.4802779,36.4752137 36.4802779,37.8712251 C36.4802779,39.2672365 37.597087,40.3840456 38.9930984,40.3840456 C40.3891098,40.3840456 41.5059189,39.2672365 41.5059189,37.8712251 C41.5059189,36.4752137 40.3891098,35.3584046 38.9930984,35.3584046 Z M38.9930984,39.2444444 C38.2658256,39.2444444 37.659765,38.6383838 37.659765,37.9111111 C37.659765,37.1838384 38.2658256,36.5777778 38.9930984,36.5777778 C39.7203711,36.5777778 40.3264317,37.1838384 40.3264317,37.9111111 C40.3264317,38.6383838 39.7203711,39.2444444 38.9930984,39.2444444 Z M38.9930984,37.0323232 C38.5082499,37.0323232 38.1143105,37.4262626 38.1143105,37.9111111 C38.1143105,38.3959596 38.5082499,38.789899 38.9930984,38.789899 C39.4779468,38.789899 39.8718862,38.3959596 39.8718862,37.9111111 C39.8718862,37.4262626 39.4779468,37.0323232 38.9930984,37.0323232 Z" id="Icon_SW"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
11
src/assets/images/Icon_VI.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.2 (67145) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Icon_VI</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Hugendubel_Icons" transform="translate(-30.000000, -214.000000)" fill="#000000" fill-rule="nonzero" stroke="#000000" stroke-width="0.5">
|
||||
<path d="M40,233 C35.0294373,233 31,228.970563 31,224 C31,219.029437 35.0294373,215 40,215 C44.9705627,215 49,219.029437 49,224 C49,228.970563 44.9705627,233 40,233 Z M40,216 C35.581722,216 32,219.581722 32,224 C32,228.418278 35.581722,232 40,232 C44.418278,232 48,228.418278 48,224 C48,219.581722 44.418278,216 40,216 Z M43.055,223.371888 C43.21,223.461888 43.3,223.626888 43.3,223.801888 C43.3,223.976888 43.21,224.141888 43.055,224.231888 L38.055,227.231888 C37.98,227.276888 37.89,227.301888 37.8,227.301888 C37.715,227.301888 37.63,227.281888 37.555,227.236888 C37.395,227.146888 37.3,226.981888 37.3,226.801888 L37.3,220.801888 C37.3,220.621888 37.39,220.456888 37.55,220.366888 C37.71,220.276888 37.9,220.276888 38.055,220.371888 L43.055,223.371888 Z M38.3,225.916888 L41.83,223.801888 L38.3,221.681888 L38.3,225.916888 Z" id="Icon_VI"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
11
src/assets/images/Icon_ZS.svg
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
@@ -6,6 +6,7 @@
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700" rel="stylesheet">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
41
yarn.lock
@@ -312,26 +312,6 @@
|
||||
lodash "^4.17.10"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@ngrx/effects@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngrx/effects/-/effects-7.0.0.tgz#57ea3a42ed970b748e78292e54fe02a768027b05"
|
||||
integrity sha512-lhwt+UMDPYuxeTQ5vBw/MuKrIroHvQ6cLy0nGvNl8oPxakI2Jz/NAPuTYd+AdV/6ao9M9+kxXhQRFkAV53EEjA==
|
||||
|
||||
"@ngrx/router-store@^7.1.0":
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngrx/router-store/-/router-store-7.1.0.tgz#931bdc902d806b3d026e99604748ebfefcd82dc3"
|
||||
integrity sha512-xLTtdLvbgwFyhXU9A/kYsuVruvp8w7WcNorGq0LyWCwI+rk4twaNFJLUx/rVnLbzfXLichU8kHAiRmR8VD438A==
|
||||
|
||||
"@ngrx/store-devtools@^7.1.0":
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngrx/store-devtools/-/store-devtools-7.1.0.tgz#ea5248d616b2bdf7607e9f4a1c80aa4365e0f830"
|
||||
integrity sha512-r0LUFQKxKOhFIO2TBK7k6eoOCT6WGQFXzOFTWwctU7teQgSSpzyUVQfsULfAyFpGN9f1hog9leY/J/EVjdwBQQ==
|
||||
|
||||
"@ngrx/store@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-7.0.0.tgz#5472000197c2a388b09afceb2d062cb37b03d334"
|
||||
integrity sha512-fF4A4De/vtQawxGBc1jV5HiLrc/J3NS8A2UDRoD3kLdviDzAlAber6kuj5XmM+xxaI9f9qnUrwOVXr/oPfqoBg==
|
||||
|
||||
"@ngtools/json-schema@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngtools/json-schema/-/json-schema-1.1.0.tgz#c3a0c544d62392acc2813a42c8a0dc6f58f86922"
|
||||
@@ -348,6 +328,27 @@
|
||||
tree-kill "1.2.0"
|
||||
webpack-sources "1.2.0"
|
||||
|
||||
"@ngxs/devtools-plugin@^3.3.4":
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@ngxs/devtools-plugin/-/devtools-plugin-3.3.4.tgz#7836ddb94245a8f5bd5137599c66a1a8aea31993"
|
||||
integrity sha512-gwVbK+utZlikIJ1wOC8WuOqAjB3t55J4LYiN9VwSxntvnXEAe+J2PQrnvK0e/C9df8HAbytGK2Jbisg00QO/ew==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@ngxs/logger-plugin@^3.3.4":
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@ngxs/logger-plugin/-/logger-plugin-3.3.4.tgz#74d7e56e7577d56206e25e36ce48d79c5ba99ca8"
|
||||
integrity sha512-e2lbWZdPlMaOuESVitppkmqG4c/v3N885HQqcyVZNLFl8hZd4+XnKFBqCdO95zvfWeRc/nMXhb+3fC/AaQVIBA==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@ngxs/store@^3.3.4":
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@ngxs/store/-/store-3.3.4.tgz#dced015eedf054bc651bbc1b67b590287cec7437"
|
||||
integrity sha512-99J2/+Tg/yoq+Fs9mfC6bgGnywV85TLIBkO8DWVN6mPVh2DQ6WlsxgvJjZcp0J5Uw8v5+uKsTit6OXeDxO5VOw==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@schematics/angular@7.2.2":
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-7.2.2.tgz#5a466ebbbd7e1fbb13851f26446ec308b822d1dc"
|
||||
|
||||