user store service added

This commit is contained in:
byung eun park 2019-08-13 22:28:38 +09:00
parent 16d721e5be
commit 0e94a19d27
29 changed files with 463 additions and 15 deletions

View File

@ -0,0 +1,37 @@
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { UserModule } from './pages/users/user/user.module';
import { AppService } from './service/app.service';
export function initApp(appService: AppService) {
return () => appService.initApp();
}
@NgModule({
imports: [
UserModule.forRoot(),
],
exports: [],
providers: [
AppService,
// ...GUARDS,
// CookieService,
// ClipboardService,
{
provide: APP_INITIALIZER,
useFactory: initApp,
deps: [AppService],
multi: true
},
// { provide: HTTP_INTERCEPTORS, useClass: AuthHttpInterceptor, multi: true },
{ provide: 'virtualScroller.scrollThrottlingTime', useValue: 0 },
{ provide: 'virtualScroller.scrollDebounceTime', useValue: 0 },
{ provide: 'virtualScroller.scrollAnimationTime', useValue: 750 },
{ provide: 'virtualScroller.scrollbarWidth', useValue: undefined },
{ provide: 'virtualScroller.scrollbarHeight', useValue: undefined },
{ provide: 'virtualScroller.checkResizeInterval', useValue: 1000 },
{ provide: 'virtualScroller.resizeBypassRefreshThreshold', useValue: 5 }
]
})
export class AppProviderModule { }

View File

@ -0,0 +1,49 @@
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import {
StoreRouterConnectingModule,
} from '@ngrx/router-store';
import { EffectsModule } from '@ngrx/effects';
import { environment } from '../environments/environment';
import { REDUCERS, META_REDUCERS, EFFECTS } from './store';
@NgModule({
exports: [
StoreModule,
],
imports: [
StoreModule.forRoot(REDUCERS, { metaReducers: META_REDUCERS }),
/**
* @ngrx/router-store keeps router state up-to-date in the store.
*/
StoreRouterConnectingModule.forRoot({
/*
They stateKey defines the name of the state used by the router-store reducer.
This matches the key defined in the map of reducers
*/
stateKey: 'router',
}),
/**
* Store devtools instrument the store retaining past versions of state
* and recalculating new states. This enables powerful time-travel
* debugging.
*
* To use the debugger, install the Redux Devtools extension for either
* Chrome or Firefox
*
* See: https://github.com/zalmoxisus/redux-devtools-extension
*/
StoreDevtoolsModule.instrument({
name: 'WebApp DevTools',
maxAge: 50,
logOnly: environment.production,
}),
EffectsModule.forRoot(EFFECTS),
],
providers: [
],
})
export class AppStoreModule { }

View File

@ -17,6 +17,8 @@ import {
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AppStoreModule } from './app-store.module';
import { AppProviderModule } from './app-provider.module';
import { appFuseConfig } from './app.fuse'; import { appFuseConfig } from './app.fuse';
import { LayoutModule } from './layout/layout.module'; import { LayoutModule } from './layout/layout.module';
@ -43,10 +45,12 @@ import { from } from 'rxjs';
FuseThemeOptionsModule, FuseThemeOptionsModule,
HttpClientModule, HttpClientModule,
AppRoutingModule,
// App modules // App modules
LayoutModule AppRoutingModule,
AppStoreModule,
AppProviderModule,
LayoutModule,
], ],
declarations: [AppComponent], declarations: [AppComponent],
providers: [], providers: [],

View File

@ -0,0 +1,48 @@
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { AbstractService, httpOptions } from './abstract.service';
import { Base } from '../../../../../shared/common/model/base.model';
export abstract class AbstractRestService<T extends Base> extends AbstractService<T> {
public constructor(httpClient: HttpClient, apiEntryPoint: string) {
super(httpClient, apiEntryPoint);
}
public getAll(): Observable<T[]> {
return this.httpClient.get<T[]>(this.apiEntryPoint);
}
public get(id: string | number): Observable<T> {
return this.httpClient.get<T>(this.apiEntryPoint + `/${id}`, httpOptions);
}
public save(model: T): Observable<T> {
return model.id ? this.update(model) : this.add(model);
}
public add(model: T): Observable<T> {
return this.httpClient.put<T>(
this.apiEntryPoint,
JSON.stringify(model),
httpOptions
);
}
public update(model: T): Observable<T> {
if (!model.id) {
throwError('id of model is not valid');
}
return this.httpClient.post<T>(
`${this.apiEntryPoint}`,
JSON.stringify(model),
httpOptions
);
}
public delete(id: string | number): Observable<T> {
return this.httpClient.delete<T>(
`${this.apiEntryPoint}/${id}`,
httpOptions
);
}
}

View File

@ -0,0 +1,18 @@
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Base } from '../../../../../shared/common/model/base.model';
export const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
export abstract class AbstractService<T extends Base> {
public constructor(
protected httpClient: HttpClient,
protected apiEntryPoint: string,
) {
}
}

View File

@ -1,5 +1,5 @@
import { UserDetailComponent } from './user-detail.component'; import { UserDetailComponent } from './user-detail/user-detail.component';
import { UserListComponent } from './user-list.component'; import { UserListComponent } from './user-list/user-list.component';
import { UserConnectComponent } from './user-connect/user-connect.component'; import { UserConnectComponent } from './user-connect/user-connect.component';
import { UserRegistComponent } from './user-regist/user-regist.component'; import { UserRegistComponent } from './user-regist/user-regist.component';
import { UserFeesComponent } from './user-fees/user-fees.component'; import { UserFeesComponent } from './user-fees/user-fees.component';

View File

@ -9,7 +9,7 @@ import {
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { DataSource } from '@angular/cdk/collections'; import { DataSource } from '@angular/cdk/collections';
import { BehaviorSubject, fromEvent, merge, Observable, Subject } from 'rxjs'; import { BehaviorSubject, fromEvent, merge, Observable, Subject, from } from 'rxjs';
import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators';
import { fuseAnimations } from 'src/@fuse/animations'; import { fuseAnimations } from 'src/@fuse/animations';
@ -17,6 +17,9 @@ import { FuseUtils } from 'src/@fuse/utils';
import { takeUntil } from 'rxjs/internal/operators'; import { takeUntil } from 'rxjs/internal/operators';
import { User } from '../../../../../../shared/user/model/user.model';
import { UserService } from '../../service/user.service';
@Component({ @Component({
selector: 'app-user-user-list', selector: 'app-user-user-list',
templateUrl: './user-list.component.html', templateUrl: './user-list.component.html',
@ -61,7 +64,7 @@ export class UserListComponent implements OnInit, OnDestroy {
* Constructor * Constructor
*/ */
constructor( constructor(
private userService: UserService
) { ) {
// Set the private defaults // Set the private defaults
@ -76,7 +79,7 @@ export class UserListComponent implements OnInit, OnDestroy {
* On init * On init
*/ */
ngOnInit(): void { ngOnInit(): void {
this.fetchUserList();
} }
/** /**
@ -87,4 +90,15 @@ export class UserListComponent implements OnInit, OnDestroy {
this._unsubscribeAll.next(); this._unsubscribeAll.next();
this._unsubscribeAll.complete(); this._unsubscribeAll.complete();
} }
fetchUserList() {
this.userService.getAllUsers().pipe(
map((userList: User[]) => {
if (userList && 0 < userList.length) {
console.log(userList);
}
})
).subscribe();
}
} }

View File

@ -0,0 +1,5 @@
import { UserService } from './user.service';
export const SERVICES = [
UserService
];

View File

@ -0,0 +1,18 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../../../../environments/environment';
import { User } from '../../../../../shared/user/model/user.model';
import { AbstractRestService } from '../../../common/util/service/abstract-rest.service';
@Injectable()
export class UserService extends AbstractRestService<User> {
public constructor(httpClient: HttpClient) {
super(httpClient, environment.apiEntryPoint + '/users');
}
public getAllUsers(): Observable<User[]> {
return this.httpClient.get<User[]>(`${this.apiEntryPoint}`);
}
}

View File

@ -0,0 +1,16 @@
import {
createSelector,
createFeatureSelector,
} from '@ngrx/store';
// tslint:disable-next-line:no-empty-interface
export interface State {
}
export const REDUCERS = {
};
export const EFFECTS = [
];
export const selectState = createFeatureSelector<State>('user');

View File

@ -1,8 +1,8 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { UserDetailComponent } from './component/user-detail.component'; import { UserDetailComponent } from './component/user-detail/user-detail.component';
import { UserListComponent } from './component/user-list.component'; import { UserListComponent } from './component/user-list/user-list.component';
import { UserConnectComponent } from './component/user-connect/user-connect.component'; import { UserConnectComponent } from './component/user-connect/user-connect.component';
import { UserRegistComponent } from './component/user-regist/user-regist.component'; import { UserRegistComponent } from './component/user-regist/user-regist.component';
import { UserFeesComponent } from './component/user-fees/user-fees.component'; import { UserFeesComponent } from './component/user-fees/user-fees.component';

View File

@ -0,0 +1,25 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import {
REDUCERS,
EFFECTS,
} from './store';
@NgModule({
imports: [
StoreModule.forFeature('user', REDUCERS),
EffectsModule.forFeature(EFFECTS),
],
})
export class UserStoreModule {
}
@NgModule({
imports: [
UserStoreModule,
],
exports: []
})
export class UserRootModule { }

View File

@ -1,4 +1,4 @@
import { NgModule } from '@angular/core'; import { NgModule, ModuleWithProviders } from '@angular/core';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatChipsModule } from '@angular/material/chips'; import { MatChipsModule } from '@angular/material/chips';
@ -26,6 +26,9 @@ import { MatStepperModule } from '@angular/material/stepper';
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns'; import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
import { UserStoreModule } from './user-store.module';
import { SERVICES } from './service';
@NgModule({ @NgModule({
imports: [ imports: [
MatButtonModule, MatButtonModule,
@ -59,4 +62,19 @@ import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
declarations: [...COMPONENTS], declarations: [...COMPONENTS],
}) })
export class UserModule { } export class UserModule {
public static forRoot(): ModuleWithProviders<UserRootModule> {
return {
ngModule: UserRootModule,
providers: [...SERVICES]
};
}
}
@NgModule({
imports: [
UserStoreModule,
],
exports: []
})
export class UserRootModule { }

View File

@ -0,0 +1,26 @@
import { Injectable } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { MatDialog } from '@angular/material';
import { EventManager } from '@angular/platform-browser';
import { CookieService } from 'ngx-cookie-service';
import { TranslateService } from '@ngx-translate/core';
@Injectable()
export class AppService {
constructor(
private store: Store<any>,
private eventManager: EventManager,
private cookieService: CookieService,
private tanslateService: TranslateService,
// private matDialog: MatDialog,
// private accountsService: AccountsService,
) { }
initApp(): Promise<any> {
// return new Promise((resolve, reject) => {
// const browserLang = this.tanslateService.getBrowserCultureLang();
// });
return null;
}
}

66
src/app/store/index.ts Normal file
View File

@ -0,0 +1,66 @@
import { Type } from '@angular/core';
import {
ActionReducer,
ActionReducerMap,
MetaReducer,
createSelector,
} from '@ngrx/store';
import * as fromRouter from '@ngrx/router-store';
import { environment } from '../../environments/environment';
// import * as AppEventsStore from './events';
// import * as AppLayoutStore from './layout';
// import * as AppLoginStore from './login';
// import * as AppNicknameStore from './nickname';
import * as AppRouterStore from './router';
export const EFFECTS: Type<any>[] = [
// AppLoginStore.Effects,
// AppEventsStore.Effects,
// AppNicknameStore.Effects,
AppRouterStore.Effects,
];
export const REDUCERS: ActionReducerMap<any> = {
router: fromRouter.routerReducer,
// layout: AppLayoutStore.reducer,
// events: AppEventsStore.reducer,
};
// console.log all actions
export function logger(reducer: ActionReducer<State>): ActionReducer<State> {
return function (state: State, action: any): State {
const result = reducer(state, action);
console.groupCollapsed(action.type);
console.log('prev state', state);
console.log('action', action);
console.log('next state', result);
console.groupEnd();
return result;
};
}
export const META_REDUCERS: MetaReducer<State>[] = !environment.production
? [logger]
: [];
export interface State {
router: fromRouter.RouterReducerState;
// layout: AppLayoutStore.State;
// events: AppEventsStore.State;
}
export const AppRouterSelector = AppRouterStore.getSelectors(
(state: State) => state.router,
);
// export const AppLayoutSelector = AppLayoutStore.getSelectors(
// (state: State) => state.layout,
// );
// export const AppEventsSelector = AppEventsStore.getSelectors(
// (state: State) => state.events,
// );

View File

@ -0,0 +1,55 @@
import { Injectable } from '@angular/core';
// import { MatSnackBar, MatDialog } from '@angular/material';
import { Location } from '@angular/common';
import { Router } from '@angular/router';
import { Effect, Actions, ofType } from '@ngrx/effects';
import { map, tap } from 'rxjs/operators';
@Injectable()
export class Effects {
constructor(
private actions$: Actions,
private router: Router,
private location: Location,
// private matSnackBar: MatSnackBar,
// private matDialog: MatDialog,
) { }
// @Effect({ dispatch: false })
// userProfileGotoProfile$ = this.actions$.pipe(
// ofType(UserProfileStore.ActionType.GotoProfile),
// map((action: UserProfileStore.GotoProfile) => action.payload),
// tap((payload: { uid: string }) => {
// this.matDialog.closeAll();
// this.router.navigateByUrl(`/article/${payload.uid}`);
// }),
// );
// @Effect({ dispatch: false })
// userProfileGotoProfileEdit$ = this.actions$.pipe(
// ofType(UserProfileStore.ActionType.GotoProfileEdit),
// tap(() => {
// this.router.navigateByUrl(`/user/edit`);
// }),
// );
// @Effect({ dispatch: false })
// userProfileGotoSettings$ = this.actions$.pipe(
// ofType(UserProfileStore.ActionType.GotoSettings),
// tap(() => {
// this.router.navigateByUrl(`/user/settings`);
// }),
// );
// @Effect({ dispatch: false })
// articleRouterGotoSave$ = this.actions$.pipe(
// ofType(ArticleRouterStore.ActionType.GotoSave),
// map((action: ArticleRouterStore.GotoSave) => action.payload),
// tap((payload: { aid: string }) => {
// this.matDialog.closeAll();
// this.router.navigateByUrl(`/article/write/${payload.aid}`);
// }),
// );
}

View File

@ -0,0 +1,10 @@
import { Selector, createSelector } from '@ngrx/store';
import * as fromRouter from '@ngrx/router-store';
export type State = fromRouter.RouterReducerState;
export function getSelectors<S>(selector: Selector<any, State>) {
return {
selectState: createSelector(selector, (state: State) => state.state),
};
}

View File

@ -0,0 +1,2 @@
export * from './app-router.effect';
export * from './app-router.state';

View File

@ -1,4 +1,5 @@
export const environment = { export const environment = {
production: false, production: false,
hmr : true hmr: true,
apiEntryPoint: 'http://localhost:8088/api',
}; };

View File

@ -1,4 +1,5 @@
export const environment = { export const environment = {
production: true, production: true,
hmr : false hmr: false,
apiEntryPoint: 'http://localhost:8088/api',
}; };

View File

@ -4,7 +4,8 @@
export const environment = { export const environment = {
production: false, production: false,
hmr : false hmr: false,
apiEntryPoint: 'http://localhost:8088/api',
}; };
/* /*

View File

@ -0,0 +1,7 @@
export interface Base {
id?: string;
createDate?: Date;
updateDate?: Date;
}

View File

@ -0,0 +1,10 @@
export interface PageClient {
// content: Client[];
totalPages: number;
totalElements: number;
last: boolean;
size: number;
first: boolean;
sort: string;
numberOfElements: number;
}

View File

@ -0,0 +1,17 @@
import { Base } from '../../common/model/base.model';
export interface User extends Base {
username?: string;
nickname?: string;
email?: string;
block?: boolean;
isAdmin?: boolean;
sendEmail?: boolean;
activation?: string;
lastResetTime?: Date;
resetCount?: number;
otpKey?: string;
otp?: string;
requireReset?: boolean;
}