mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
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:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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[];
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ export class ProcessHeaderComponent implements OnInit {
|
||||
breadcrumbs: <Breadcrumb[]>[{
|
||||
name: 'Artikelsuche',
|
||||
path: '/article-search'
|
||||
}]
|
||||
}],
|
||||
currentRoute: 'article-search'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<div>{{product.title}}</div>
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
19
src/app/components/product-card/product-card.component.ts
Normal file
19
src/app/components/product-card/product-card.component.ts
Normal 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() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -7,7 +7,7 @@ export interface Process {
|
||||
name: string;
|
||||
selected: boolean;
|
||||
icon: string;
|
||||
currentRoute: string;
|
||||
breadcrumbs: Breadcrumb[];
|
||||
filters: Filter[];
|
||||
search: Search;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user