Added @ngrx/ruter-state which will be used for state management of url navigation

This commit is contained in:
Eraldo Hasanaj
2019-01-29 13:43:32 +01:00
parent 4d62fc77ad
commit c3b45fb227
18 changed files with 826 additions and 32 deletions

View File

@@ -20,7 +20,9 @@
"@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",
"core-js": "^2.5.4",
"rxjs": "~6.3.3",
"tslib": "^1.9.0",

View File

@@ -18,6 +18,12 @@ import { filterReducer } from './core/reducers/filter.reducer';
import { FilterService } from './core/services/filter.service';
import { BasicAuthorizationInterceptor } from './core/interceptors';
import { CatServiceModule } from 'projects/cat-service/src/lib';
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';
const rootReducer = {
processes: processReducer,
@@ -25,7 +31,9 @@ const rootReducer = {
feed: feedReducer,
recentArticleSearch: recentArticleSearchReducer,
products: productReducer,
filters: filterReducer
filters: filterReducer,
search: searchReducer,
routerReducer: fromRouter.routerReducer
};
export function _basicAuthorizationInterceptorFactory() {
@@ -39,7 +47,8 @@ export function _basicAuthorizationInterceptorFactory() {
@NgModule({
declarations: [
AppComponent
AppComponent,
SearchResultsComponent
],
imports: [
BrowserModule,
@@ -48,11 +57,16 @@ export function _basicAuthorizationInterceptorFactory() {
StoreModule.forRoot(rootReducer),
HttpClientModule,
EffectsModule.forRoot(effects),
StoreRouterConnectingModule,
StoreDevtoolsModule.instrument({
maxAge: 25
}),
CatServiceModule.forRoot('https://catsearch.paragon-data.de')
],
providers: [
ProductService,
FilterService,
{ provide: RouterStateSerializer, useClass: CustomSerializer },
{ provide: HTTP_INTERCEPTORS, useFactory: _basicAuthorizationInterceptorFactory, multi: true }
],
bootstrap: [AppComponent]

View File

@@ -3,6 +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';
export class AppState {
readonly processes: Process[];
@@ -11,4 +12,5 @@ export class AppState {
readonly recentArticleSearch: RecentArticleSearch[];
readonly products: Product[];
readonly error: string;
readonly routerStateUrl: RouterStateUrl;
}

View File

@@ -6,6 +6,7 @@ import { RecentArticleSearch } from 'src/app/core/models/recent-article-search.m
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';
@Component({
selector: 'app-article-search',
@@ -22,12 +23,16 @@ export class ArticleSearchComponent implements OnInit {
@Input()
searchParams = '';
constructor(private store: Store<AppState>) { }
constructor(
private store: Store<AppState>,
private router: Router
) { }
search() {
if (!this.searchParams) { return; }
this.store.dispatch(new GetProducts(this.searchParams));
this.store.dispatch(new LoadRecentArticle());
this.router.navigate(['search-results']);
// this.store.dispatch(new GetProducts(this.searchParams));
// this.store.dispatch(new LoadRecentArticle());
}
clear() {
@@ -46,7 +51,6 @@ export class ArticleSearchComponent implements OnInit {
if (data.error) {
console.error(data.error);
} else {
console.log(data);
this.products = data;
}
}

View File

@@ -0,0 +1,3 @@
<p>
search-results works!
</p>

View File

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

View File

@@ -0,0 +1,26 @@
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';
@Component({
selector: 'app-search-results',
templateUrl: './search-results.component.html',
styleUrls: ['./search-results.component.scss']
})
export class SearchResultsComponent implements OnInit {
process$: Observable<Process>;
search: Search;
constructor(private store: Store<AppState>) { }
ngOnInit() {
this.store.select('search').subscribe(
(data: Process) => this.search = data.search
);
}
}

View File

@@ -0,0 +1,10 @@
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[]) {}
}

View File

@@ -1,4 +1,6 @@
import { Breadcrumb } from './breadcrumb.model';
import { Filter } from './filter.model';
import { Search } from './search.model';
export interface Process {
id: number;
@@ -6,4 +8,6 @@ export interface Process {
selected: boolean;
icon: string;
breadcrumbs: Breadcrumb[];
filters: Filter[];
search: Search;
}

View File

@@ -0,0 +1,6 @@
import { Filter } from './filter.model';
export interface Search {
query: string;
fitlers: Filter[];
}

View File

@@ -6,9 +6,9 @@ export function processReducer(processes: Process[] = [], action: any) {
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)];
default:
return processes;
}

View File

@@ -7,7 +7,7 @@ export function productReducer(products: Product[] = [], action: any) {
case GET_PRODUCTS:
return;
case GET_PRODUCTS_SUCCESS:
return action.payload;
return [...action.payload];
case GET_PRODUCTS_FAIL:
return { error: action.payload };
default:

View File

@@ -6,7 +6,7 @@ export function recentArticleSearchReducer(recentArticles: RecentArticleSearch[]
case LOAD_RECENT_ARTICLES:
return;
case LOAD_RECENT_ARTICLES_SUCCESS:
return action.payload;
return [...action.payload];
default:
return recentArticles;
}

View File

@@ -0,0 +1,30 @@
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};
}
}

View File

@@ -0,0 +1,11 @@
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;
}
}

View File

@@ -1,9 +1,11 @@
import { Routes } from '@angular/router';
import { DashboardComponent } from 'src/app/components/dashboard/dashboard.component';
import { ArticleSearchComponent } from 'src/app/components/article-search/article-search.component';
import { SearchResultsComponent } from 'src/app/components/search-results/search-results.component';
export const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'article-search', component: ArticleSearchComponent }
{ path: 'article-search', component: ArticleSearchComponent },
{ path: 'search-results', component: SearchResultsComponent }
];

697
yarn.lock
View File

File diff suppressed because it is too large Load Diff