Implemented model for search-result compoent & added search-result component & product-card compoenent also added navigation when click loop on recent searches

This commit is contained in:
Eraldo Hasanaj
2019-01-29 17:02:27 +01:00
parent fe89da3ce3
commit e2cc975c67
17 changed files with 157 additions and 42 deletions

View File

@@ -18,12 +18,12 @@ import { filterReducer } from './core/reducers/filter.reducer';
import { FilterService } from './core/services/filter.service';
import { BasicAuthorizationInterceptor } from './core/interceptors';
import { SearchResultsComponent } from './components/search-results/search-results.component';
import { searchReducer } from './core/reducers/search.reducer';
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, CatSearchService } from 'projects/cat-service/src/lib';
import { CatServiceModule, CatSearchService, CatSearchMockService } from 'projects/cat-service/src/lib';
import { ProductCardComponent } from './components/product-card/product-card.component';
const rootReducer = {
processes: processReducer,
@@ -32,7 +32,6 @@ const rootReducer = {
recentArticleSearch: recentArticleSearchReducer,
products: productReducer,
filters: filterReducer,
search: searchReducer,
routerReducer: fromRouter.routerReducer
};
@@ -48,7 +47,8 @@ export function _basicAuthorizationInterceptorFactory() {
@NgModule({
declarations: [
AppComponent,
SearchResultsComponent
SearchResultsComponent,
ProductCardComponent
],
imports: [
BrowserModule,
@@ -68,12 +68,12 @@ export function _basicAuthorizationInterceptorFactory() {
FilterService,
{ provide: RouterStateSerializer, useClass: CustomSerializer },
{ provide: HTTP_INTERCEPTORS, useFactory: _basicAuthorizationInterceptorFactory, multi: true },
// { provide: CatSearchService, useClass: CatSearchMockService } // Uncomment if u want to use the CatSearchMockService
{ provide: CatSearchService, useClass: CatSearchMockService } // Uncomment if u want to use the CatSearchMockService
],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(cat: CatSearchService) {
cat.settings().subscribe(console.log.bind(window));
cat.settings().subscribe();
}
}

View File

@@ -3,7 +3,7 @@ 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 { RouterStateUrl } from './core/reducers/router.reducer';
import { Filter } from './core/models/filter.model';
export class AppState {
readonly processes: Process[];
@@ -12,5 +12,5 @@ export class AppState {
readonly recentArticleSearch: RecentArticleSearch[];
readonly products: Product[];
readonly error: string;
readonly routerStateUrl: RouterStateUrl;
readonly filters: Filter[];
}

View File

@@ -30,7 +30,7 @@
<div class="recent-search-content">
<div *ngFor="let article of recentArticles" class="recent-article">
<div class="recent-article-container align-left">
<div><img class="lupe-icon" src="../../../assets/images/Lupe_Icon.svg"></div>
<div (click)="showRecentSearchResults(article)"><img class="lupe-icon" src="../../../assets/images/Lupe_Icon.svg"></div>
<div class="recent-article-label">{{article.name}}</div>
</div>
</div>

View File

@@ -4,9 +4,12 @@ import { AppState } from 'src/app/app.state';
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 { GetProducts } from 'src/app/core/actions/product.actions';
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 } from 'src/app/core/actions/process.actions';
@Component({
selector: 'app-article-search',
@@ -19,6 +22,7 @@ export class ArticleSearchComponent implements OnInit {
recentArticles: RecentArticleSearch[];
products$: Observable<Product[]>;
products: Product[];
filters: Filter[];
@Input()
searchParams = '';
@@ -30,9 +34,18 @@ export class ArticleSearchComponent implements OnInit {
search() {
if (!this.searchParams) { return; }
this.router.navigate(['search-results']);
// this.store.dispatch(new GetProducts(this.searchParams));
// this.store.dispatch(new LoadRecentArticle());
this.loadSelectedFilters();
const search = <Search>{
query: this.searchParams,
fitlers: this.filters
};
this.store.dispatch(new AddSearch(search));
this.navigateToRoute('search-results');
}
navigateToRoute(route: string) {
this.store.dispatch(new ChangeCurrentRoute(route));
this.router.navigate([route]);
}
clear() {
@@ -46,6 +59,11 @@ export class ArticleSearchComponent implements OnInit {
}
}
showRecentSearchResults(article: RecentArticleSearch) {
this.searchParams = article.name;
this.search();
}
searchProductsHandler(data: any) {
if (data) {
if (data.error) {
@@ -69,8 +87,14 @@ export class ArticleSearchComponent implements OnInit {
);
}
loadSelectedFilters() {
// TODO filter selected filters
this.store.select('filters').subscribe(
(data: Filter[]) => this.filters = data
);
}
ngOnInit() {
this.loadRecentArticles();
this.loadSearchResults();
}
}

View File

@@ -43,7 +43,8 @@ export class ProcessHeaderComponent implements OnInit {
breadcrumbs: <Breadcrumb[]>[{
name: 'Artikelsuche',
path: '/article-search'
}]
}],
currentRoute: 'article-search'
}
});
}

View File

@@ -3,6 +3,8 @@ 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';
@Component({
selector: 'app-process-tab',
@@ -14,7 +16,10 @@ export class ProcessTabComponent implements OnInit {
@Input() process: Process;
@Input() processes: Array<Process>;
constructor(private store: Store<AppState>) { }
constructor(
private store: Store<AppState>,
private router: Router
) { }
deleteProcess(process: Process) {
this.store.dispatch({
@@ -28,6 +33,7 @@ export class ProcessTabComponent implements OnInit {
type: SELECT_PROCESS,
payload: process
});
this.router.navigate([process.currentRoute]);
}
ngOnInit() {

View File

@@ -0,0 +1 @@
<div>{{product.title}}</div>

View File

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ProductCardComponent } from './product-card.component';
describe('ProductCardComponent', () => {
let component: ProductCardComponent;
let fixture: ComponentFixture<ProductCardComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ProductCardComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProductCardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,19 @@
import { Component, OnInit, Input } from '@angular/core';
import { Product } from 'src/app/core/models/product.model';
@Component({
selector: 'app-product-card',
templateUrl: './product-card.component.html',
styleUrls: ['./product-card.component.scss']
})
export class ProductCardComponent implements OnInit {
@Input()
product: Product;
constructor() { }
ngOnInit() {
}
}

View File

@@ -1,3 +1,5 @@
<p>
search-results works!
</p>
<div class="result-container">
<app-product-card *ngFor="let product of products"
[product]="product">
</app-product-card>
</div>

View File

@@ -1,9 +1,11 @@
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from 'src/app/app.state';
import { Observable } from 'rxjs';
import { Process } from 'src/app/core/models/process.model';
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';
@Component({
selector: 'app-search-results',
@@ -12,15 +14,34 @@ import { Search } from 'src/app/core/models/search.model';
})
export class SearchResultsComponent implements OnInit {
process$: Observable<Process>;
search: Search;
currentSearch: Search;
products: Product[];
constructor(private store: Store<AppState>) { }
constructor(
private store: Store<AppState>,
private router: Router
) { }
ngOnInit() {
this.store.select('search').subscribe(
(data: Process) => this.search = data.search
this.loadCurrentSearch();
if (!this.currentSearch) {
this.router.navigate(['dashboard']);
return;
}
this.store.dispatch(new GetProducts(this.currentSearch.query));
this.loadProducts();
}
loadCurrentSearch() {
this.store.select(state => state.processes).subscribe(
(data: Process[]) => this.currentSearch = data
.find(t => t.selected === true).search
);
}
loadProducts() {
this.store.select(state => state.products).subscribe(
(data: Product[]) => this.products = data
);
}
}

View File

@@ -4,6 +4,7 @@ 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;
@@ -22,3 +23,9 @@ export class SelectProcess implements Action {
constructor(public payload: Process) {}
}
export class ChangeCurrentRoute implements Action {
readonly type = CHANGE_CURRENT_ROUTE;
constructor(public payload: string) {}
}

View File

@@ -6,5 +6,7 @@ export const ADD_SEARCH = 'ADD_SEARCH';
export class AddSearch implements Action {
readonly type = ADD_SEARCH;
constructor(public payload: Search[]) {}
constructor(public payload: Search) {}
}
export type SearchActions = AddSearch;

View File

@@ -7,7 +7,7 @@ export interface Process {
name: string;
selected: boolean;
icon: string;
currentRoute: string;
breadcrumbs: Breadcrumb[];
filters: Filter[];
search: Search;
}

View File

@@ -1,14 +1,20 @@
import { Process } from '../models/process.model';
import { ADD_PROCESS, DELETE_PROCESS, SELECT_PROCESS } from '../actions/process.actions';
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)];
return deleteProcessHandler(processes, action.payload);
case SELECT_PROCESS:
return [...selectProcessHandler(processes, action.payload)];
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;
}
@@ -33,3 +39,15 @@ function selectProcessHandler(currentProcessesState: Process[], process: Process
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;
}

View File

@@ -1,11 +0,0 @@
import { Process } from '../models/process.model';
import { ADD_SEARCH } from '../actions/search.actions';
export function searchReducer(process: Process = <Process>{}, action: any) {
switch (action.type) {
case ADD_SEARCH:
return {...process, search: action.payload};
default:
return process;
}
}