user refactoring

This commit is contained in:
byung eun park 2019-08-19 16:35:54 +09:00
parent dfd73c445a
commit 5fa9a68295
43 changed files with 563 additions and 220 deletions

View File

@ -1,40 +1,26 @@
import { NgModule, APP_INITIALIZER } from '@angular/core'; import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { UserModule } from './pages/users/user/user.module';
import { AppService } from './service/app.service'; import { CookieService } from 'ngx-cookie-service';
import { API_BASE_URL } from 'src/shared/common/type/injection-token.type';
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({ @NgModule({
imports: [UserModule.forRoot()], imports: [],
exports: [], exports: [],
providers: [ providers: [
AppService, CookieService,
// ...GUARDS,
// CookieService,
// ClipboardService,
{ {
provide: APP_INITIALIZER, provide: HTTP_INTERCEPTORS,
useFactory: initApp, useClass: BasicAuthHtppInterceptorService,
deps: [AppService],
multi: true multi: true
}, },
{ {
provide: API_BASE_URL, provide: API_BASE_URL,
useValue: 'http://localhost:8088/api', useValue: 'http://localhost:8088/api',
multi: true 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 { }

View File

@ -23,7 +23,9 @@ import { appFuseConfig } from './app.fuse';
import { LayoutModule } from './layout/layout.module'; 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'; import { from } from 'rxjs';
@NgModule({ @NgModule({
@ -54,6 +56,9 @@ import { from } from 'rxjs';
LayoutModule, LayoutModule,
AuthModule.forRoot(), AuthModule.forRoot(),
DashboardModule.forRoot(),
UserModule.forRoot(),
], ],
declarations: [AppComponent], declarations: [AppComponent],
providers: [], providers: [],

View File

@ -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<any>, next: HttpHandler) {
if (sessionStorage.getItem('username') && sessionStorage.getItem('token')) {
req = req.clone({
setHeaders: {
Authorization: sessionStorage.getItem('token')
}
});
}
return next.handle(req);
}
}

View File

@ -6,7 +6,7 @@ import { take } from 'rxjs/operators';
import { FuseConfigService } from 'src/@fuse/services/config.service'; import { FuseConfigService } from 'src/@fuse/services/config.service';
import { fuseAnimations } from 'src/@fuse/animations'; 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({ @Component({
selector: 'authentication', selector: 'authentication',
@ -67,7 +67,7 @@ export class AuthenticationComponent implements OnInit {
let userName = this.loginForm.get('username').value; let userName = this.loginForm.get('username').value;
let password = this.loginForm.get('password').value; let password = this.loginForm.get('password').value;
this._authService.login(userName, password) this._authService.authenticate(userName, password)
.pipe(take(1)) .pipe(take(1))
.subscribe( .subscribe(
res => { res => {

View File

@ -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<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

@ -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<T extends Base> {
public constructor(
protected httpClient: HttpClient,
protected apiEntryPoint: string,
) {
}
}

View File

@ -34,30 +34,32 @@
<!-- CONTENT CARD --> <!-- CONTENT CARD -->
<div class="content-card"> <div class="content-card">
<mat-table class="users-table" #table matSort [@animateStagger]="{ value: '50' }" fusePerfectScrollbar> <mat-table class="users-table" #table [dataSource]="dataSource" matSort [@animateStagger]="{ value: '50' }"
fusePerfectScrollbar>
<!-- ID/Nickname Column --> <!-- ID/Nickname Column -->
<ng-container matColumnDef="id"> <ng-container matColumnDef="username">
<mat-header-cell *matHeaderCellDef mat-sort-header>아이디/닉네임</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>아이디/닉네임</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="text-truncate">{{ order.id }}</p> <p class="text-truncate">{{ user.username }}</p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<!-- Phone Column --> <!-- Phone Column -->
<ng-container matColumnDef="phone"> <ng-container matColumnDef="phone">
<mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>연락처</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>연락처</mat-header-cell>
<mat-cell *matCellDef="let order" fxHide fxShow.gt-sm> <mat-cell *matCellDef="let user" fxHide fxShow.gt-sm>
<p class="text-truncate">{{ order.reference }}</p> <!-- <p class="text-truncate">{{ user.phone }}</p> -->
<p class="text-truncate">010-3004-2001</p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
<!-- Status Column --> <!-- Status Column -->
<ng-container matColumnDef="status"> <ng-container matColumnDef="status">
<mat-header-cell *matHeaderCellDef mat-sort-header>상태</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>상태</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="text-truncate"> <p class="text-truncate">
{{ order.customer.firstName }} <!-- {{ user.status }} -->
{{ order.customer.lastName }} 정상
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -65,9 +67,10 @@
<!-- Total Price Column --> <!-- Total Price Column -->
<ng-container matColumnDef="totalPrice"> <ng-container matColumnDef="totalPrice">
<mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-md>보유금</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-md>보유금</mat-header-cell>
<mat-cell *matCellDef="let order" fxHide fxShow.gt-md> <mat-cell *matCellDef="let user" fxHide fxShow.gt-md>
<p class="total-price text-truncate"> <p class="total-price text-truncate">
{{ order.total | currency: 'USD':'symbol' }} <!-- {{ user.totalprice | currency: 'USD':'symbol' }} -->
1,000,000
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -75,9 +78,10 @@
<!-- Point Column --> <!-- Point Column -->
<ng-container matColumnDef="point"> <ng-container matColumnDef="point">
<mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>포인트</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>포인트</mat-header-cell>
<mat-cell *matCellDef="let order" fxHide fxShow.gt-sm> <mat-cell *matCellDef="let user" fxHide fxShow.gt-sm>
<p class="text-truncate"> <p class="text-truncate">
{{ order.payment.method }} <!-- {{ user.point }} -->
5000
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -85,9 +89,11 @@
<!-- Level Column --> <!-- Level Column -->
<ng-container matColumnDef="level"> <ng-container matColumnDef="level">
<mat-header-cell *matHeaderCellDef mat-sort-header>레벨</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>레벨</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <!-- <p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> -->
{{ order.status[0].name }} <p class="text-truncate">
<!-- {{ user.level }} -->
브론즈
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -95,9 +101,10 @@
<!-- Charge Money Column --> <!-- Charge Money Column -->
<ng-container matColumnDef="chargeMoney"> <ng-container matColumnDef="chargeMoney">
<mat-header-cell *matHeaderCellDef mat-sort-header>충전금</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>충전금</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <p class="text-truncate ">
{{ order.status[0].name }} <!-- {{ user.chargeMoney }} -->
1,000,000
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -105,9 +112,10 @@
<!-- Exchange Money Column --> <!-- Exchange Money Column -->
<ng-container matColumnDef="exchangeMoney"> <ng-container matColumnDef="exchangeMoney">
<mat-header-cell *matHeaderCellDef mat-sort-header>환전금</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>환전금</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <p class="text-truncate ">
{{ order.status[0].name }} <!-- {{ user.exchangeMoney }} -->
0
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -115,9 +123,10 @@
<!-- Revenue Money Column --> <!-- Revenue Money Column -->
<ng-container matColumnDef="revenueMoney"> <ng-container matColumnDef="revenueMoney">
<mat-header-cell *matHeaderCellDef mat-sort-header>수익금</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>수익금</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <p class="text-truncate">
{{ order.status[0].name }} <!-- {{ user.revenueMoney }} -->
1,000,000
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -125,9 +134,10 @@
<!-- Number of Bets Column --> <!-- Number of Bets Column -->
<ng-container matColumnDef="numberOfBets"> <ng-container matColumnDef="numberOfBets">
<mat-header-cell *matHeaderCellDef mat-sort-header>배팅건</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>배팅건</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <p class="text-truncate">
{{ order.status[0].name }} <!-- {{ user.betNumberof }} -->
10
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -135,9 +145,10 @@
<!-- Referrals Column --> <!-- Referrals Column -->
<ng-container matColumnDef="referrals"> <ng-container matColumnDef="referrals">
<mat-header-cell *matHeaderCellDef mat-sort-header>추천수</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>추천수</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <p class="text-truncate">
{{ order.status[0].name }} <!-- {{ user.referrals }} -->
10
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -145,9 +156,10 @@
<!-- Recommender Column --> <!-- Recommender Column -->
<ng-container matColumnDef="recommender"> <ng-container matColumnDef="recommender">
<mat-header-cell *matHeaderCellDef mat-sort-header>추천인</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>추천인</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <p class="text-truncate">
{{ order.status[0].name }} <!-- {{ user.recommender }} -->
test
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -155,9 +167,10 @@
<!-- Coupon Status Column --> <!-- Coupon Status Column -->
<ng-container matColumnDef="couponStatus"> <ng-container matColumnDef="couponStatus">
<mat-header-cell *matHeaderCellDef mat-sort-header>쿠폰현황</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>쿠폰현황</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <p class="text-truncate">
{{ order.status[0].name }} <!-- {{ user.coupon }} -->
10
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -165,9 +178,9 @@
<!-- Register Date Column --> <!-- Register Date Column -->
<ng-container matColumnDef="registerDate"> <ng-container matColumnDef="registerDate">
<mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>가입날짜</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>가입날짜</mat-header-cell>
<mat-cell *matCellDef="let order" fxHide fxShow.gt-sm> <mat-cell *matCellDef="let user" fxHide fxShow.gt-sm>
<p class="text-truncate"> <p class="text-truncate">
{{ order.date }} {{ user.createAt }}
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -175,9 +188,9 @@
<!-- Recent Connect Date Column --> <!-- Recent Connect Date Column -->
<ng-container matColumnDef="recentConnectDate"> <ng-container matColumnDef="recentConnectDate">
<mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>최근접속일</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>최근접속일</mat-header-cell>
<mat-cell *matCellDef="let order" fxHide fxShow.gt-sm> <mat-cell *matCellDef="let user" fxHide fxShow.gt-sm>
<p class="text-truncate"> <p class="text-truncate">
{{ order.date }} {{ user.updateAt }}
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>
@ -185,9 +198,9 @@
<!-- Recent Connect IP Column --> <!-- Recent Connect IP Column -->
<ng-container matColumnDef="recentConnectIp"> <ng-container matColumnDef="recentConnectIp">
<mat-header-cell *matHeaderCellDef mat-sort-header>최근접속IP</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>최근접속IP</mat-header-cell>
<mat-cell *matCellDef="let order"> <mat-cell *matCellDef="let user">
<p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color"> <p class="text-truncate">
{{ order.status[0].name }} <!-- {{ user.recentConnectIp }} -->
</p> </p>
</mat-cell> </mat-cell>
</ng-container> </ng-container>

View File

@ -4,7 +4,8 @@ import {
OnDestroy, OnDestroy,
OnInit, OnInit,
ViewChild, ViewChild,
ViewEncapsulation ViewEncapsulation,
AfterViewInit
} from '@angular/core'; } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
@ -17,8 +18,11 @@ 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 { Page } from 'src/modules/common/data/model/page';
import { UserService } from '../../service/user.service'; 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({ @Component({
selector: 'app-user-user-list', selector: 'app-user-user-list',
@ -27,10 +31,11 @@ import { UserService } from '../../service/user.service';
animations: fuseAnimations, animations: fuseAnimations,
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class UserListComponent implements OnInit, OnDestroy { export class UserListComponent implements OnInit, OnDestroy, AfterViewInit {
dataSource: UsersDataSource | null;
displayedColumns = [ displayedColumns = [
'id', 'username',
'phone', 'phone',
'status', 'status',
'totalPrice', 'totalPrice',
@ -48,9 +53,6 @@ export class UserListComponent implements OnInit, OnDestroy {
'recentConnectIp' 'recentConnectIp'
]; ];
total: number;
userList: User[];
@ViewChild(MatPaginator, { static: true }) @ViewChild(MatPaginator, { static: true })
paginator: MatPaginator; paginator: MatPaginator;
@ -82,7 +84,24 @@ export class UserListComponent implements OnInit, OnDestroy {
* On init * On init
*/ */
ngOnInit(): void { 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(); this._unsubscribeAll.complete();
} }
fetchUserList() { ngAfterViewInit(): void { }
this.userService.getAllUsers().pipe(
map((userList: User[]) => {
if (userList && 0 < userList.length) {
console.log(userList);
}
})
).subscribe();
}
} }

View File

@ -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<User> {
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<User[] | readonly User[]> {
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();
}
}

View File

@ -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<User> {
public constructor(httpClient: HttpClient) {
super(httpClient, environment.apiEntryPoint + '/users');
}
public getAllUsers(): Observable<User[]> {
return this.httpClient.get<User[]>(`${this.apiEntryPoint}`);
}
}

View File

@ -26,9 +26,6 @@ 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,
@ -62,19 +59,4 @@ import { SERVICES } from './service';
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

@ -6,7 +6,7 @@ import { map } from 'rxjs/operators';
import { JwtSigninResponse } from '../model/jwt-signin-response.model'; import { JwtSigninResponse } from '../model/jwt-signin-response.model';
import { CookieService } from 'ngx-cookie-service'; 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' }) @Injectable({ providedIn: 'root' })
export class AuthService { export class AuthService {
@ -16,7 +16,7 @@ export class AuthService {
@Inject(API_BASE_URL) private apiBaseUrl: string @Inject(API_BASE_URL) private apiBaseUrl: string
) { } ) { }
public login( public authenticate(
username: string, username: string,
password: string password: string
): Observable<JwtSigninResponse> { ): Observable<JwtSigninResponse> {

View File

@ -1,5 +1,5 @@
import { Action } from '@ngrx/store'; 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 { export enum ActionType {
LoginProcessing = '[account.auth] LoginProcessing', LoginProcessing = '[account.auth] LoginProcessing',

View File

@ -1,5 +1,5 @@
import { Selector, createSelector } from '@ngrx/store'; 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 { export interface State {
processing: boolean; processing: boolean;

View File

@ -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<CommonRootModule> {
return {
ngModule: CommonRootModule,
providers: []
};
}
}

View File

@ -0,0 +1,9 @@
export interface DateAudit {
createdAt: Date;
updatedAt: Date;
}
export interface UserDateAuditEntity extends DateAudit {
createdBy: number;
updatedBy: number;
}

View File

@ -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<T> {
content: T[] | null;
empty: boolean;
first: boolean;
last: boolean;
number: number;
numberOfElements: number;
pageable: Pageable;
size: number;
sort: Sort;
totalElements: number;
totalPages: number;
}

View File

@ -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 {}

View File

@ -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<DashboardRootModule> {
return {
ngModule: DashboardRootModule,
providers: [SERVICES]
};
}
}
@NgModule({
imports: [],
exports: []
})
export class DashboardRootModule {}

View File

@ -0,0 +1,8 @@
export interface Dashboard {
id: number;
title: string;
description: string;
url: string;
sortOrder: number;
display: boolean;
}

View File

@ -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<Dashboard[]> {
return this.httpClient.get<Dashboard[]>(
`${this.apiBaseUrl}/dashboards`,
{}
);
}
public updateDashboardDisplay(
id: number,
display: boolean
): Observable<Dashboard> {
return this.httpClient.put<Dashboard>(
`${this.apiBaseUrl}/dashboards/${id}/display/${display}`,
{}
);
}
public updateDashboardSortOrder(
id: number,
targetSortOrder: number
): Observable<Dashboard> {
return this.httpClient.put<Dashboard>(
`${this.apiBaseUrl}/dashboards/${id}/sort_order/${targetSortOrder}`,
{}
);
}
public deleteDashboard(id: number): Observable<void> {
return this.httpClient.delete<void>(
`${this.apiBaseUrl}/dashboards/${id}`,
{}
);
}
}

View File

@ -0,0 +1,3 @@
import { DashboardService } from './dashboard.service';
export const SERVICES = [DashboardService];

View File

@ -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 }>()
);

View File

@ -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
) {}
}

View File

@ -0,0 +1,4 @@
export * from './action';
export * from './effect';
export * from './reducer';
export * from './state';

View File

@ -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
}))
);

View File

@ -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<S>(selector: Selector<any, State>) {
return {
selectDashboards: createSelector(
selector,
(state: State) => state.dashboards
),
selectCurrentDashboard: createSelector(
selector,
(state: State) => state.currentDashboard
)
};
}

View File

@ -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;
}

View File

@ -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; username?: string;
nickname?: string; nickname?: string;
email?: string; email?: string;

View File

@ -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<Page<User>> {
return this.httpClient.get<Page<User>>(`${this.apiBaseUrl}/users`, {});
}
}

View File

@ -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<UserRootModule> {
return {
ngModule: UserRootModule,
providers: [SERVICES]
};
}
}

View File

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

View File

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

View File

@ -6,7 +6,6 @@
"deprecation": { "deprecation": {
"severity": "warning" "severity": "warning"
}, },
"completed-docs": false,
"component-class-suffix": true, "component-class-suffix": true,
"contextual-lifecycle": true, "contextual-lifecycle": true,
"directive-class-suffix": true, "directive-class-suffix": true,