From 0de2b258b840dcecf18b054b5fe6470920c9eac7 Mon Sep 17 00:00:00 2001 From: JUNG YI DAM Date: Thu, 14 Jul 2022 05:04:54 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20page=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.routing.ts | 7 + .../apps/report/sessionin-info/api.ts | 223 +++++++++++ .../apps/report/sessionin-info/data.ts | 33 ++ src/app/mock-api/common/navigation/data.ts | 7 + src/app/mock-api/index.ts | 2 + .../report/sessionin-info/components/index.ts | 3 + .../components/list.component.html | 359 ++++++++++++++++++ .../components/list.component.ts | 198 ++++++++++ .../models/sessionin-info-pagination.ts | 8 + .../sessionin-info/models/sessionin-info.ts | 29 ++ .../resolvers/sessionin-info.resolver.ts | 89 +++++ .../services/sessionin-info.service.ts | 161 ++++++++ .../sessionin-info/sessionin-info.module.ts | 50 +++ .../sessionin-info/sessionin-info.routing.ts | 24 ++ src/assets/i18n/en.json | 1 + src/assets/i18n/ko.json | 1 + 16 files changed, 1195 insertions(+) create mode 100644 src/app/mock-api/apps/report/sessionin-info/api.ts create mode 100644 src/app/mock-api/apps/report/sessionin-info/data.ts create mode 100644 src/app/modules/admin/report/sessionin-info/components/index.ts create mode 100644 src/app/modules/admin/report/sessionin-info/components/list.component.html create mode 100644 src/app/modules/admin/report/sessionin-info/components/list.component.ts create mode 100644 src/app/modules/admin/report/sessionin-info/models/sessionin-info-pagination.ts create mode 100644 src/app/modules/admin/report/sessionin-info/models/sessionin-info.ts create mode 100644 src/app/modules/admin/report/sessionin-info/resolvers/sessionin-info.resolver.ts create mode 100644 src/app/modules/admin/report/sessionin-info/services/sessionin-info.service.ts create mode 100644 src/app/modules/admin/report/sessionin-info/sessionin-info.module.ts create mode 100644 src/app/modules/admin/report/sessionin-info/sessionin-info.routing.ts diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts index acc85f9..799d828 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routing.ts @@ -373,6 +373,13 @@ export const appRoutes: Route[] = [ 'app/modules/admin/report/payment-log/payment-log.module' ).then((m: any) => m.PaymentLogModule), }, + { + path: 'sessionin-info', + loadChildren: () => + import( + 'app/modules/admin/report/sessionin-info/sessionin-info.module' + ).then((m: any) => m.SessioninInfoModule), + }, { path: 'excel-log', loadChildren: () => diff --git a/src/app/mock-api/apps/report/sessionin-info/api.ts b/src/app/mock-api/apps/report/sessionin-info/api.ts new file mode 100644 index 0000000..2ab2c9f --- /dev/null +++ b/src/app/mock-api/apps/report/sessionin-info/api.ts @@ -0,0 +1,223 @@ +import { Injectable } from '@angular/core'; +import { assign, cloneDeep } from 'lodash-es'; +import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api'; +import { sessioninInfos as sessioninInfosData } from './data'; + +@Injectable({ + providedIn: 'root', +}) +export class ReportSessioninInfoMockApi { + private _sessioninInfos: any[] = sessioninInfosData; + + /** + * Constructor + */ + constructor(private _fuseMockApiService: FuseMockApiService) { + // Register Mock API handlers + this.registerHandlers(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Register Mock API handlers + */ + registerHandlers(): void { + // ----------------------------------------------------------------------------------------------------- + // @ SessioninInfos - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/report/sessionin-info/sessionin-infos', 300) + .reply(({ request }) => { + // Get available queries + const search = request.params.get('search'); + const sort = request.params.get('sort') || 'name'; + const order = request.params.get('order') || 'asc'; + const page = parseInt(request.params.get('page') ?? '1', 10); + const size = parseInt(request.params.get('size') ?? '10', 10); + + // Clone the sessioninInfos + let sessioninInfos: any[] | null = cloneDeep(this._sessioninInfos); + + // Sort the sessioninInfos + if (sort === 'sku' || sort === 'name' || sort === 'active') { + sessioninInfos.sort((a, b) => { + const fieldA = a[sort].toString().toUpperCase(); + const fieldB = b[sort].toString().toUpperCase(); + return order === 'asc' + ? fieldA.localeCompare(fieldB) + : fieldB.localeCompare(fieldA); + }); + } else { + sessioninInfos.sort((a, b) => + order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort] + ); + } + + // If search exists... + if (search) { + // Filter the sessioninInfos + sessioninInfos = sessioninInfos.filter( + (contact: any) => + contact.name && + contact.name.toLowerCase().includes(search.toLowerCase()) + ); + } + + // Paginate - Start + const sessioninInfosLength = sessioninInfos.length; + + // Calculate pagination details + const begin = page * size; + const end = Math.min(size * (page + 1), sessioninInfosLength); + const lastPage = Math.max(Math.ceil(sessioninInfosLength / size), 1); + + // Prepare the pagination object + let pagination = {}; + + // If the requested page number is bigger than + // the last possible page number, return null for + // sessioninInfos but also send the last possible page so + // the app can navigate to there + if (page > lastPage) { + sessioninInfos = null; + pagination = { + lastPage, + }; + } else { + // Paginate the results by size + sessioninInfos = sessioninInfos.slice(begin, end); + + // Prepare the pagination mock-api + pagination = { + length: sessioninInfosLength, + size: size, + page: page, + lastPage: lastPage, + startIndex: begin, + endIndex: end - 1, + }; + } + + // Return the response + return [ + 200, + { + sessioninInfos, + pagination, + }, + ]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninInfo - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/report/sessionin-info/sessionin-info') + .reply(({ request }) => { + // Get the id from the params + const id = request.params.get('id'); + + // Clone the sessioninInfos + const sessioninInfos = cloneDeep(this._sessioninInfos); + + // Find the sessioninInfo + const sessioninInfo = sessioninInfos.find( + (item: any) => item.id === id + ); + + // Return the response + return [200, sessioninInfo]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninInfo - POST + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPost('api/apps/report/sessionin-info/sessionin-info') + .reply(() => { + // Generate a new sessioninInfo + const newSessioninInfo = { + id: FuseMockApiUtils.guid(), + category: '', + name: 'A New User', + description: '', + tags: [], + sku: '', + barcode: '', + brand: '', + vendor: '', + stock: '', + reserved: '', + cost: '', + basePrice: '', + taxPercent: '', + price: '', + weight: '', + thumbnail: '', + images: [], + active: false, + }; + + // Unshift the new sessioninInfo + this._sessioninInfos.unshift(newSessioninInfo); + + // Return the response + return [200, newSessioninInfo]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninInfo - PATCH + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPatch('api/apps/report/sessionin-info/sessionin-info') + .reply(({ request }) => { + // Get the id and sessioninInfo + const id = request.body.id; + const sessioninInfo = cloneDeep(request.body.sessioninInfo); + + // Prepare the updated sessioninInfo + let updatedSessioninInfo = null; + + // Find the sessioninInfo and update it + this._sessioninInfos.forEach((item, index, sessioninInfos) => { + if (item.id === id) { + // Update the sessioninInfo + sessioninInfos[index] = assign( + {}, + sessioninInfos[index], + sessioninInfo + ); + + // Store the updated sessioninInfo + updatedSessioninInfo = sessioninInfos[index]; + } + }); + + // Return the response + return [200, updatedSessioninInfo]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninInfo - DELETE + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onDelete('api/apps/report/sessionin-info/sessionin-info') + .reply(({ request }) => { + // Get the id + const id = request.params.get('id'); + + // Find the sessioninInfo and delete it + this._sessioninInfos.forEach((item, index) => { + if (item.id === id) { + this._sessioninInfos.splice(index, 1); + } + }); + + // Return the response + return [200, true]; + }); + } +} diff --git a/src/app/mock-api/apps/report/sessionin-info/data.ts b/src/app/mock-api/apps/report/sessionin-info/data.ts new file mode 100644 index 0000000..fb47140 --- /dev/null +++ b/src/app/mock-api/apps/report/sessionin-info/data.ts @@ -0,0 +1,33 @@ +/* eslint-disable */ + +export const sessioninInfos = [ + { + id: 'on00', + totalPartnerCount: '5', + totalHoldingMoney: 303675, + totalComp: 108933, + total: 412608, + branchCount: 1, + divisionCount: 1, + officeCount: 1, + storeCount: 1, + memberCount: 1, + nickname: 'on00', + accountHolder: '11', + phoneNumber: '010-1111-1111', + calculateType: '롤링', + ownCash: 50000, + ownComp: 1711, + ownCoupon: 50000, + gameMoney: 0, + todayComp: 0, + totalDeposit: 0, + totalWithdraw: 0, + balance: 0, + registDate: '2022-06-12 15:38', + finalSigninDate: '', + ip: '', + state: '정상', + note: '', + }, +]; diff --git a/src/app/mock-api/common/navigation/data.ts b/src/app/mock-api/common/navigation/data.ts index cee6ba1..e7c2579 100644 --- a/src/app/mock-api/common/navigation/data.ts +++ b/src/app/mock-api/common/navigation/data.ts @@ -285,6 +285,13 @@ export const defaultNavigation: FuseNavigationItem[] = [ icon: 'heroicons_outline:academic-cap', link: '/report/payment-log', }, + { + id: 'report.sessionin-info', + title: 'Sessionin Info', + type: 'basic', + icon: 'heroicons_outline:academic-cap', + link: '/report/sessionin-info', + }, { id: 'report.excel-log', title: 'Excel Log', diff --git a/src/app/mock-api/index.ts b/src/app/mock-api/index.ts index 286c89b..dee7e87 100644 --- a/src/app/mock-api/index.ts +++ b/src/app/mock-api/index.ts @@ -50,6 +50,7 @@ import { ReportMoneyLogMockApi } from './apps/report/money-log/api'; import { ReportCompLogMockApi } from './apps/report/comp-log/api'; import { ReportModificationLogMockApi } from './apps/report/modification-log/api'; import { ReportPaymentLogMockApi } from './apps/report/payment-log/api'; +import { ReportSessioninInfoMockApi } from './apps/report/sessionin-info/api'; import { ReportExcelLogMockApi } from './apps/report/excel-log/api'; import { ReportLoosingMockApi } from './apps/report/loosing/api'; @@ -106,6 +107,7 @@ export const mockApiServices = [ ReportCompLogMockApi, ReportModificationLogMockApi, ReportPaymentLogMockApi, + ReportSessioninInfoMockApi, ReportExcelLogMockApi, ReportLoosingMockApi, ]; diff --git a/src/app/modules/admin/report/sessionin-info/components/index.ts b/src/app/modules/admin/report/sessionin-info/components/index.ts new file mode 100644 index 0000000..04759eb --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/components/index.ts @@ -0,0 +1,3 @@ +import { ListComponent } from './list.component'; + +export const COMPONENTS = [ListComponent]; diff --git a/src/app/modules/admin/report/sessionin-info/components/list.component.html b/src/app/modules/admin/report/sessionin-info/components/list.component.html new file mode 100644 index 0000000..c4426db --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/components/list.component.html @@ -0,0 +1,359 @@ +
+ +
+ +
+ +
+ +
로그인정보
+ +
+ + + + + + + 40 + 60 + 80 + 100 + + + + + LV.1 + LV.2 + LV.3 + LV.4 + + + + + 정상 + 대기 + 탈퇴 + 휴면 + 블랙 + 정지 + + + + + 카지노제한 + 슬롯제한 + + + + + 계좌입금 + + + + + 카지노콤프 + 슬롯콤프 + 배팅콤프 + 첫충콤프 + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+
+ + +
+ There are no sessionin infos! +
+
+
+
+
diff --git a/src/app/modules/admin/report/sessionin-info/components/list.component.ts b/src/app/modules/admin/report/sessionin-info/components/list.component.ts new file mode 100644 index 0000000..4b4462e --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/components/list.component.ts @@ -0,0 +1,198 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild, + ViewEncapsulation, +} from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { + debounceTime, + map, + merge, + Observable, + Subject, + switchMap, + takeUntil, +} from 'rxjs'; +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfirmationService } from '@fuse/services/confirmation'; + +import { User } from '../../../member/user/models/user'; +import { SessioninInfo } from '../models/sessionin-info'; +import { SessioninInfoPagination } from '../models/sessionin-info-pagination'; +import { SessioninInfoService } from '../services/sessionin-info.service'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'sessionin-info-list', + templateUrl: './list.component.html', + styles: [ + /* language=SCSS */ + ` + .inventory-grid { + grid-template-columns: 60px auto 40px; + + @screen sm { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px; + } + + @screen md { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px 60px; + } + + @screen lg { + grid-template-columns: 60px 70px 70px 70px 70px 100px 60px 60px auto 60px 60px 60px 60px; + } + } + `, + ], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: fuseAnimations, +}) +export class ListComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild(MatPaginator) private _paginator!: MatPaginator; + @ViewChild(MatSort) private _sort!: MatSort; + + sessioninInfos$!: Observable; + users$!: Observable; + + isLoading = false; + searchInputControl = new FormControl(); + selectedSessioninInfo?: SessioninInfo; + pagination?: SessioninInfoPagination; + + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseConfirmationService: FuseConfirmationService, + private _formBuilder: FormBuilder, + private _sessioninInfoService: SessioninInfoService, + private router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { + // Get the pagination + this._sessioninInfoService.pagination$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((pagination: SessioninInfoPagination | undefined) => { + // Update the pagination + this.pagination = pagination; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Get the products + this.sessioninInfos$ = this._sessioninInfoService.sessioninInfos$; + } + + /** + * After view init + */ + ngAfterViewInit(): void { + if (this._sort && this._paginator) { + // Set the initial sort + this._sort.sort({ + id: 'name', + start: 'asc', + disableClear: true, + }); + + // Mark for check + this._changeDetectorRef.markForCheck(); + + // If the sessioninInfo changes the sort order... + this._sort.sortChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + // Reset back to the first page + this._paginator.pageIndex = 0; + }); + + // Get products if sort or page changes + merge(this._sort.sortChange, this._paginator.page) + .pipe( + switchMap(() => { + this.isLoading = true; + return this._sessioninInfoService.getSessioninInfos( + this._paginator.pageIndex, + this._paginator.pageSize, + this._sort.active, + this._sort.direction + ); + }), + map(() => { + this.isLoading = false; + }) + ) + .subscribe(); + } + } + + /** + * On destroy + */ + ngOnDestroy(): void { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(null); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + viewUserDetail(id: string): void { + let url: string = 'member/user/' + id; + this.router.navigateByUrl(url); + } + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create product + */ + __createProduct(): void {} + + /** + * Toggle product details + * + * @param productId + */ + __toggleDetails(productId: string): void {} + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + __trackByFn(index: number, item: any): any { + return item.id || index; + } +} diff --git a/src/app/modules/admin/report/sessionin-info/models/sessionin-info-pagination.ts b/src/app/modules/admin/report/sessionin-info/models/sessionin-info-pagination.ts new file mode 100644 index 0000000..67dcc9c --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/models/sessionin-info-pagination.ts @@ -0,0 +1,8 @@ +export interface SessioninInfoPagination { + length: number; + size: number; + page: number; + lastPage: number; + startIndex: number; + endIndex: number; +} diff --git a/src/app/modules/admin/report/sessionin-info/models/sessionin-info.ts b/src/app/modules/admin/report/sessionin-info/models/sessionin-info.ts new file mode 100644 index 0000000..cc39dd9 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/models/sessionin-info.ts @@ -0,0 +1,29 @@ +export interface SessioninInfo { + id?: string; + totalPartnerCount?: number; + totalHoldingMoney?: number; + totalComp?: number; + total?: number; + branchCount?: number; + divisionCount?: number; + officeCount?: number; + storeCount?: number; + memberCount?: number; + nickname?: string; + accountHolder?: string; + phoneNumber?: string; + calculateType?: string; + ownCash?: number; + ownComp?: number; + ownCoupon?: number; + gameMoney?: number; + todayComp?: number; + totalDeposit?: number; + totalWithdraw?: number; + balance?: number; + registDate?: string; + finalSigninDate?: string; + ip?: string; + state?: string; + note?: string; +} diff --git a/src/app/modules/admin/report/sessionin-info/resolvers/sessionin-info.resolver.ts b/src/app/modules/admin/report/sessionin-info/resolvers/sessionin-info.resolver.ts new file mode 100644 index 0000000..5ec1abe --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/resolvers/sessionin-info.resolver.ts @@ -0,0 +1,89 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + Resolve, + Router, + RouterStateSnapshot, +} from '@angular/router'; +import { catchError, Observable, throwError } from 'rxjs'; + +import { SessioninInfo } from '../models/sessionin-info'; +import { SessioninInfoPagination } from '../models/sessionin-info-pagination'; +import { SessioninInfoService } from '../services/sessionin-info.service'; + +@Injectable({ + providedIn: 'root', +}) +export class SessioninInfoResolver implements Resolve { + /** + * Constructor + */ + constructor( + private _sessioninInfoService: SessioninInfoService, + private _router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable { + return this._sessioninInfoService + .getSessioninInfoById(route.paramMap.get('id')) + .pipe( + // Error here means the requested product is not available + catchError((error) => { + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} + +@Injectable({ + providedIn: 'root', +}) +export class SessioninInfosResolver implements Resolve { + /** + * Constructor + */ + constructor(private _sessioninInfoService: SessioninInfoService) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable<{ + pagination: SessioninInfoPagination; + sessioninInfos: SessioninInfo[]; + }> { + return this._sessioninInfoService.getSessioninInfos(); + } +} diff --git a/src/app/modules/admin/report/sessionin-info/services/sessionin-info.service.ts b/src/app/modules/admin/report/sessionin-info/services/sessionin-info.service.ts new file mode 100644 index 0000000..8f8d06b --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/services/sessionin-info.service.ts @@ -0,0 +1,161 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { + BehaviorSubject, + filter, + map, + Observable, + of, + switchMap, + take, + tap, + throwError, +} from 'rxjs'; + +import { SessioninInfo } from '../models/sessionin-info'; +import { SessioninInfoPagination } from '../models/sessionin-info-pagination'; + +@Injectable({ + providedIn: 'root', +}) +export class SessioninInfoService { + // Private + private __pagination = new BehaviorSubject< + SessioninInfoPagination | undefined + >(undefined); + private __sessioninInfo = new BehaviorSubject( + undefined + ); + private __sessioninInfos = new BehaviorSubject( + undefined + ); + + /** + * Constructor + */ + constructor(private _httpClient: HttpClient) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Getter for pagination + */ + get pagination$(): Observable { + return this.__pagination.asObservable(); + } + + /** + * Getter for sessioninInfo + */ + get sessioninInfo$(): Observable { + return this.__sessioninInfo.asObservable(); + } + + /** + * Getter for sessioninInfos + */ + get sessioninInfos$(): Observable { + return this.__sessioninInfos.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get SessioninInfos + * + * + * @param page + * @param size + * @param sort + * @param order + * @param search + */ + getSessioninInfos( + page: number = 0, + size: number = 10, + sort: string = 'name', + order: 'asc' | 'desc' | '' = 'asc', + search: string = '' + ): Observable<{ + pagination: SessioninInfoPagination; + sessioninInfos: SessioninInfo[]; + }> { + return this._httpClient + .get<{ + pagination: SessioninInfoPagination; + sessioninInfos: SessioninInfo[]; + }>('api/apps/report/sessionin-info/sessionin-infos', { + params: { + page: '' + page, + size: '' + size, + sort, + order, + search, + }, + }) + .pipe( + tap((response) => { + this.__pagination.next(response.pagination); + this.__sessioninInfos.next(response.sessioninInfos); + }) + ); + } + + /** + * Get product by id + */ + getSessioninInfoById(id: string | null): Observable { + return this.__sessioninInfos.pipe( + take(1), + map((sessioninInfos) => { + // Find the product + const sessioninInfo = + sessioninInfos?.find((item) => item.id === id) || undefined; + + // Update the product + this.__sessioninInfo.next(sessioninInfo); + + // Return the product + return sessioninInfo; + }), + switchMap((product) => { + if (!product) { + return throwError('Could not found product with id of ' + id + '!'); + } + + return of(product); + }) + ); + } + + /** + * Create product + */ + createSessioninInfo(): Observable { + return this.sessioninInfos$.pipe( + take(1), + switchMap((sessioninInfos) => + this._httpClient + .post('api/apps/report/sessionin-info/product', {}) + .pipe( + map((newSessioninInfo) => { + // Update the sessioninInfos with the new product + if (!!sessioninInfos) { + this.__sessioninInfos.next([ + newSessioninInfo, + ...sessioninInfos, + ]); + } + + // Return the new product + return newSessioninInfo; + }) + ) + ) + ); + } +} diff --git a/src/app/modules/admin/report/sessionin-info/sessionin-info.module.ts b/src/app/modules/admin/report/sessionin-info/sessionin-info.module.ts new file mode 100644 index 0000000..1a86656 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/sessionin-info.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +import { MatSortModule } from '@angular/material/sort'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + +import { TranslocoModule } from '@ngneat/transloco'; + +import { SharedModule } from 'app/shared/shared.module'; + +import { COMPONENTS } from './components'; + +import { sessioninInfoRoutes } from './sessionin-info.routing'; + +@NgModule({ + declarations: [COMPONENTS], + imports: [ + TranslocoModule, + SharedModule, + RouterModule.forChild(sessioninInfoRoutes), + + MatButtonModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatPaginatorModule, + MatProgressBarModule, + MatRippleModule, + MatSortModule, + MatSelectModule, + MatTooltipModule, + MatGridListModule, + MatSlideToggleModule, + MatRadioModule, + MatCheckboxModule, + ], +}) +export class SessioninInfoModule {} diff --git a/src/app/modules/admin/report/sessionin-info/sessionin-info.routing.ts b/src/app/modules/admin/report/sessionin-info/sessionin-info.routing.ts new file mode 100644 index 0000000..555012e --- /dev/null +++ b/src/app/modules/admin/report/sessionin-info/sessionin-info.routing.ts @@ -0,0 +1,24 @@ +import { Route } from '@angular/router'; + +import { ListComponent } from './components/list.component'; +import { ViewComponent } from '../../member/user/components/view.component'; + +import { SessioninInfosResolver } from './resolvers/sessionin-info.resolver'; +import { UserResolver } from '../../member/user/resolvers/user.resolver'; + +export const sessioninInfoRoutes: Route[] = [ + { + path: '', + component: ListComponent, + resolve: { + sessioninInfos: SessioninInfosResolver, + }, + }, + { + path: ':id', + component: ViewComponent, + resolve: { + users: UserResolver, + }, + }, +]; diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 818b75b..e12b49d 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -33,6 +33,7 @@ "Comp Log": "Comp Logs", "Modification Log": "Member Modification Logs", "Payment Log": "Manual Payment Logs", + "Sessionin Info": "Sessionin Info", "Excel Log": "Excel Download Logs", "Loosing": "Loosing Management" } diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json index 89d0e4a..63cba82 100644 --- a/src/assets/i18n/ko.json +++ b/src/assets/i18n/ko.json @@ -34,6 +34,7 @@ "Comp Log": "콤프사용 Logs", "Modification Log": "회원수정 로그", "Payment Log": "수동지급/회수 로그", + "Sessionin Info": "로그인정보", "Excel Log": "엑셀다운 로그", "Loosing": "루징관리" } From e2a7a45e767b145274eb1ff05d744a48568debf5 Mon Sep 17 00:00:00 2001 From: JUNG YI DAM Date: Thu, 14 Jul 2022 05:25:53 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=EC=A4=91=EB=B3=B5=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20page=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.routing.ts | 7 + .../apps/report/sessionin-overlap/api.ts | 225 +++++++++++ .../apps/report/sessionin-overlap/data.ts | 33 ++ src/app/mock-api/common/navigation/data.ts | 7 + src/app/mock-api/index.ts | 2 + .../sessionin-overlap/components/index.ts | 3 + .../components/list.component.html | 363 ++++++++++++++++++ .../components/list.component.ts | 198 ++++++++++ .../models/sessionin-Overlap-pagination.ts | 8 + .../models/sessionin-overlap.ts | 29 ++ .../resolvers/sessionin-overlap.resolver.ts | 89 +++++ .../services/sessionin-overlap.service.ts | 164 ++++++++ .../sessionin-overlap.module.ts | 50 +++ .../sessionin-overlap.routing.ts | 24 ++ src/assets/i18n/en.json | 1 + src/assets/i18n/ko.json | 1 + 16 files changed, 1204 insertions(+) create mode 100644 src/app/mock-api/apps/report/sessionin-overlap/api.ts create mode 100644 src/app/mock-api/apps/report/sessionin-overlap/data.ts create mode 100644 src/app/modules/admin/report/sessionin-overlap/components/index.ts create mode 100644 src/app/modules/admin/report/sessionin-overlap/components/list.component.html create mode 100644 src/app/modules/admin/report/sessionin-overlap/components/list.component.ts create mode 100644 src/app/modules/admin/report/sessionin-overlap/models/sessionin-Overlap-pagination.ts create mode 100644 src/app/modules/admin/report/sessionin-overlap/models/sessionin-overlap.ts create mode 100644 src/app/modules/admin/report/sessionin-overlap/resolvers/sessionin-overlap.resolver.ts create mode 100644 src/app/modules/admin/report/sessionin-overlap/services/sessionin-overlap.service.ts create mode 100644 src/app/modules/admin/report/sessionin-overlap/sessionin-overlap.module.ts create mode 100644 src/app/modules/admin/report/sessionin-overlap/sessionin-overlap.routing.ts diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts index 799d828..2ac9414 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routing.ts @@ -380,6 +380,13 @@ export const appRoutes: Route[] = [ 'app/modules/admin/report/sessionin-info/sessionin-info.module' ).then((m: any) => m.SessioninInfoModule), }, + { + path: 'sessionin-overlap', + loadChildren: () => + import( + 'app/modules/admin/report/sessionin-overlap/sessionin-overlap.module' + ).then((m: any) => m.SessioninOverlapModule), + }, { path: 'excel-log', loadChildren: () => diff --git a/src/app/mock-api/apps/report/sessionin-overlap/api.ts b/src/app/mock-api/apps/report/sessionin-overlap/api.ts new file mode 100644 index 0000000..b7b73f0 --- /dev/null +++ b/src/app/mock-api/apps/report/sessionin-overlap/api.ts @@ -0,0 +1,225 @@ +import { Injectable } from '@angular/core'; +import { assign, cloneDeep } from 'lodash-es'; +import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api'; +import { sessioninOverlaps as sessioninOverlapsData } from './data'; + +@Injectable({ + providedIn: 'root', +}) +export class ReportSessioninOverlapMockApi { + private _sessioninOverlaps: any[] = sessioninOverlapsData; + + /** + * Constructor + */ + constructor(private _fuseMockApiService: FuseMockApiService) { + // Register Mock API handlers + this.registerHandlers(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Register Mock API handlers + */ + registerHandlers(): void { + // ----------------------------------------------------------------------------------------------------- + // @ SessioninOverlaps - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/report/sessionin-overlap/sessionin-overlaps', 300) + .reply(({ request }) => { + // Get available queries + const search = request.params.get('search'); + const sort = request.params.get('sort') || 'name'; + const order = request.params.get('order') || 'asc'; + const page = parseInt(request.params.get('page') ?? '1', 10); + const size = parseInt(request.params.get('size') ?? '10', 10); + + // Clone the sessioninoverlaps + let sessioninOverlaps: any[] | null = cloneDeep( + this._sessioninOverlaps + ); + + // Sort the sessioninOverlaps + if (sort === 'sku' || sort === 'name' || sort === 'active') { + sessioninOverlaps.sort((a, b) => { + const fieldA = a[sort].toString().toUpperCase(); + const fieldB = b[sort].toString().toUpperCase(); + return order === 'asc' + ? fieldA.localeCompare(fieldB) + : fieldB.localeCompare(fieldA); + }); + } else { + sessioninOverlaps.sort((a, b) => + order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort] + ); + } + + // If search exists... + if (search) { + // Filter the sessioninOverlaps + sessioninOverlaps = sessioninOverlaps.filter( + (contact: any) => + contact.name && + contact.name.toLowerCase().includes(search.toLowerCase()) + ); + } + + // Paginate - Start + const sessioninOverlapsLength = sessioninOverlaps.length; + + // Calculate pagination details + const begin = page * size; + const end = Math.min(size * (page + 1), sessioninOverlapsLength); + const lastPage = Math.max(Math.ceil(sessioninOverlapsLength / size), 1); + + // Prepare the pagination object + let pagination = {}; + + // If the requested page number is bigger than + // the last possible page number, return null for + // sessioninOverlaps but also send the last possible page so + // the app can navigate to there + if (page > lastPage) { + sessioninOverlaps = null; + pagination = { + lastPage, + }; + } else { + // Paginate the results by size + sessioninOverlaps = sessioninOverlaps.slice(begin, end); + + // Prepare the pagination mock-api + pagination = { + length: sessioninOverlapsLength, + size: size, + page: page, + lastPage: lastPage, + startIndex: begin, + endIndex: end - 1, + }; + } + + // Return the response + return [ + 200, + { + sessioninOverlaps, + pagination, + }, + ]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninOverlap - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/report/sessionin-overlap/sessionin-overlap') + .reply(({ request }) => { + // Get the id from the params + const id = request.params.get('id'); + + // Clone the sessioninOverlaps + const sessioninOverlaps = cloneDeep(this._sessioninOverlaps); + + // Find the sessioninOverlap + const sessioninOverlap = sessioninOverlaps.find( + (item: any) => item.id === id + ); + + // Return the response + return [200, sessioninOverlap]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninOverlap - POST + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPost('api/apps/report/sessionin-overlap/sessionin-overlap') + .reply(() => { + // Generate a new sessioninOverlap + const newSessioninOverlap = { + id: FuseMockApiUtils.guid(), + category: '', + name: 'A New User', + description: '', + tags: [], + sku: '', + barcode: '', + brand: '', + vendor: '', + stock: '', + reserved: '', + cost: '', + basePrice: '', + taxPercent: '', + price: '', + weight: '', + thumbnail: '', + images: [], + active: false, + }; + + // Unshift the new sessioninOverlap + this._sessioninOverlaps.unshift(newSessioninOverlap); + + // Return the response + return [200, newSessioninOverlap]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninOverlap - PATCH + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPatch('api/apps/report/sessionin-overlap/sessionin-overlap') + .reply(({ request }) => { + // Get the id and sessioninOverlap + const id = request.body.id; + const sessioninOverlap = cloneDeep(request.body.sessioninOverlap); + + // Prepare the updated sessioninOverlap + let updatedSessioninOverlap = null; + + // Find the sessioninOverlap and update it + this._sessioninOverlaps.forEach((item, index, sessioninOverlaps) => { + if (item.id === id) { + // Update the sessioninOverlap + sessioninOverlaps[index] = assign( + {}, + sessioninOverlaps[index], + sessioninOverlap + ); + + // Store the updated sessioninOverlap + updatedSessioninOverlap = sessioninOverlaps[index]; + } + }); + + // Return the response + return [200, updatedSessioninOverlap]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninOverlap - DELETE + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onDelete('api/apps/report/sessionin-overlap/sessionin-overlap') + .reply(({ request }) => { + // Get the id + const id = request.params.get('id'); + + // Find the sessioninOverlap and delete it + this._sessioninOverlaps.forEach((item, index) => { + if (item.id === id) { + this._sessioninOverlaps.splice(index, 1); + } + }); + + // Return the response + return [200, true]; + }); + } +} diff --git a/src/app/mock-api/apps/report/sessionin-overlap/data.ts b/src/app/mock-api/apps/report/sessionin-overlap/data.ts new file mode 100644 index 0000000..f1f2c01 --- /dev/null +++ b/src/app/mock-api/apps/report/sessionin-overlap/data.ts @@ -0,0 +1,33 @@ +/* eslint-disable */ + +export const sessioninOverlaps = [ + { + id: 'on00', + totalPartnerCount: '5', + totalHoldingMoney: 303675, + totalComp: 108933, + total: 412608, + branchCount: 1, + divisionCount: 1, + officeCount: 1, + storeCount: 1, + memberCount: 1, + nickname: 'on00', + accountHolder: '11', + phoneNumber: '010-1111-1111', + calculateType: '롤링', + ownCash: 50000, + ownComp: 1711, + ownCoupon: 50000, + gameMoney: 0, + todayComp: 0, + totalDeposit: 0, + totalWithdraw: 0, + balance: 0, + registDate: '2022-06-12 15:38', + finalSigninDate: '', + ip: '', + state: '정상', + note: '', + }, +]; diff --git a/src/app/mock-api/common/navigation/data.ts b/src/app/mock-api/common/navigation/data.ts index e7c2579..7d8659b 100644 --- a/src/app/mock-api/common/navigation/data.ts +++ b/src/app/mock-api/common/navigation/data.ts @@ -292,6 +292,13 @@ export const defaultNavigation: FuseNavigationItem[] = [ icon: 'heroicons_outline:academic-cap', link: '/report/sessionin-info', }, + { + id: 'report.sessionin-overlap', + title: 'Sessionin Overlap', + type: 'basic', + icon: 'heroicons_outline:academic-cap', + link: '/report/sessionin-overlap', + }, { id: 'report.excel-log', title: 'Excel Log', diff --git a/src/app/mock-api/index.ts b/src/app/mock-api/index.ts index dee7e87..a21e114 100644 --- a/src/app/mock-api/index.ts +++ b/src/app/mock-api/index.ts @@ -53,6 +53,7 @@ import { ReportPaymentLogMockApi } from './apps/report/payment-log/api'; import { ReportSessioninInfoMockApi } from './apps/report/sessionin-info/api'; import { ReportExcelLogMockApi } from './apps/report/excel-log/api'; import { ReportLoosingMockApi } from './apps/report/loosing/api'; +import { ReportSessioninOverlapMockApi } from './apps/report/sessionin-overlap/api'; export const mockApiServices = [ AcademyMockApi, @@ -110,4 +111,5 @@ export const mockApiServices = [ ReportSessioninInfoMockApi, ReportExcelLogMockApi, ReportLoosingMockApi, + ReportSessioninOverlapMockApi, ]; diff --git a/src/app/modules/admin/report/sessionin-overlap/components/index.ts b/src/app/modules/admin/report/sessionin-overlap/components/index.ts new file mode 100644 index 0000000..04759eb --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/components/index.ts @@ -0,0 +1,3 @@ +import { ListComponent } from './list.component'; + +export const COMPONENTS = [ListComponent]; diff --git a/src/app/modules/admin/report/sessionin-overlap/components/list.component.html b/src/app/modules/admin/report/sessionin-overlap/components/list.component.html new file mode 100644 index 0000000..6e2c6dc --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/components/list.component.html @@ -0,0 +1,363 @@ +
+ +
+ +
+ +
+ +
중복로그인
+ +
+ + + + + + + 40 + 60 + 80 + 100 + + + + + LV.1 + LV.2 + LV.3 + LV.4 + + + + + 정상 + 대기 + 탈퇴 + 휴면 + 블랙 + 정지 + + + + + 카지노제한 + 슬롯제한 + + + + + 계좌입금 + + + + + 카지노콤프 + 슬롯콤프 + 배팅콤프 + 첫충콤프 + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+
+ + +
+ There are no sessionin overlaps! +
+
+
+
+
diff --git a/src/app/modules/admin/report/sessionin-overlap/components/list.component.ts b/src/app/modules/admin/report/sessionin-overlap/components/list.component.ts new file mode 100644 index 0000000..cedf22f --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/components/list.component.ts @@ -0,0 +1,198 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild, + ViewEncapsulation, +} from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { + debounceTime, + map, + merge, + Observable, + Subject, + switchMap, + takeUntil, +} from 'rxjs'; +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfirmationService } from '@fuse/services/confirmation'; + +import { User } from '../../../member/user/models/user'; +import { SessioninOverlap } from '../models/sessionin-overlap'; +import { SessioninOverlapPagination } from '../models/sessionin-Overlap-pagination'; +import { SessioninOverlapService } from '../services/sessionin-overlap.service'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'sessionin-overlap-list', + templateUrl: './list.component.html', + styles: [ + /* language=SCSS */ + ` + .inventory-grid { + grid-template-columns: 60px auto 40px; + + @screen sm { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px; + } + + @screen md { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px 60px; + } + + @screen lg { + grid-template-columns: 60px 70px 70px 70px 70px 100px 60px 60px auto 60px 60px 60px 60px; + } + } + `, + ], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: fuseAnimations, +}) +export class ListComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild(MatPaginator) private _paginator!: MatPaginator; + @ViewChild(MatSort) private _sort!: MatSort; + + sessioninOverlaps$!: Observable; + users$!: Observable; + + isLoading = false; + searchInputControl = new FormControl(); + selectedSessioninOverlap?: SessioninOverlap; + pagination?: SessioninOverlapPagination; + + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseConfirmationService: FuseConfirmationService, + private _formBuilder: FormBuilder, + private _sessioninOverlapService: SessioninOverlapService, + private router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { + // Get the pagination + this._sessioninOverlapService.pagination$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((pagination: SessioninOverlapPagination | undefined) => { + // Update the pagination + this.pagination = pagination; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Get the products + this.sessioninOverlaps$ = this._sessioninOverlapService.sessioninOverlaps$; + } + + /** + * After view init + */ + ngAfterViewInit(): void { + if (this._sort && this._paginator) { + // Set the initial sort + this._sort.sort({ + id: 'name', + start: 'asc', + disableClear: true, + }); + + // Mark for check + this._changeDetectorRef.markForCheck(); + + // If the sessioninOverlap changes the sort order... + this._sort.sortChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + // Reset back to the first page + this._paginator.pageIndex = 0; + }); + + // Get products if sort or page changes + merge(this._sort.sortChange, this._paginator.page) + .pipe( + switchMap(() => { + this.isLoading = true; + return this._sessioninOverlapService.getSessioninOverlaps( + this._paginator.pageIndex, + this._paginator.pageSize, + this._sort.active, + this._sort.direction + ); + }), + map(() => { + this.isLoading = false; + }) + ) + .subscribe(); + } + } + + /** + * On destroy + */ + ngOnDestroy(): void { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(null); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + viewUserDetail(id: string): void { + let url: string = 'member/user/' + id; + this.router.navigateByUrl(url); + } + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create product + */ + __createProduct(): void {} + + /** + * Toggle product details + * + * @param productId + */ + __toggleDetails(productId: string): void {} + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + __trackByFn(index: number, item: any): any { + return item.id || index; + } +} diff --git a/src/app/modules/admin/report/sessionin-overlap/models/sessionin-Overlap-pagination.ts b/src/app/modules/admin/report/sessionin-overlap/models/sessionin-Overlap-pagination.ts new file mode 100644 index 0000000..0e12fc4 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/models/sessionin-Overlap-pagination.ts @@ -0,0 +1,8 @@ +export interface SessioninOverlapPagination { + length: number; + size: number; + page: number; + lastPage: number; + startIndex: number; + endIndex: number; +} diff --git a/src/app/modules/admin/report/sessionin-overlap/models/sessionin-overlap.ts b/src/app/modules/admin/report/sessionin-overlap/models/sessionin-overlap.ts new file mode 100644 index 0000000..574f138 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/models/sessionin-overlap.ts @@ -0,0 +1,29 @@ +export interface SessioninOverlap { + id?: string; + totalPartnerCount?: number; + totalHoldingMoney?: number; + totalComp?: number; + total?: number; + branchCount?: number; + divisionCount?: number; + officeCount?: number; + storeCount?: number; + memberCount?: number; + nickname?: string; + accountHolder?: string; + phoneNumber?: string; + calculateType?: string; + ownCash?: number; + ownComp?: number; + ownCoupon?: number; + gameMoney?: number; + todayComp?: number; + totalDeposit?: number; + totalWithdraw?: number; + balance?: number; + registDate?: string; + finalSigninDate?: string; + ip?: string; + state?: string; + note?: string; +} diff --git a/src/app/modules/admin/report/sessionin-overlap/resolvers/sessionin-overlap.resolver.ts b/src/app/modules/admin/report/sessionin-overlap/resolvers/sessionin-overlap.resolver.ts new file mode 100644 index 0000000..476cb16 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/resolvers/sessionin-overlap.resolver.ts @@ -0,0 +1,89 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + Resolve, + Router, + RouterStateSnapshot, +} from '@angular/router'; +import { catchError, Observable, throwError } from 'rxjs'; + +import { SessioninOverlap } from '../models/sessionin-overlap'; +import { SessioninOverlapPagination } from '../models/sessionin-Overlap-pagination'; +import { SessioninOverlapService } from '../services/sessionin-overlap.service'; + +@Injectable({ + providedIn: 'root', +}) +export class SessioninOverlapResolver implements Resolve { + /** + * Constructor + */ + constructor( + private _sessioninOverlapService: SessioninOverlapService, + private _router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable { + return this._sessioninOverlapService + .getSessioninOverlapById(route.paramMap.get('id')) + .pipe( + // Error here means the requested product is not available + catchError((error) => { + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} + +@Injectable({ + providedIn: 'root', +}) +export class SessioninOverlapsResolver implements Resolve { + /** + * Constructor + */ + constructor(private _sessioninOverlapService: SessioninOverlapService) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable<{ + pagination: SessioninOverlapPagination; + sessioninOverlaps: SessioninOverlap[]; + }> { + return this._sessioninOverlapService.getSessioninOverlaps(); + } +} diff --git a/src/app/modules/admin/report/sessionin-overlap/services/sessionin-overlap.service.ts b/src/app/modules/admin/report/sessionin-overlap/services/sessionin-overlap.service.ts new file mode 100644 index 0000000..94b31f6 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/services/sessionin-overlap.service.ts @@ -0,0 +1,164 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { + BehaviorSubject, + filter, + map, + Observable, + of, + switchMap, + take, + tap, + throwError, +} from 'rxjs'; + +import { SessioninOverlap } from '../models/sessionin-overlap'; +import { SessioninOverlapPagination } from '../models/sessionin-Overlap-pagination'; + +@Injectable({ + providedIn: 'root', +}) +export class SessioninOverlapService { + // Private + private __pagination = new BehaviorSubject< + SessioninOverlapPagination | undefined + >(undefined); + private __sessioninOverlap = new BehaviorSubject< + SessioninOverlap | undefined + >(undefined); + private __sessioninOverlaps = new BehaviorSubject< + SessioninOverlap[] | undefined + >(undefined); + + /** + * Constructor + */ + constructor(private _httpClient: HttpClient) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Getter for pagination + */ + get pagination$(): Observable { + return this.__pagination.asObservable(); + } + + /** + * Getter for sessioninOverlap + */ + get sessioninOverlap$(): Observable { + return this.__sessioninOverlap.asObservable(); + } + + /** + * Getter for sessioninOverlaps + */ + get sessioninOverlaps$(): Observable { + return this.__sessioninOverlaps.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get SessioninOverlaps + * + * + * @param page + * @param size + * @param sort + * @param order + * @param search + */ + getSessioninOverlaps( + page: number = 0, + size: number = 10, + sort: string = 'name', + order: 'asc' | 'desc' | '' = 'asc', + search: string = '' + ): Observable<{ + pagination: SessioninOverlapPagination; + sessioninOverlaps: SessioninOverlap[]; + }> { + return this._httpClient + .get<{ + pagination: SessioninOverlapPagination; + sessioninOverlaps: SessioninOverlap[]; + }>('api/apps/report/sessionin-overlap/sessionin-overlaps', { + params: { + page: '' + page, + size: '' + size, + sort, + order, + search, + }, + }) + .pipe( + tap((response) => { + this.__pagination.next(response.pagination); + this.__sessioninOverlaps.next(response.sessioninOverlaps); + }) + ); + } + + /** + * Get product by id + */ + getSessioninOverlapById(id: string | null): Observable { + return this.__sessioninOverlaps.pipe( + take(1), + map((sessioninOverlaps) => { + // Find the product + const sessioninOverlap = + sessioninOverlaps?.find((item) => item.id === id) || undefined; + + // Update the product + this.__sessioninOverlap.next(sessioninOverlap); + + // Return the product + return sessioninOverlap; + }), + switchMap((product) => { + if (!product) { + return throwError('Could not found product with id of ' + id + '!'); + } + + return of(product); + }) + ); + } + + /** + * Create product + */ + createSessioninOverlap(): Observable { + return this.sessioninOverlaps$.pipe( + take(1), + switchMap((sessioninOverlaps) => + this._httpClient + .post( + 'api/apps/report/sessionin-overlap/product', + {} + ) + .pipe( + map((newSessioninOverlap) => { + // Update the sessioninOverlaps with the new product + if (!!sessioninOverlaps) { + this.__sessioninOverlaps.next([ + newSessioninOverlap, + ...sessioninOverlaps, + ]); + } + + // Return the new product + return newSessioninOverlap; + }) + ) + ) + ); + } +} diff --git a/src/app/modules/admin/report/sessionin-overlap/sessionin-overlap.module.ts b/src/app/modules/admin/report/sessionin-overlap/sessionin-overlap.module.ts new file mode 100644 index 0000000..0b3825c --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/sessionin-overlap.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +import { MatSortModule } from '@angular/material/sort'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + +import { TranslocoModule } from '@ngneat/transloco'; + +import { SharedModule } from 'app/shared/shared.module'; + +import { COMPONENTS } from './components'; + +import { sessioninOverlapRoutes } from './sessionin-overlap.routing'; + +@NgModule({ + declarations: [COMPONENTS], + imports: [ + TranslocoModule, + SharedModule, + RouterModule.forChild(sessioninOverlapRoutes), + + MatButtonModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatPaginatorModule, + MatProgressBarModule, + MatRippleModule, + MatSortModule, + MatSelectModule, + MatTooltipModule, + MatGridListModule, + MatSlideToggleModule, + MatRadioModule, + MatCheckboxModule, + ], +}) +export class SessioninOverlapModule {} diff --git a/src/app/modules/admin/report/sessionin-overlap/sessionin-overlap.routing.ts b/src/app/modules/admin/report/sessionin-overlap/sessionin-overlap.routing.ts new file mode 100644 index 0000000..9411951 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-overlap/sessionin-overlap.routing.ts @@ -0,0 +1,24 @@ +import { Route } from '@angular/router'; + +import { ListComponent } from './components/list.component'; +import { ViewComponent } from '../../member/user/components/view.component'; + +import { SessioninOverlapsResolver } from './resolvers/sessionin-overlap.resolver'; +import { UserResolver } from '../../member/user/resolvers/user.resolver'; + +export const sessioninOverlapRoutes: Route[] = [ + { + path: '', + component: ListComponent, + resolve: { + sessioninOverlaps: SessioninOverlapsResolver, + }, + }, + { + path: ':id', + component: ViewComponent, + resolve: { + users: UserResolver, + }, + }, +]; diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index e12b49d..43a7458 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -34,6 +34,7 @@ "Modification Log": "Member Modification Logs", "Payment Log": "Manual Payment Logs", "Sessionin Info": "Sessionin Info", + "Sessionin Overlap": "Sessionin Overlap", "Excel Log": "Excel Download Logs", "Loosing": "Loosing Management" } diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json index 63cba82..97e2b88 100644 --- a/src/assets/i18n/ko.json +++ b/src/assets/i18n/ko.json @@ -35,6 +35,7 @@ "Modification Log": "회원수정 로그", "Payment Log": "수동지급/회수 로그", "Sessionin Info": "로그인정보", + "Sessionin Overlap": "중복로그인", "Excel Log": "엑셀다운 로그", "Loosing": "루징관리" } From 6ec39361d6c69fdfa964aee5b11c9847060f9a85 Mon Sep 17 00:00:00 2001 From: JUNG YI DAM Date: Thu, 14 Jul 2022 05:45:55 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=EC=A0=95=EB=B3=B4=20page=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app.routing.ts | 7 + .../apps/report/sessionin-admin/api.ts | 223 +++++++++++ .../apps/report/sessionin-admin/data.ts | 33 ++ src/app/mock-api/common/navigation/data.ts | 7 + src/app/mock-api/index.ts | 6 +- .../sessionin-admin/components/index.ts | 3 + .../components/list.component.html | 359 ++++++++++++++++++ .../components/list.component.ts | 198 ++++++++++ .../models/sessionin-admin-pagination.ts | 8 + .../sessionin-admin/models/sessionin-admin.ts | 29 ++ .../resolvers/sessionin-admin.resolver.ts | 89 +++++ .../services/sessionin-admin.service.ts | 161 ++++++++ .../sessionin-admin/sessionin-admin.module.ts | 50 +++ .../sessionin-admin.routing.ts | 24 ++ src/assets/i18n/en.json | 1 + src/assets/i18n/ko.json | 1 + 16 files changed, 1197 insertions(+), 2 deletions(-) create mode 100644 src/app/mock-api/apps/report/sessionin-admin/api.ts create mode 100644 src/app/mock-api/apps/report/sessionin-admin/data.ts create mode 100644 src/app/modules/admin/report/sessionin-admin/components/index.ts create mode 100644 src/app/modules/admin/report/sessionin-admin/components/list.component.html create mode 100644 src/app/modules/admin/report/sessionin-admin/components/list.component.ts create mode 100644 src/app/modules/admin/report/sessionin-admin/models/sessionin-admin-pagination.ts create mode 100644 src/app/modules/admin/report/sessionin-admin/models/sessionin-admin.ts create mode 100644 src/app/modules/admin/report/sessionin-admin/resolvers/sessionin-admin.resolver.ts create mode 100644 src/app/modules/admin/report/sessionin-admin/services/sessionin-admin.service.ts create mode 100644 src/app/modules/admin/report/sessionin-admin/sessionin-admin.module.ts create mode 100644 src/app/modules/admin/report/sessionin-admin/sessionin-admin.routing.ts diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts index 2ac9414..0915fc2 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routing.ts @@ -387,6 +387,13 @@ export const appRoutes: Route[] = [ 'app/modules/admin/report/sessionin-overlap/sessionin-overlap.module' ).then((m: any) => m.SessioninOverlapModule), }, + { + path: 'sessionin-admin', + loadChildren: () => + import( + 'app/modules/admin/report/sessionin-admin/sessionin-admin.module' + ).then((m: any) => m.SessioninAdminModule), + }, { path: 'excel-log', loadChildren: () => diff --git a/src/app/mock-api/apps/report/sessionin-admin/api.ts b/src/app/mock-api/apps/report/sessionin-admin/api.ts new file mode 100644 index 0000000..c03f480 --- /dev/null +++ b/src/app/mock-api/apps/report/sessionin-admin/api.ts @@ -0,0 +1,223 @@ +import { Injectable } from '@angular/core'; +import { assign, cloneDeep } from 'lodash-es'; +import { FuseMockApiService, FuseMockApiUtils } from '@fuse/lib/mock-api'; +import { sessioninAdmins as sessioninAdminsData } from './data'; + +@Injectable({ + providedIn: 'root', +}) +export class ReportSessioninAdminMockApi { + private _sessioninAdmins: any[] = sessioninAdminsData; + + /** + * Constructor + */ + constructor(private _fuseMockApiService: FuseMockApiService) { + // Register Mock API handlers + this.registerHandlers(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Register Mock API handlers + */ + registerHandlers(): void { + // ----------------------------------------------------------------------------------------------------- + // @ SessioninAdmins - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/report/sessionin-admin/sessionin-admins', 300) + .reply(({ request }) => { + // Get available queries + const search = request.params.get('search'); + const sort = request.params.get('sort') || 'name'; + const order = request.params.get('order') || 'asc'; + const page = parseInt(request.params.get('page') ?? '1', 10); + const size = parseInt(request.params.get('size') ?? '10', 10); + + // Clone the sessioninAdmins + let sessioninAdmins: any[] | null = cloneDeep(this._sessioninAdmins); + + // Sort the sessioninAdmins + if (sort === 'sku' || sort === 'name' || sort === 'active') { + sessioninAdmins.sort((a, b) => { + const fieldA = a[sort].toString().toUpperCase(); + const fieldB = b[sort].toString().toUpperCase(); + return order === 'asc' + ? fieldA.localeCompare(fieldB) + : fieldB.localeCompare(fieldA); + }); + } else { + sessioninAdmins.sort((a, b) => + order === 'asc' ? a[sort] - b[sort] : b[sort] - a[sort] + ); + } + + // If search exists... + if (search) { + // Filter the sessioninAdmins + sessioninAdmins = sessioninAdmins.filter( + (contact: any) => + contact.name && + contact.name.toLowerCase().includes(search.toLowerCase()) + ); + } + + // Paginate - Start + const sessioninAdminsLength = sessioninAdmins.length; + + // Calculate pagination details + const begin = page * size; + const end = Math.min(size * (page + 1), sessioninAdminsLength); + const lastPage = Math.max(Math.ceil(sessioninAdminsLength / size), 1); + + // Prepare the pagination object + let pagination = {}; + + // If the requested page number is bigger than + // the last possible page number, return null for + // sessioninAdmins but also send the last possible page so + // the app can navigate to there + if (page > lastPage) { + sessioninAdmins = null; + pagination = { + lastPage, + }; + } else { + // Paginate the results by size + sessioninAdmins = sessioninAdmins.slice(begin, end); + + // Prepare the pagination mock-api + pagination = { + length: sessioninAdminsLength, + size: size, + page: page, + lastPage: lastPage, + startIndex: begin, + endIndex: end - 1, + }; + } + + // Return the response + return [ + 200, + { + sessioninAdmins, + pagination, + }, + ]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninAdmin - GET + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onGet('api/apps/report/sessionin-admin/sessionin-admin') + .reply(({ request }) => { + // Get the id from the params + const id = request.params.get('id'); + + // Clone the sessioninAdmins + const sessioninAdmins = cloneDeep(this._sessioninAdmins); + + // Find the sessioninAdmin + const sessioninAdmin = sessioninAdmins.find( + (item: any) => item.id === id + ); + + // Return the response + return [200, sessioninAdmin]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninAdmin - POST + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPost('api/apps/report/sessionin-admin/sessionin-admin') + .reply(() => { + // Generate a new sessioninAdmin + const newSessioninAdmin = { + id: FuseMockApiUtils.guid(), + category: '', + name: 'A New User', + description: '', + tags: [], + sku: '', + barcode: '', + brand: '', + vendor: '', + stock: '', + reserved: '', + cost: '', + basePrice: '', + taxPercent: '', + price: '', + weight: '', + thumbnail: '', + images: [], + active: false, + }; + + // Unshift the new sessioninAdmin + this._sessioninAdmins.unshift(newSessioninAdmin); + + // Return the response + return [200, newSessioninAdmin]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninAdmin - PATCH + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onPatch('api/apps/report/sessionin-admin/sessionin-admin') + .reply(({ request }) => { + // Get the id and sessioninAdmin + const id = request.body.id; + const sessioninAdmin = cloneDeep(request.body.sessioninAdmin); + + // Prepare the updated sessioninAdmin + let updatedSessioninAdmin = null; + + // Find the sessioninAdmin and update it + this._sessioninAdmins.forEach((item, index, sessioninAdmins) => { + if (item.id === id) { + // Update the sessioninAdmin + sessioninAdmins[index] = assign( + {}, + sessioninAdmins[index], + sessioninAdmin + ); + + // Store the updated sessioninAdmin + updatedSessioninAdmin = sessioninAdmins[index]; + } + }); + + // Return the response + return [200, updatedSessioninAdmin]; + }); + + // ----------------------------------------------------------------------------------------------------- + // @ SessioninAdmin - DELETE + // ----------------------------------------------------------------------------------------------------- + this._fuseMockApiService + .onDelete('api/apps/report/sessionin-admin/sessionin-admin') + .reply(({ request }) => { + // Get the id + const id = request.params.get('id'); + + // Find the sessioninAdmin and delete it + this._sessioninAdmins.forEach((item, index) => { + if (item.id === id) { + this._sessioninAdmins.splice(index, 1); + } + }); + + // Return the response + return [200, true]; + }); + } +} diff --git a/src/app/mock-api/apps/report/sessionin-admin/data.ts b/src/app/mock-api/apps/report/sessionin-admin/data.ts new file mode 100644 index 0000000..33aa15a --- /dev/null +++ b/src/app/mock-api/apps/report/sessionin-admin/data.ts @@ -0,0 +1,33 @@ +/* eslint-disable */ + +export const sessioninAdmins = [ + { + id: 'on00', + totalPartnerCount: '5', + totalHoldingMoney: 303675, + totalComp: 108933, + total: 412608, + branchCount: 1, + divisionCount: 1, + officeCount: 1, + storeCount: 1, + memberCount: 1, + nickname: 'on00', + accountHolder: '11', + phoneNumber: '010-1111-1111', + calculateType: '롤링', + ownCash: 50000, + ownComp: 1711, + ownCoupon: 50000, + gameMoney: 0, + todayComp: 0, + totalDeposit: 0, + totalWithdraw: 0, + balance: 0, + registDate: '2022-06-12 15:38', + finalSigninDate: '', + ip: '', + state: '정상', + note: '', + }, +]; diff --git a/src/app/mock-api/common/navigation/data.ts b/src/app/mock-api/common/navigation/data.ts index 7d8659b..82b8983 100644 --- a/src/app/mock-api/common/navigation/data.ts +++ b/src/app/mock-api/common/navigation/data.ts @@ -299,6 +299,13 @@ export const defaultNavigation: FuseNavigationItem[] = [ icon: 'heroicons_outline:academic-cap', link: '/report/sessionin-overlap', }, + { + id: 'report.sessionin-admin', + title: 'Sessionin Admin', + type: 'basic', + icon: 'heroicons_outline:academic-cap', + link: '/report/sessionin-admin', + }, { id: 'report.excel-log', title: 'Excel Log', diff --git a/src/app/mock-api/index.ts b/src/app/mock-api/index.ts index a21e114..d2b3bba 100644 --- a/src/app/mock-api/index.ts +++ b/src/app/mock-api/index.ts @@ -51,9 +51,10 @@ import { ReportCompLogMockApi } from './apps/report/comp-log/api'; import { ReportModificationLogMockApi } from './apps/report/modification-log/api'; import { ReportPaymentLogMockApi } from './apps/report/payment-log/api'; import { ReportSessioninInfoMockApi } from './apps/report/sessionin-info/api'; +import { ReportSessioninOverlapMockApi } from './apps/report/sessionin-overlap/api'; +import { ReportSessioninAdminMockApi } from './apps/report/sessionin-admin/api'; import { ReportExcelLogMockApi } from './apps/report/excel-log/api'; import { ReportLoosingMockApi } from './apps/report/loosing/api'; -import { ReportSessioninOverlapMockApi } from './apps/report/sessionin-overlap/api'; export const mockApiServices = [ AcademyMockApi, @@ -109,7 +110,8 @@ export const mockApiServices = [ ReportModificationLogMockApi, ReportPaymentLogMockApi, ReportSessioninInfoMockApi, + ReportSessioninOverlapMockApi, + ReportSessioninAdminMockApi, ReportExcelLogMockApi, ReportLoosingMockApi, - ReportSessioninOverlapMockApi, ]; diff --git a/src/app/modules/admin/report/sessionin-admin/components/index.ts b/src/app/modules/admin/report/sessionin-admin/components/index.ts new file mode 100644 index 0000000..04759eb --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/components/index.ts @@ -0,0 +1,3 @@ +import { ListComponent } from './list.component'; + +export const COMPONENTS = [ListComponent]; diff --git a/src/app/modules/admin/report/sessionin-admin/components/list.component.html b/src/app/modules/admin/report/sessionin-admin/components/list.component.html new file mode 100644 index 0000000..5aca1f8 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/components/list.component.html @@ -0,0 +1,359 @@ +
+ +
+ +
+ +
+ +
관리자로그인정보
+ +
+ + + + + + + 40 + 60 + 80 + 100 + + + + + LV.1 + LV.2 + LV.3 + LV.4 + + + + + 정상 + 대기 + 탈퇴 + 휴면 + 블랙 + 정지 + + + + + 카지노제한 + 슬롯제한 + + + + + 계좌입금 + + + + + 카지노콤프 + 슬롯콤프 + 배팅콤프 + 첫충콤프 + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +
+
+ + +
+ There are no sessionin Admin Infos! +
+
+
+
+
diff --git a/src/app/modules/admin/report/sessionin-admin/components/list.component.ts b/src/app/modules/admin/report/sessionin-admin/components/list.component.ts new file mode 100644 index 0000000..0d81262 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/components/list.component.ts @@ -0,0 +1,198 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit, + ViewChild, + ViewEncapsulation, +} from '@angular/core'; +import { + FormBuilder, + FormControl, + FormGroup, + Validators, +} from '@angular/forms'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { + debounceTime, + map, + merge, + Observable, + Subject, + switchMap, + takeUntil, +} from 'rxjs'; +import { fuseAnimations } from '@fuse/animations'; +import { FuseConfirmationService } from '@fuse/services/confirmation'; + +import { User } from '../../../member/user/models/user'; +import { SessioninAdmin } from '../models/sessionin-admin'; +import { SessioninAdminPagination } from '../models/sessionin-admin-pagination'; +import { SessioninAdminService } from '../services/sessionin-admin.service'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'sessionin-admin-list', + templateUrl: './list.component.html', + styles: [ + /* language=SCSS */ + ` + .inventory-grid { + grid-template-columns: 60px auto 40px; + + @screen sm { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px; + } + + @screen md { + grid-template-columns: 60px 60px 60px 60px 60px 60px auto 60px 60px; + } + + @screen lg { + grid-template-columns: 60px 70px 70px 70px 70px 100px 60px 60px auto 60px 60px 60px 60px; + } + } + `, + ], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + animations: fuseAnimations, +}) +export class ListComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild(MatPaginator) private _paginator!: MatPaginator; + @ViewChild(MatSort) private _sort!: MatSort; + + sessioninAdmins$!: Observable; + users$!: Observable; + + isLoading = false; + searchInputControl = new FormControl(); + selectedSessioninAdmin?: SessioninAdmin; + pagination?: SessioninAdminPagination; + + private _unsubscribeAll: Subject = new Subject(); + + /** + * Constructor + */ + constructor( + private _changeDetectorRef: ChangeDetectorRef, + private _fuseConfirmationService: FuseConfirmationService, + private _formBuilder: FormBuilder, + private _sessioninAdminService: SessioninAdminService, + private router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Lifecycle hooks + // ----------------------------------------------------------------------------------------------------- + + /** + * On init + */ + ngOnInit(): void { + // Get the pagination + this._sessioninAdminService.pagination$ + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe((pagination: SessioninAdminPagination | undefined) => { + // Update the pagination + this.pagination = pagination; + + // Mark for check + this._changeDetectorRef.markForCheck(); + }); + + // Get the products + this.sessioninAdmins$ = this._sessioninAdminService.sessioninAdmins$; + } + + /** + * After view init + */ + ngAfterViewInit(): void { + if (this._sort && this._paginator) { + // Set the initial sort + this._sort.sort({ + id: 'name', + start: 'asc', + disableClear: true, + }); + + // Mark for check + this._changeDetectorRef.markForCheck(); + + // If the sessioninAdmin changes the sort order... + this._sort.sortChange + .pipe(takeUntil(this._unsubscribeAll)) + .subscribe(() => { + // Reset back to the first page + this._paginator.pageIndex = 0; + }); + + // Get products if sort or page changes + merge(this._sort.sortChange, this._paginator.page) + .pipe( + switchMap(() => { + this.isLoading = true; + return this._sessioninAdminService.getSessioninAdmins( + this._paginator.pageIndex, + this._paginator.pageSize, + this._sort.active, + this._sort.direction + ); + }), + map(() => { + this.isLoading = false; + }) + ) + .subscribe(); + } + } + + /** + * On destroy + */ + ngOnDestroy(): void { + // Unsubscribe from all subscriptions + this._unsubscribeAll.next(null); + this._unsubscribeAll.complete(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + viewUserDetail(id: string): void { + let url: string = 'member/user/' + id; + this.router.navigateByUrl(url); + } + // ----------------------------------------------------------------------------------------------------- + // @ Private methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Create product + */ + __createProduct(): void {} + + /** + * Toggle product details + * + * @param productId + */ + __toggleDetails(productId: string): void {} + + /** + * Track by function for ngFor loops + * + * @param index + * @param item + */ + __trackByFn(index: number, item: any): any { + return item.id || index; + } +} diff --git a/src/app/modules/admin/report/sessionin-admin/models/sessionin-admin-pagination.ts b/src/app/modules/admin/report/sessionin-admin/models/sessionin-admin-pagination.ts new file mode 100644 index 0000000..7503a10 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/models/sessionin-admin-pagination.ts @@ -0,0 +1,8 @@ +export interface SessioninAdminPagination { + length: number; + size: number; + page: number; + lastPage: number; + startIndex: number; + endIndex: number; +} diff --git a/src/app/modules/admin/report/sessionin-admin/models/sessionin-admin.ts b/src/app/modules/admin/report/sessionin-admin/models/sessionin-admin.ts new file mode 100644 index 0000000..d285865 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/models/sessionin-admin.ts @@ -0,0 +1,29 @@ +export interface SessioninAdmin { + id?: string; + totalPartnerCount?: number; + totalHoldingMoney?: number; + totalComp?: number; + total?: number; + branchCount?: number; + divisionCount?: number; + officeCount?: number; + storeCount?: number; + memberCount?: number; + nickname?: string; + accountHolder?: string; + phoneNumber?: string; + calculateType?: string; + ownCash?: number; + ownComp?: number; + ownCoupon?: number; + gameMoney?: number; + todayComp?: number; + totalDeposit?: number; + totalWithdraw?: number; + balance?: number; + registDate?: string; + finalSigninDate?: string; + ip?: string; + state?: string; + note?: string; +} diff --git a/src/app/modules/admin/report/sessionin-admin/resolvers/sessionin-admin.resolver.ts b/src/app/modules/admin/report/sessionin-admin/resolvers/sessionin-admin.resolver.ts new file mode 100644 index 0000000..c089aa9 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/resolvers/sessionin-admin.resolver.ts @@ -0,0 +1,89 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + Resolve, + Router, + RouterStateSnapshot, +} from '@angular/router'; +import { catchError, Observable, throwError } from 'rxjs'; + +import { SessioninAdmin } from '../models/sessionin-admin'; +import { SessioninAdminPagination } from '../models/sessionin-admin-pagination'; +import { SessioninAdminService } from '../services/sessionin-admin.service'; + +@Injectable({ + providedIn: 'root', +}) +export class SessioninAdminResolver implements Resolve { + /** + * Constructor + */ + constructor( + private _sessioninAdminService: SessioninAdminService, + private _router: Router + ) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable { + return this._sessioninAdminService + .getSessioninAdminById(route.paramMap.get('id')) + .pipe( + // Error here means the requested product is not available + catchError((error) => { + // Log the error + console.error(error); + + // Get the parent url + const parentUrl = state.url.split('/').slice(0, -1).join('/'); + + // Navigate to there + this._router.navigateByUrl(parentUrl); + + // Throw an error + return throwError(error); + }) + ); + } +} + +@Injectable({ + providedIn: 'root', +}) +export class SessioninAdminsResolver implements Resolve { + /** + * Constructor + */ + constructor(private _sessioninAdminService: SessioninAdminService) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Resolver + * + * @param route + * @param state + */ + resolve( + route: ActivatedRouteSnapshot, + state: RouterStateSnapshot + ): Observable<{ + pagination: SessioninAdminPagination; + sessioninAdmins: SessioninAdmin[]; + }> { + return this._sessioninAdminService.getSessioninAdmins(); + } +} diff --git a/src/app/modules/admin/report/sessionin-admin/services/sessionin-admin.service.ts b/src/app/modules/admin/report/sessionin-admin/services/sessionin-admin.service.ts new file mode 100644 index 0000000..bf25057 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/services/sessionin-admin.service.ts @@ -0,0 +1,161 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { + BehaviorSubject, + filter, + map, + Observable, + of, + switchMap, + take, + tap, + throwError, +} from 'rxjs'; + +import { SessioninAdmin } from '../models/sessionin-admin'; +import { SessioninAdminPagination } from '../models/sessionin-admin-pagination'; + +@Injectable({ + providedIn: 'root', +}) +export class SessioninAdminService { + // Private + private __pagination = new BehaviorSubject< + SessioninAdminPagination | undefined + >(undefined); + private __sessioninAdmin = new BehaviorSubject( + undefined + ); + private __sessioninAdmins = new BehaviorSubject( + undefined + ); + + /** + * Constructor + */ + constructor(private _httpClient: HttpClient) {} + + // ----------------------------------------------------------------------------------------------------- + // @ Accessors + // ----------------------------------------------------------------------------------------------------- + + /** + * Getter for pagination + */ + get pagination$(): Observable { + return this.__pagination.asObservable(); + } + + /** + * Getter for sessioninAdmin + */ + get sessioninAdmin$(): Observable { + return this.__sessioninAdmin.asObservable(); + } + + /** + * Getter for sessioninAdmins + */ + get sessioninAdmins$(): Observable { + return this.__sessioninAdmins.asObservable(); + } + + // ----------------------------------------------------------------------------------------------------- + // @ Public methods + // ----------------------------------------------------------------------------------------------------- + + /** + * Get SessioninAdmins + * + * + * @param page + * @param size + * @param sort + * @param order + * @param search + */ + getSessioninAdmins( + page: number = 0, + size: number = 10, + sort: string = 'name', + order: 'asc' | 'desc' | '' = 'asc', + search: string = '' + ): Observable<{ + pagination: SessioninAdminPagination; + sessioninAdmins: SessioninAdmin[]; + }> { + return this._httpClient + .get<{ + pagination: SessioninAdminPagination; + sessioninAdmins: SessioninAdmin[]; + }>('api/apps/report/sessionin-admin/sessionin-admins', { + params: { + page: '' + page, + size: '' + size, + sort, + order, + search, + }, + }) + .pipe( + tap((response) => { + this.__pagination.next(response.pagination); + this.__sessioninAdmins.next(response.sessioninAdmins); + }) + ); + } + + /** + * Get product by id + */ + getSessioninAdminById(id: string | null): Observable { + return this.__sessioninAdmins.pipe( + take(1), + map((sessioninAdmins) => { + // Find the product + const sessioninAdmin = + sessioninAdmins?.find((item) => item.id === id) || undefined; + + // Update the product + this.__sessioninAdmin.next(sessioninAdmin); + + // Return the product + return sessioninAdmin; + }), + switchMap((product) => { + if (!product) { + return throwError('Could not found product with id of ' + id + '!'); + } + + return of(product); + }) + ); + } + + /** + * Create product + */ + createSessioninAdmin(): Observable { + return this.sessioninAdmins$.pipe( + take(1), + switchMap((sessioninAdmins) => + this._httpClient + .post('api/apps/report/sessionin-admin/product', {}) + .pipe( + map((newSessioninAdmin) => { + // Update the sessioninAdmins with the new product + if (!!sessioninAdmins) { + this.__sessioninAdmins.next([ + newSessioninAdmin, + ...sessioninAdmins, + ]); + } + + // Return the new product + return newSessioninAdmin; + }) + ) + ) + ); + } +} diff --git a/src/app/modules/admin/report/sessionin-admin/sessionin-admin.module.ts b/src/app/modules/admin/report/sessionin-admin/sessionin-admin.module.ts new file mode 100644 index 0000000..c281ee5 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/sessionin-admin.module.ts @@ -0,0 +1,50 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatRippleModule } from '@angular/material/core'; +import { MatSortModule } from '@angular/material/sort'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatGridListModule } from '@angular/material/grid-list'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatRadioModule } from '@angular/material/radio'; +import { MatCheckboxModule } from '@angular/material/checkbox'; + +import { TranslocoModule } from '@ngneat/transloco'; + +import { SharedModule } from 'app/shared/shared.module'; + +import { COMPONENTS } from './components'; + +import { sessioninAdminRoutes } from './sessionin-admin.routing'; + +@NgModule({ + declarations: [COMPONENTS], + imports: [ + TranslocoModule, + SharedModule, + RouterModule.forChild(sessioninAdminRoutes), + + MatButtonModule, + MatFormFieldModule, + MatIconModule, + MatInputModule, + MatPaginatorModule, + MatProgressBarModule, + MatRippleModule, + MatSortModule, + MatSelectModule, + MatTooltipModule, + MatGridListModule, + MatSlideToggleModule, + MatRadioModule, + MatCheckboxModule, + ], +}) +export class SessioninAdminModule {} diff --git a/src/app/modules/admin/report/sessionin-admin/sessionin-admin.routing.ts b/src/app/modules/admin/report/sessionin-admin/sessionin-admin.routing.ts new file mode 100644 index 0000000..493ade7 --- /dev/null +++ b/src/app/modules/admin/report/sessionin-admin/sessionin-admin.routing.ts @@ -0,0 +1,24 @@ +import { Route } from '@angular/router'; + +import { ListComponent } from './components/list.component'; +import { ViewComponent } from '../../member/user/components/view.component'; + +import { SessioninAdminsResolver } from './resolvers/sessionin-admin.resolver'; +import { UserResolver } from '../../member/user/resolvers/user.resolver'; + +export const sessioninAdminRoutes: Route[] = [ + { + path: '', + component: ListComponent, + resolve: { + sessioninAdmins: SessioninAdminsResolver, + }, + }, + { + path: ':id', + component: ViewComponent, + resolve: { + users: UserResolver, + }, + }, +]; diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 43a7458..bad3712 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -34,6 +34,7 @@ "Modification Log": "Member Modification Logs", "Payment Log": "Manual Payment Logs", "Sessionin Info": "Sessionin Info", + "Sessionin Admin": "Sessionin Admin Info", "Sessionin Overlap": "Sessionin Overlap", "Excel Log": "Excel Download Logs", "Loosing": "Loosing Management" diff --git a/src/assets/i18n/ko.json b/src/assets/i18n/ko.json index 97e2b88..e4a6a09 100644 --- a/src/assets/i18n/ko.json +++ b/src/assets/i18n/ko.json @@ -36,6 +36,7 @@ "Payment Log": "수동지급/회수 로그", "Sessionin Info": "로그인정보", "Sessionin Overlap": "중복로그인", + "Sessionin Admin": "관리자 로그인정보", "Excel Log": "엑셀다운 로그", "Loosing": "루징관리" }