1. 조직도 검색시 200건 이상 조회 가능하도록 수정,

2. 조직도 테이블 virture scroll 적용.
This commit is contained in:
leejinho 2020-04-03 10:33:02 +09:00
parent e3b26549cc
commit 7eb7d85da9
6 changed files with 195 additions and 75 deletions

View File

@ -1,6 +1,6 @@
{
"name": "ucap-webmessenger",
"version": "1.0.16",
"version": "1.0.0",
"author": {
"name": "LG CNS",
"email": "lgucap@lgcns.com"
@ -137,6 +137,7 @@
"moment": "^2.24.0",
"moment-timezone": "^0.5.27",
"ng-packagr": "^5.7.1",
"ng-table-virtual-scroll": "^1.3.1",
"ngrx-store-freeze": "^0.2.4",
"ngx-logger": "^4.0.8",
"ngx-perfect-scrollbar": "^8.0.0",

View File

@ -95,6 +95,8 @@ export const searchDeptUser = createAction(
props<{
companyCode: string;
search: string;
pageCurrent?: number;
userList?: UserInfoSS[];
}>()
);
@ -119,6 +121,8 @@ export const integrateSearchDeptUser = createAction(
props<{
companyCode: string;
search: string;
pageCurrent?: number;
userList?: UserInfoSS[];
}>()
);

View File

@ -10,8 +10,7 @@ import {
map,
tap,
switchMap,
withLatestFrom,
take
withLatestFrom
} from 'rxjs/operators';
import {
@ -28,7 +27,6 @@ import {
selectedDeptSuccess,
searchDeptUser,
searchDeptUserSuccess,
clearSearchDeptUser,
integrateSearchDeptUser,
integrateSearchDeptUserSuccess,
integrateSearchDeptUserFailure,
@ -45,13 +43,12 @@ import {
SSVC_TYPE_QUERY_DEPT_USER_DATA,
DeptUserData,
SSVC_TYPE_QUERY_DEPT_USER_RES,
DeptUserResponse,
DeptSearchType
DeptSearchType,
DeptUserRequest
} from '@ucap-webmessenger/protocol-query';
import { Store, select } from '@ngrx/store';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { KEY_LOGIN_RES_INFO } from '@app/types';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { OrganizationService } from '@ucap-webmessenger/ui-organization';
import { NGXLogger } from 'ngx-logger';
@ -171,38 +168,106 @@ export class Effects {
)
),
switchMap(([req, loginResInfo]) => {
return this.organizationService
.getDeptUser({
divCd: 'INT_SRCH',
companyCode: req.companyCode,
search: req.search,
searchRange: DeptSearchType.All,
senderCompanyCode: loginResInfo.companyCode,
senderEmployeeType: loginResInfo.userInfo.employeeType
})
.pipe(
map(datas => {
const userInfos: UserInfoSS[] = datas.userInfos;
this.store.dispatch(
integrateSearchDeptUserSuccess({
userInfos
})
);
const pageListCount = 180;
const pageCurrent = !!req.pageCurrent ? req.pageCurrent : 1;
const request = {
divCd: 'INT_SRCH',
companyCode: req.companyCode,
search: req.search,
searchRange: DeptSearchType.All,
senderCompanyCode: loginResInfo.companyCode,
senderEmployeeType: loginResInfo.userInfo.employeeType,
pageListCount,
pageCurrent
} as DeptUserRequest;
// 검색 결과에 따른 프레즌스 조회.
const userSeqList: number[] = [];
userInfos.map(user => userSeqList.push(user.seq));
if (userSeqList.length > 0) {
this.store.dispatch(
StatusStore.bulkInfo({
divCd: 'inttrSrch',
userSeqs: userSeqList
})
);
}
}),
catchError(error => of(integrateSearchDeptUserFailure({ error })))
);
let mergedUserList: UserInfoSS[] = !!req.userList ? req.userList : [];
const userInfos: UserInfoSS[] = [];
return this.queryProtocolService.deptUser(request).pipe(
map(res => {
switch (res.SSVC_TYPE) {
case SSVC_TYPE_QUERY_DEPT_USER_DATA:
userInfos.push(...(res as DeptUserData).userInfos);
break;
case SSVC_TYPE_QUERY_DEPT_USER_RES:
if (!!userInfos && userInfos.length > 0) {
mergedUserList = [...mergedUserList, ...userInfos];
}
// 검색 결과에 따른 프레즌스 조회.
const userSeqList: number[] = [];
userInfos.map(user => userSeqList.push(user.seq));
if (userSeqList.length > 0) {
this.store.dispatch(
StatusStore.bulkInfo({
divCd: 'inttrSrch',
userSeqs: userSeqList
})
);
}
// 재귀 할지 판단.
if (!!userInfos && userInfos.length >= pageListCount) {
// 추가 조회.
this.store.dispatch(
integrateSearchDeptUser({
...req,
pageCurrent: pageCurrent + 1,
userList: mergedUserList
})
);
} else {
mergedUserList.sort((a, b) =>
a.order < b.order
? -1
: a.order > b.order
? 1
: a.name < b.name
? -1
: a.name > b.name
? 1
: 0
);
// 최종 조회건.
this.store.dispatch(
integrateSearchDeptUserSuccess({
userInfos: mergedUserList
})
);
}
break;
}
}),
catchError(error => of(integrateSearchDeptUserFailure({ error })))
);
// return this.organizationService
// .getDeptUser(request)
// .pipe(
// map(datas => {
// const userInfos: UserInfoSS[] = datas.userInfos;
// this.store.dispatch(
// integrateSearchDeptUserSuccess({
// userInfos
// })
// );
// // 검색 결과에 따른 프레즌스 조회.
// const userSeqList: number[] = [];
// userInfos.map(user => userSeqList.push(user.seq));
// if (userSeqList.length > 0) {
// this.store.dispatch(
// StatusStore.bulkInfo({
// divCd: 'inttrSrch',
// userSeqs: userSeqList
// })
// );
// }
// }),
// catchError(error => of(integrateSearchDeptUserFailure({ error })))
// );
})
);
},
@ -222,38 +287,80 @@ export class Effects {
)
),
switchMap(([req, loginResInfo]) => {
return this.organizationService
.getDeptUser({
divCd: 'ORG_SRCH',
companyCode: req.companyCode,
search: req.search,
searchRange: DeptSearchType.All,
senderCompanyCode: loginResInfo.companyCode,
senderEmployeeType: loginResInfo.userInfo.employeeType
})
.pipe(
map(datas => {
const userInfos: UserInfoSS[] = datas.userInfos;
this.store.dispatch(
searchDeptUserSuccess({
userInfos
})
);
const pageListCount = 180;
const pageCurrent = !!req.pageCurrent ? req.pageCurrent : 1;
const request = {
divCd: 'ORG_SRCH',
companyCode: req.companyCode,
search: req.search,
searchRange: DeptSearchType.All,
senderCompanyCode: loginResInfo.companyCode,
senderEmployeeType: loginResInfo.userInfo.employeeType,
pageListCount,
pageCurrent
} as DeptUserRequest;
// 검색 결과에 따른 프레즌스 조회.
const userSeqList: number[] = [];
userInfos.map(user => userSeqList.push(user.seq));
if (userSeqList.length > 0) {
this.store.dispatch(
StatusStore.bulkInfo({
divCd: 'orgtrSrch',
userSeqs: userSeqList
})
);
}
}),
catchError(error => of(deptUserFailure({ error })))
);
let mergedUserList: UserInfoSS[] = !!req.userList ? req.userList : [];
const userInfos: UserInfoSS[] = [];
return this.queryProtocolService.deptUser(request).pipe(
map(res => {
switch (res.SSVC_TYPE) {
case SSVC_TYPE_QUERY_DEPT_USER_DATA:
userInfos.push(...(res as DeptUserData).userInfos);
break;
case SSVC_TYPE_QUERY_DEPT_USER_RES:
if (!!userInfos && userInfos.length > 0) {
mergedUserList = [...mergedUserList, ...userInfos];
}
// 검색 결과에 따른 프레즌스 조회.
const userSeqList: number[] = [];
userInfos.map(user => userSeqList.push(user.seq));
if (userSeqList.length > 0) {
this.store.dispatch(
StatusStore.bulkInfo({
divCd: 'orgtrSrch',
userSeqs: userSeqList
})
);
}
// 재귀 할지 판단.
if (!!userInfos && userInfos.length >= pageListCount) {
// 추가 조회.
this.store.dispatch(
searchDeptUser({
...req,
pageCurrent: pageCurrent + 1,
userList: mergedUserList
})
);
} else {
mergedUserList.sort((a, b) =>
a.order < b.order
? -1
: a.order > b.order
? 1
: a.name < b.name
? -1
: a.name > b.name
? 1
: 0
);
// 최종 조회건.
this.store.dispatch(
searchDeptUserSuccess({
userInfos: mergedUserList
})
);
}
break;
}
}),
catchError(error => of(deptUserFailure({ error })))
);
})
);
},

View File

@ -1,11 +1,13 @@
<perfect-scrollbar
class="scrollbar"
*ngIf="!!sortedData && 0 < sortedData.length"
<cdk-virtual-scroll-viewport
perfectScrollbar
tvsItemSize="53"
headerHeight="56"
style="height: 100%;"
>
<table
mat-table
matSort
[dataSource]="sortedData"
[dataSource]="dataSource"
(matSortChange)="sortData($event)"
>
<ng-container matColumnDef="profileImage">
@ -151,7 +153,7 @@
</div>
</td>
</ng-container>
<ng-container matColumnDef="checkable" stickyEnd>
<ng-container matColumnDef="checkable">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox
#checkbox
@ -175,7 +177,7 @@
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</perfect-scrollbar>
</cdk-virtual-scroll-viewport>
<div
class="no-search-result"
fxFlexFill

View File

@ -18,6 +18,7 @@ import {
import { Sort } from '@angular/material/sort';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { Observable, Subscription } from 'rxjs';
import { TableVirtualScrollDataSource } from 'ng-table-virtual-scroll';
@Component({
selector: 'ucap-organization-detail-table',
@ -29,6 +30,7 @@ export class DetailTableComponent implements OnInit, OnDestroy {
set userInfoListIn(userInfo: UserInfoSS[]) {
this.departmentUserInfoList = userInfo;
this.sortedData = userInfo;
this.dataSource.data = !!userInfo ? userInfo : [];
}
@Input()
loginRes: LoginResponse;
@ -60,6 +62,7 @@ export class DetailTableComponent implements OnInit, OnDestroy {
departmentUserInfoList: UserInfoSS[];
sortedData: UserInfoSS[] = [];
dataSource = new TableVirtualScrollDataSource<UserInfoSS>([]);
PresenceType = PresenceType;
displayedColumns: string[] = [
@ -227,6 +230,7 @@ export class DetailTableComponent implements OnInit, OnDestroy {
return 0;
}
});
this.dataSource.data = this.sortedData;
}
compare(a: number | string, b: number | string, isAsc: boolean) {
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);

View File

@ -16,6 +16,7 @@ import { MatTreeModule } from '@angular/material/tree';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { VirtualScrollerModule } from 'ngx-virtual-scroller';
import { TableVirtualScrollModule } from 'ng-table-virtual-scroll';
import { TranslateModule } from '@ngx-translate/core';
import { UCapUiModule } from '@ucap-webmessenger/ui';
@ -56,6 +57,7 @@ const DIRECTIVES = [];
PerfectScrollbarModule,
VirtualScrollerModule,
TableVirtualScrollModule,
UCapUiModule
],