diff --git a/src/app/app-provider.module.ts b/src/app/app-provider.module.ts index 4b97d17..22b1e82 100644 --- a/src/app/app-provider.module.ts +++ b/src/app/app-provider.module.ts @@ -1,40 +1,26 @@ 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'; -import { API_BASE_URL } from 'src/shared/common/type/injection-token.type'; +import { CookieService } from 'ngx-cookie-service'; + +import { BasicAuthHtppInterceptorService } from './interceptor/basic-auth.http-interceptor'; +import { API_BASE_URL } from 'src/modules/common/type/injection-token.type'; -export function initApp(appService: AppService) { - return () => appService.initApp(); -} @NgModule({ - imports: [UserModule.forRoot()], + imports: [], exports: [], providers: [ - AppService, - // ...GUARDS, - // CookieService, - // ClipboardService, + CookieService, { - provide: APP_INITIALIZER, - useFactory: initApp, - deps: [AppService], + provide: HTTP_INTERCEPTORS, + useClass: BasicAuthHtppInterceptorService, multi: true }, { provide: API_BASE_URL, useValue: 'http://localhost:8088/api', 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 {} +export class AppProviderModule { } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 8ac928f..25c0da8 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -23,7 +23,9 @@ import { appFuseConfig } from './app.fuse'; import { LayoutModule } from './layout/layout.module'; -import { AuthModule } from 'src/shared/auth/auth.module'; +import { AuthModule } from 'src/modules/auth/auth.module'; +import { DashboardModule } from 'src/modules/dashboard/dashboard.module'; +import { UserModule } from 'src/modules/user/user.module'; import { from } from 'rxjs'; @NgModule({ @@ -54,6 +56,9 @@ import { from } from 'rxjs'; LayoutModule, AuthModule.forRoot(), + DashboardModule.forRoot(), + UserModule.forRoot(), + ], declarations: [AppComponent], providers: [], diff --git a/src/app/interceptor/basic-auth.http-interceptor.ts b/src/app/interceptor/basic-auth.http-interceptor.ts new file mode 100644 index 0000000..ead0975 --- /dev/null +++ b/src/app/interceptor/basic-auth.http-interceptor.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; +import { + HttpInterceptor, + HttpRequest, + HttpHandler +} from '@angular/common/http'; + +import { AuthService } from 'src/modules/auth/service/auth.service'; + +@Injectable({ + providedIn: 'root' +}) +export class BasicAuthHtppInterceptorService implements HttpInterceptor { + constructor(private authService: AuthService) {} + + intercept(req: HttpRequest, next: HttpHandler) { + if (sessionStorage.getItem('username') && sessionStorage.getItem('token')) { + req = req.clone({ + setHeaders: { + Authorization: sessionStorage.getItem('token') + } + }); + } + return next.handle(req); + } +} diff --git a/src/app/pages/accounts/component/authentication/authentication.component.ts b/src/app/pages/accounts/component/authentication/authentication.component.ts index 717e67e..bba9669 100644 --- a/src/app/pages/accounts/component/authentication/authentication.component.ts +++ b/src/app/pages/accounts/component/authentication/authentication.component.ts @@ -6,7 +6,7 @@ import { take } from 'rxjs/operators'; import { FuseConfigService } from 'src/@fuse/services/config.service'; import { fuseAnimations } from 'src/@fuse/animations'; -import { AuthService } from 'src/shared/auth/service/auth.service'; +import { AuthService } from 'src/modules/auth/service/auth.service'; @Component({ selector: 'authentication', @@ -67,7 +67,7 @@ export class AuthenticationComponent implements OnInit { let userName = this.loginForm.get('username').value; let password = this.loginForm.get('password').value; - this._authService.login(userName, password) + this._authService.authenticate(userName, password) .pipe(take(1)) .subscribe( res => { diff --git a/src/app/pages/common/util/service/abstract-rest.service.ts b/src/app/pages/common/util/service/abstract-rest.service.ts deleted file mode 100644 index baf568c..0000000 --- a/src/app/pages/common/util/service/abstract-rest.service.ts +++ /dev/null @@ -1,48 +0,0 @@ -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 extends AbstractService { - public constructor(httpClient: HttpClient, apiEntryPoint: string) { - super(httpClient, apiEntryPoint); - } - - public getAll(): Observable { - return this.httpClient.get(this.apiEntryPoint); - } - - public get(id: string | number): Observable { - return this.httpClient.get(this.apiEntryPoint + `/${id}`, httpOptions); - } - - public save(model: T): Observable { - return model.id ? this.update(model) : this.add(model); - } - - public add(model: T): Observable { - return this.httpClient.put( - this.apiEntryPoint, - JSON.stringify(model), - httpOptions - ); - } - - public update(model: T): Observable { - if (!model.id) { - throwError('id of model is not valid'); - } - return this.httpClient.post( - `${this.apiEntryPoint}`, - JSON.stringify(model), - httpOptions - ); - } - - public delete(id: string | number): Observable { - return this.httpClient.delete( - `${this.apiEntryPoint}/${id}`, - httpOptions - ); - } -} diff --git a/src/app/pages/common/util/service/abstract.service.ts b/src/app/pages/common/util/service/abstract.service.ts deleted file mode 100644 index b77d8ff..0000000 --- a/src/app/pages/common/util/service/abstract.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -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 { - - public constructor( - protected httpClient: HttpClient, - protected apiEntryPoint: string, - ) { - - } -} diff --git a/src/app/pages/users/user/component/user-list/user-list.component.html b/src/app/pages/users/user/component/user-list/user-list.component.html index f631a37..359c7e4 100644 --- a/src/app/pages/users/user/component/user-list/user-list.component.html +++ b/src/app/pages/users/user/component/user-list/user-list.component.html @@ -34,30 +34,32 @@
- + - + 아이디/닉네임 - -

{{ order.id }}

+ +

{{ user.username }}

연락처 - -

{{ order.reference }}

+ + +

010-3004-2001

상태 - +

- {{ order.customer.firstName }} - {{ order.customer.lastName }} + + 정상

@@ -65,9 +67,10 @@ 보유금 - +

- {{ order.total | currency: 'USD':'symbol' }} + + 1,000,000

@@ -75,9 +78,10 @@ 포인트 - +

- {{ order.payment.method }} + + 5000

@@ -85,9 +89,11 @@ 레벨 - -

- {{ order.status[0].name }} + + +

+ + 브론즈

@@ -95,9 +101,10 @@ 충전금 - -

- {{ order.status[0].name }} + +

+ + 1,000,000

@@ -105,9 +112,10 @@ 환전금 - -

- {{ order.status[0].name }} + +

+ + 0

@@ -115,9 +123,10 @@ 수익금 - -

- {{ order.status[0].name }} + +

+ + 1,000,000

@@ -125,9 +134,10 @@ 배팅건 - -

- {{ order.status[0].name }} + +

+ + 10

@@ -135,9 +145,10 @@ 추천수 - -

- {{ order.status[0].name }} + +

+ + 10

@@ -145,9 +156,10 @@ 추천인 - -

- {{ order.status[0].name }} + +

+ + test

@@ -155,9 +167,10 @@ 쿠폰현황 - -

- {{ order.status[0].name }} + +

+ + 10

@@ -165,9 +178,9 @@ 가입날짜 - +

- {{ order.date }} + {{ user.createAt }}

@@ -175,9 +188,9 @@ 최근접속일 - +

- {{ order.date }} + {{ user.updateAt }}

@@ -185,9 +198,9 @@ 최근접속IP - -

- {{ order.status[0].name }} + +

+

diff --git a/src/app/pages/users/user/component/user-list/user-list.component.ts b/src/app/pages/users/user/component/user-list/user-list.component.ts index f471e92..eb539d3 100644 --- a/src/app/pages/users/user/component/user-list/user-list.component.ts +++ b/src/app/pages/users/user/component/user-list/user-list.component.ts @@ -4,7 +4,8 @@ import { OnDestroy, OnInit, ViewChild, - ViewEncapsulation + ViewEncapsulation, + AfterViewInit } from '@angular/core'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; @@ -17,8 +18,11 @@ import { FuseUtils } from 'src/@fuse/utils'; import { takeUntil } from 'rxjs/internal/operators'; -import { User } from '../../../../../../shared/user/model/user.model'; -import { UserService } from '../../service/user.service'; +import { Page } from 'src/modules/common/data/model/page'; +import { User } from 'src/modules/user/model/user.model'; +import { UserService } from 'src/modules/user/service/user.service'; +import { UsersDataSource } from './user-list.data-source'; + @Component({ selector: 'app-user-user-list', @@ -27,10 +31,11 @@ import { UserService } from '../../service/user.service'; animations: fuseAnimations, encapsulation: ViewEncapsulation.None }) -export class UserListComponent implements OnInit, OnDestroy { +export class UserListComponent implements OnInit, OnDestroy, AfterViewInit { + dataSource: UsersDataSource | null; displayedColumns = [ - 'id', + 'username', 'phone', 'status', 'totalPrice', @@ -48,9 +53,6 @@ export class UserListComponent implements OnInit, OnDestroy { 'recentConnectIp' ]; - total: number; - userList: User[]; - @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; @@ -82,7 +84,24 @@ export class UserListComponent implements OnInit, OnDestroy { * On init */ ngOnInit(): void { - this.fetchUserList(); + this.dataSource = new UsersDataSource( + this.userService, + this.paginator, + this.sort + ); + + fromEvent(this.filter.nativeElement, 'keyup') + .pipe( + takeUntil(this._unsubscribeAll), + debounceTime(150), + distinctUntilChanged() + ) + .subscribe(() => { + if (!this.dataSource) { + return; + } + this.dataSource.filter = this.filter.nativeElement.value; + }); } /** @@ -94,14 +113,5 @@ export class UserListComponent implements OnInit, OnDestroy { this._unsubscribeAll.complete(); } - fetchUserList() { - this.userService.getAllUsers().pipe( - map((userList: User[]) => { - - if (userList && 0 < userList.length) { - console.log(userList); - } - }) - ).subscribe(); - } + ngAfterViewInit(): void { } } diff --git a/src/app/pages/users/user/component/user-list/user-list.data-source.ts b/src/app/pages/users/user/component/user-list/user-list.data-source.ts new file mode 100644 index 0000000..4f18efc --- /dev/null +++ b/src/app/pages/users/user/component/user-list/user-list.data-source.ts @@ -0,0 +1,62 @@ +import { DataSource } from '@angular/cdk/table'; + +import { BehaviorSubject, Observable, merge } from 'rxjs'; +import { switchMap, map } from 'rxjs/operators'; + +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { CollectionViewer } from '@angular/cdk/collections'; + +import { User } from 'src/modules/user/model/user.model'; +import { UserService } from 'src/modules/user/service/user.service'; + +export class UsersDataSource extends DataSource { + private filterSubject = new BehaviorSubject(''); + + constructor( + private userService: UserService, + private paginator: MatPaginator, + private sort: MatSort + ) { + super(); + } + + // Filter + get filter(): string { + return this.filterSubject.value; + } + + set filter(filter: string) { + this.filterSubject.next(filter); + } + + connect( + collectionViewer: CollectionViewer + ): Observable { + const displayDataChanges = [ + this.paginator.page, + this.sort.sortChange, + this.filterSubject + ]; + + return merge(...displayDataChanges).pipe( + switchMap(() => { + const filter = this.filter; + const sortActive = this.sort.active; + const sortDirection = this.sort.direction; + const pageIndex = this.paginator.pageIndex; + const pageSize = this.paginator.pageSize; + + return this.userService.getAllUsers().pipe( + map(page => { + return page.content; + }) + ); + }) + ); + } + + disconnect(collectionViewer: CollectionViewer): void { + this.filterSubject.complete(); + } +} diff --git a/src/app/pages/users/user/service/user.service.ts b/src/app/pages/users/user/service/user.service.ts deleted file mode 100644 index 390c092..0000000 --- a/src/app/pages/users/user/service/user.service.ts +++ /dev/null @@ -1,18 +0,0 @@ -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 { - - public constructor(httpClient: HttpClient) { - super(httpClient, environment.apiEntryPoint + '/users'); - } - - public getAllUsers(): Observable { - return this.httpClient.get(`${this.apiEntryPoint}`); - } -} diff --git a/src/app/pages/users/user/user.module.ts b/src/app/pages/users/user/user.module.ts index 471f691..ddf59af 100644 --- a/src/app/pages/users/user/user.module.ts +++ b/src/app/pages/users/user/user.module.ts @@ -26,9 +26,6 @@ import { MatStepperModule } from '@angular/material/stepper'; import { adapterFactory } from 'angular-calendar/date-adapters/date-fns'; -import { UserStoreModule } from './user-store.module'; -import { SERVICES } from './service'; - @NgModule({ imports: [ MatButtonModule, @@ -62,19 +59,4 @@ import { SERVICES } from './service'; declarations: [...COMPONENTS], }) -export class UserModule { - public static forRoot(): ModuleWithProviders { - return { - ngModule: UserRootModule, - providers: [...SERVICES] - }; - } -} - -@NgModule({ - imports: [ - UserStoreModule, - ], - exports: [] -}) -export class UserRootModule { } +export class UserModule { } diff --git a/src/shared/auth/auth-store.module.ts b/src/modules/auth/auth-store.module.ts similarity index 100% rename from src/shared/auth/auth-store.module.ts rename to src/modules/auth/auth-store.module.ts diff --git a/src/shared/auth/auth.module.ts b/src/modules/auth/auth.module.ts similarity index 100% rename from src/shared/auth/auth.module.ts rename to src/modules/auth/auth.module.ts diff --git a/src/shared/auth/model/jwt-signin-response.model.ts b/src/modules/auth/model/jwt-signin-response.model.ts similarity index 100% rename from src/shared/auth/model/jwt-signin-response.model.ts rename to src/modules/auth/model/jwt-signin-response.model.ts diff --git a/src/shared/auth/service/auth.service.ts b/src/modules/auth/service/auth.service.ts similarity index 92% rename from src/shared/auth/service/auth.service.ts rename to src/modules/auth/service/auth.service.ts index 2ab56b3..c85f800 100644 --- a/src/shared/auth/service/auth.service.ts +++ b/src/modules/auth/service/auth.service.ts @@ -6,7 +6,7 @@ import { map } from 'rxjs/operators'; import { JwtSigninResponse } from '../model/jwt-signin-response.model'; import { CookieService } from 'ngx-cookie-service'; -import { API_BASE_URL } from 'src/shared/common/type/injection-token.type'; +import { API_BASE_URL } from 'src/modules/common/type/injection-token.type'; @Injectable({ providedIn: 'root' }) export class AuthService { @@ -16,7 +16,7 @@ export class AuthService { @Inject(API_BASE_URL) private apiBaseUrl: string ) { } - public login( + public authenticate( username: string, password: string ): Observable { diff --git a/src/shared/auth/service/index.ts b/src/modules/auth/service/index.ts similarity index 100% rename from src/shared/auth/service/index.ts rename to src/modules/auth/service/index.ts diff --git a/src/shared/auth/store/auth/auth.action.ts b/src/modules/auth/store/auth/auth.action.ts similarity index 94% rename from src/shared/auth/store/auth/auth.action.ts rename to src/modules/auth/store/auth/auth.action.ts index be0aca5..04dedbf 100755 --- a/src/shared/auth/store/auth/auth.action.ts +++ b/src/modules/auth/store/auth/auth.action.ts @@ -1,5 +1,5 @@ import { Action } from '@ngrx/store'; -import { User } from 'src/shared/user/model/user.model'; +import { User } from 'src/modules/user/model/user.model'; export enum ActionType { LoginProcessing = '[account.auth] LoginProcessing', diff --git a/src/shared/auth/store/auth/auth.reducer.ts b/src/modules/auth/store/auth/auth.reducer.ts similarity index 100% rename from src/shared/auth/store/auth/auth.reducer.ts rename to src/modules/auth/store/auth/auth.reducer.ts diff --git a/src/shared/auth/store/auth/auth.state.ts b/src/modules/auth/store/auth/auth.state.ts similarity index 90% rename from src/shared/auth/store/auth/auth.state.ts rename to src/modules/auth/store/auth/auth.state.ts index b156f60..7a3f19a 100755 --- a/src/shared/auth/store/auth/auth.state.ts +++ b/src/modules/auth/store/auth/auth.state.ts @@ -1,5 +1,5 @@ import { Selector, createSelector } from '@ngrx/store'; -import { User } from 'src/shared/user/model/user.model'; +import { User } from 'src/modules/user/model/user.model'; export interface State { processing: boolean; diff --git a/src/shared/auth/store/auth/index.ts b/src/modules/auth/store/auth/index.ts similarity index 100% rename from src/shared/auth/store/auth/index.ts rename to src/modules/auth/store/auth/index.ts diff --git a/src/shared/auth/store/index.ts b/src/modules/auth/store/index.ts similarity index 100% rename from src/shared/auth/store/index.ts rename to src/modules/auth/store/index.ts diff --git a/src/modules/common/common.module.ts b/src/modules/common/common.module.ts new file mode 100644 index 0000000..669af18 --- /dev/null +++ b/src/modules/common/common.module.ts @@ -0,0 +1,22 @@ +import { NgModule, ModuleWithProviders } from '@angular/core'; +import { CommonModule as AngularCommonModule } from '@angular/common'; + +@NgModule({ + imports: [], + exports: [] +}) +export class CommonRootModule {} + +@NgModule({ + declarations: [], + imports: [AngularCommonModule], + exports: [] +}) +export class CommonModule { + public static forRoot(): ModuleWithProviders { + return { + ngModule: CommonRootModule, + providers: [] + }; + } +} diff --git a/src/modules/common/data/model/audit.ts b/src/modules/common/data/model/audit.ts new file mode 100644 index 0000000..44f24ca --- /dev/null +++ b/src/modules/common/data/model/audit.ts @@ -0,0 +1,9 @@ +export interface DateAudit { + createdAt: Date; + updatedAt: Date; +} + +export interface UserDateAuditEntity extends DateAudit { + createdBy: number; + updatedBy: number; +} diff --git a/src/modules/common/data/model/page.ts b/src/modules/common/data/model/page.ts new file mode 100644 index 0000000..e858820 --- /dev/null +++ b/src/modules/common/data/model/page.ts @@ -0,0 +1,27 @@ +export interface Sort { + empty: boolean; + sorted: true; + unsorted: boolean; +} + +export interface Pageable { + offset: number; + pageNumber: number; + pageSize: number; + paged: boolean; + sort: Sort; +} + +export interface Page { + content: T[] | null; + empty: boolean; + first: boolean; + last: boolean; + number: number; + numberOfElements: number; + pageable: Pageable; + size: number; + sort: Sort; + totalElements: number; + totalPages: number; +} diff --git a/src/shared/common/type/injection-token.type.ts b/src/modules/common/type/injection-token.type.ts similarity index 97% rename from src/shared/common/type/injection-token.type.ts rename to src/modules/common/type/injection-token.type.ts index cdc816a..90a29c9 100644 --- a/src/shared/common/type/injection-token.type.ts +++ b/src/modules/common/type/injection-token.type.ts @@ -1,3 +1,3 @@ -import { InjectionToken } from '@angular/core'; - -export const API_BASE_URL = new InjectionToken('API_BASE_URL'); +import { InjectionToken } from '@angular/core'; + +export const API_BASE_URL = new InjectionToken('API_BASE_URL'); diff --git a/src/modules/dashboard/dashboard-store.module.ts b/src/modules/dashboard/dashboard-store.module.ts new file mode 100644 index 0000000..47f9f84 --- /dev/null +++ b/src/modules/dashboard/dashboard-store.module.ts @@ -0,0 +1,13 @@ +import { NgModule, ModuleWithProviders } from '@angular/core'; +import { StoreModule } from '@ngrx/store'; +import { EffectsModule } from '@ngrx/effects'; + +import { reducer, Effects } from './store'; + +@NgModule({ + imports: [ + StoreModule.forFeature('dashboard', reducer), + EffectsModule.forFeature([Effects]) + ] +}) +export class DashboardStoreModule {} diff --git a/src/modules/dashboard/dashboard.module.ts b/src/modules/dashboard/dashboard.module.ts new file mode 100644 index 0000000..e6e098d --- /dev/null +++ b/src/modules/dashboard/dashboard.module.ts @@ -0,0 +1,24 @@ +import { NgModule, ModuleWithProviders } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SERVICES } from './service'; +import { DashboardStoreModule } from './dashboard-store.module'; + +@NgModule({ + declarations: [], + imports: [CommonModule, DashboardStoreModule], + exports: [] +}) +export class DashboardModule { + public static forRoot(): ModuleWithProviders { + return { + ngModule: DashboardRootModule, + providers: [SERVICES] + }; + } +} + +@NgModule({ + imports: [], + exports: [] +}) +export class DashboardRootModule {} diff --git a/src/modules/dashboard/model/Dashboard.ts b/src/modules/dashboard/model/Dashboard.ts new file mode 100644 index 0000000..f083359 --- /dev/null +++ b/src/modules/dashboard/model/Dashboard.ts @@ -0,0 +1,8 @@ +export interface Dashboard { + id: number; + title: string; + description: string; + url: string; + sortOrder: number; + display: boolean; +} diff --git a/src/modules/dashboard/service/dashboard.service.ts b/src/modules/dashboard/service/dashboard.service.ts new file mode 100644 index 0000000..85ce1ba --- /dev/null +++ b/src/modules/dashboard/service/dashboard.service.ts @@ -0,0 +1,50 @@ +import { Injectable, Inject } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; + +import { Observable } from 'rxjs'; +import { Dashboard } from '../model/Dashboard'; +import { API_BASE_URL } from 'src/modules/common/type/injection-token.type'; + +@Injectable({ + providedIn: 'root' +}) +export class DashboardService { + constructor( + @Inject(API_BASE_URL) private apiBaseUrl: string, + private httpClient: HttpClient + ) {} + + public getDashboards(): Observable { + return this.httpClient.get( + `${this.apiBaseUrl}/dashboards`, + {} + ); + } + + public updateDashboardDisplay( + id: number, + display: boolean + ): Observable { + return this.httpClient.put( + `${this.apiBaseUrl}/dashboards/${id}/display/${display}`, + {} + ); + } + + public updateDashboardSortOrder( + id: number, + targetSortOrder: number + ): Observable { + return this.httpClient.put( + `${this.apiBaseUrl}/dashboards/${id}/sort_order/${targetSortOrder}`, + {} + ); + } + + public deleteDashboard(id: number): Observable { + return this.httpClient.delete( + `${this.apiBaseUrl}/dashboards/${id}`, + {} + ); + } +} diff --git a/src/modules/dashboard/service/index.ts b/src/modules/dashboard/service/index.ts new file mode 100644 index 0000000..f363b2d --- /dev/null +++ b/src/modules/dashboard/service/index.ts @@ -0,0 +1,3 @@ +import { DashboardService } from './dashboard.service'; + +export const SERVICES = [DashboardService]; diff --git a/src/modules/dashboard/store/action.ts b/src/modules/dashboard/store/action.ts new file mode 100644 index 0000000..7d4cd9e --- /dev/null +++ b/src/modules/dashboard/store/action.ts @@ -0,0 +1,60 @@ +import { createAction, props } from '@ngrx/store'; + +import { Dashboard } from '../model/Dashboard'; + +export const addDashboard = createAction( + '[Dashboard] Add Dashboard', + props<{ dashboard: Dashboard }>() +); + +export const addDashboardSuccess = createAction( + '[Dashboard] Add Dashboard Success', + props<{ dashboard: Dashboard }>() +); + +export const addDashboardFailure = createAction( + '[Dashboard] Add Dashboard Failure', + props<{ dashboard: Dashboard; error: any }>() +); + +export const loadDashboards = createAction('[Dashboard] Load Dashboards'); + +export const loadDashboardsSuccess = createAction( + '[Dashboard] Load Dashboards Success', + props<{ dashboards: Dashboard[] }>() +); + +export const loadDashboardsFailure = createAction( + '[Dashboard] Load Dashboards Failure', + props<{ error: any }>() +); + +export const modifyDashboard = createAction( + '[Dashboard] Modify Dashboard', + props<{ dashboard: Dashboard }>() +); + +export const modifyDashboardSuccess = createAction( + '[Dashboard] Modify Dashboard Success', + props<{ dashboard: Dashboard }>() +); + +export const modifyDashboardFailure = createAction( + '[Dashboard] Modify Dashboard Failure', + props<{ dashboard: Dashboard; error: any }>() +); + +export const removeDashboard = createAction( + '[Dashboard] Remove Dashboard', + props<{ id: number }>() +); + +export const removeDashboardSuccess = createAction( + '[Dashboard] Remove Dashboard Success', + props<{ id: number }>() +); + +export const removeDashboardFailure = createAction( + '[Dashboard] Remove Dashboard Failure', + props<{ id: number; error: any }>() +); diff --git a/src/modules/dashboard/store/effect.ts b/src/modules/dashboard/store/effect.ts new file mode 100644 index 0000000..67de6bb --- /dev/null +++ b/src/modules/dashboard/store/effect.ts @@ -0,0 +1,52 @@ +import { Injectable } from '@angular/core'; + +import { Actions, ofType, createEffect } from '@ngrx/effects'; + +import { of } from 'rxjs'; +import { map, catchError, switchMap, mergeMap } from 'rxjs/operators'; + +import { + loadDashboards, + loadDashboardsSuccess, + loadDashboardsFailure, + addDashboard, + removeDashboard, + removeDashboardSuccess, + removeDashboardFailure +} from './action'; +import { DashboardService } from '../service/dashboard.service'; +import { Dashboard } from '../model/Dashboard'; + +@Injectable() +export class Effects { + loadDashboards$ = createEffect(() => + this.actions$.pipe( + ofType(loadDashboards), + switchMap(() => + this.dashboardService.getDashboards().pipe( + map((dashboards: Dashboard[]) => + loadDashboardsSuccess({ dashboards }) + ), + catchError(error => of(loadDashboardsFailure({ error }))) + ) + ) + ) + ); + + removeBookFromCollection$ = createEffect(() => + this.actions$.pipe( + ofType(removeDashboard), + mergeMap(({ id }) => + this.dashboardService.deleteDashboard(id).pipe( + map(() => removeDashboardSuccess({ id })), + catchError(error => of(removeDashboardFailure({ id, error }))) + ) + ) + ) + ); + + constructor( + private actions$: Actions, + private dashboardService: DashboardService + ) {} +} diff --git a/src/modules/dashboard/store/index.ts b/src/modules/dashboard/store/index.ts new file mode 100644 index 0000000..58ae3ac --- /dev/null +++ b/src/modules/dashboard/store/index.ts @@ -0,0 +1,4 @@ +export * from './action'; +export * from './effect'; +export * from './reducer'; +export * from './state'; diff --git a/src/modules/dashboard/store/reducer.ts b/src/modules/dashboard/store/reducer.ts new file mode 100644 index 0000000..f023d2f --- /dev/null +++ b/src/modules/dashboard/store/reducer.ts @@ -0,0 +1,11 @@ +import { createReducer, on } from '@ngrx/store'; + +import { State, initialState } from './state'; +import { loadDashboardsSuccess } from './action'; + +export const reducer = createReducer( + initialState, + on(loadDashboardsSuccess, (state, { dashboards }) => ({ + dashboards: dashboards + })) +); diff --git a/src/modules/dashboard/store/state.ts b/src/modules/dashboard/store/state.ts new file mode 100644 index 0000000..f7e719b --- /dev/null +++ b/src/modules/dashboard/store/state.ts @@ -0,0 +1,25 @@ +import { Selector, createSelector } from '@ngrx/store'; +import { Dashboard } from 'src/modules/dashboard/model/Dashboard'; + +export interface State { + dashboards: Dashboard[] | null; + currentDashboard: Dashboard | null; +} + +export const initialState: State = { + dashboards: null, + currentDashboard: null +}; + +export function getSelectors(selector: Selector) { + return { + selectDashboards: createSelector( + selector, + (state: State) => state.dashboards + ), + selectCurrentDashboard: createSelector( + selector, + (state: State) => state.currentDashboard + ) + }; +} diff --git a/src/modules/user/model/role.model.ts b/src/modules/user/model/role.model.ts new file mode 100644 index 0000000..2fdf247 --- /dev/null +++ b/src/modules/user/model/role.model.ts @@ -0,0 +1,10 @@ +export enum RoleName { + ROLE_SUPER_ADMIN = 'ROLE_SUPER_ADMIN', + ROLE_ADMIN = 'ROLE_ADMIN', + ROLE_USER = 'ROLE_USER' +} + +export interface Role { + id: number; + name: RoleName; +} diff --git a/src/shared/user/model/user.model.ts b/src/modules/user/model/user.model.ts similarity index 64% rename from src/shared/user/model/user.model.ts rename to src/modules/user/model/user.model.ts index b62ac77..12c4cb8 100644 --- a/src/shared/user/model/user.model.ts +++ b/src/modules/user/model/user.model.ts @@ -1,6 +1,7 @@ -import { Base } from '../../common/model/base.model'; +import { Role } from './role.model'; +import { DateAudit } from 'src/modules/common/data/model/audit'; -export interface User extends Base { +export interface User extends DateAudit { username?: string; nickname?: string; email?: string; diff --git a/src/app/pages/users/user/service/index.ts b/src/modules/user/service/index.ts similarity index 100% rename from src/app/pages/users/user/service/index.ts rename to src/modules/user/service/index.ts diff --git a/src/modules/user/service/user.service.ts b/src/modules/user/service/user.service.ts new file mode 100644 index 0000000..baa6731 --- /dev/null +++ b/src/modules/user/service/user.service.ts @@ -0,0 +1,19 @@ +import { Injectable, Inject } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { User } from 'src/modules/user/model/user.model'; +import { API_BASE_URL } from 'src/modules/common/type/injection-token.type'; +import { Page } from 'src/modules/common/data/model/page'; + +@Injectable() +export class UserService { + + constructor( + @Inject(API_BASE_URL) private apiBaseUrl: string, + private httpClient: HttpClient + ) { } + + public getAllUsers(): Observable> { + return this.httpClient.get>(`${this.apiBaseUrl}/users`, {}); + } +} diff --git a/src/modules/user/user.module.ts b/src/modules/user/user.module.ts new file mode 100644 index 0000000..185d18e --- /dev/null +++ b/src/modules/user/user.module.ts @@ -0,0 +1,23 @@ +import { NgModule, ModuleWithProviders } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SERVICES } from './service'; + +@NgModule({ + imports: [], + exports: [] +}) +export class UserRootModule { } + +@NgModule({ + declarations: [], + imports: [CommonModule], + exports: [] +}) +export class UserModule { + public static forRoot(): ModuleWithProviders { + return { + ngModule: UserRootModule, + providers: [SERVICES] + }; + } +} diff --git a/src/shared/common/model/base.model.ts b/src/shared/common/model/base.model.ts deleted file mode 100644 index a01889b..0000000 --- a/src/shared/common/model/base.model.ts +++ /dev/null @@ -1,7 +0,0 @@ - -export interface Base { - id?: string; - - createDate?: Date; - updateDate?: Date; -} diff --git a/src/shared/common/model/page-client.model.ts b/src/shared/common/model/page-client.model.ts deleted file mode 100644 index aea77d6..0000000 --- a/src/shared/common/model/page-client.model.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface PageClient { - // content: Client[]; - totalPages: number; - totalElements: number; - last: boolean; - size: number; - first: boolean; - sort: string; - numberOfElements: number; -} diff --git a/tslint.json b/tslint.json index f4ae1d1..f0adae9 100644 --- a/tslint.json +++ b/tslint.json @@ -6,7 +6,6 @@ "deprecation": { "severity": "warning" }, - "completed-docs": false, "component-class-suffix": true, "contextual-lifecycle": true, "directive-class-suffix": true,