1. 조직도 검색시 200건 이상 조회 가능하도록 수정,
2. 조직도 테이블 virture scroll 적용.
This commit is contained in:
parent
e3b26549cc
commit
7eb7d85da9
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "ucap-webmessenger",
|
"name": "ucap-webmessenger",
|
||||||
"version": "1.0.16",
|
"version": "1.0.0",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "LG CNS",
|
"name": "LG CNS",
|
||||||
"email": "lgucap@lgcns.com"
|
"email": "lgucap@lgcns.com"
|
||||||
|
@ -137,6 +137,7 @@
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"moment-timezone": "^0.5.27",
|
"moment-timezone": "^0.5.27",
|
||||||
"ng-packagr": "^5.7.1",
|
"ng-packagr": "^5.7.1",
|
||||||
|
"ng-table-virtual-scroll": "^1.3.1",
|
||||||
"ngrx-store-freeze": "^0.2.4",
|
"ngrx-store-freeze": "^0.2.4",
|
||||||
"ngx-logger": "^4.0.8",
|
"ngx-logger": "^4.0.8",
|
||||||
"ngx-perfect-scrollbar": "^8.0.0",
|
"ngx-perfect-scrollbar": "^8.0.0",
|
||||||
|
|
|
@ -95,6 +95,8 @@ export const searchDeptUser = createAction(
|
||||||
props<{
|
props<{
|
||||||
companyCode: string;
|
companyCode: string;
|
||||||
search: string;
|
search: string;
|
||||||
|
pageCurrent?: number;
|
||||||
|
userList?: UserInfoSS[];
|
||||||
}>()
|
}>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -119,6 +121,8 @@ export const integrateSearchDeptUser = createAction(
|
||||||
props<{
|
props<{
|
||||||
companyCode: string;
|
companyCode: string;
|
||||||
search: string;
|
search: string;
|
||||||
|
pageCurrent?: number;
|
||||||
|
userList?: UserInfoSS[];
|
||||||
}>()
|
}>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,7 @@ import {
|
||||||
map,
|
map,
|
||||||
tap,
|
tap,
|
||||||
switchMap,
|
switchMap,
|
||||||
withLatestFrom,
|
withLatestFrom
|
||||||
take
|
|
||||||
} from 'rxjs/operators';
|
} from 'rxjs/operators';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -28,7 +27,6 @@ import {
|
||||||
selectedDeptSuccess,
|
selectedDeptSuccess,
|
||||||
searchDeptUser,
|
searchDeptUser,
|
||||||
searchDeptUserSuccess,
|
searchDeptUserSuccess,
|
||||||
clearSearchDeptUser,
|
|
||||||
integrateSearchDeptUser,
|
integrateSearchDeptUser,
|
||||||
integrateSearchDeptUserSuccess,
|
integrateSearchDeptUserSuccess,
|
||||||
integrateSearchDeptUserFailure,
|
integrateSearchDeptUserFailure,
|
||||||
|
@ -45,13 +43,12 @@ import {
|
||||||
SSVC_TYPE_QUERY_DEPT_USER_DATA,
|
SSVC_TYPE_QUERY_DEPT_USER_DATA,
|
||||||
DeptUserData,
|
DeptUserData,
|
||||||
SSVC_TYPE_QUERY_DEPT_USER_RES,
|
SSVC_TYPE_QUERY_DEPT_USER_RES,
|
||||||
DeptUserResponse,
|
DeptSearchType,
|
||||||
DeptSearchType
|
DeptUserRequest
|
||||||
} from '@ucap-webmessenger/protocol-query';
|
} from '@ucap-webmessenger/protocol-query';
|
||||||
|
|
||||||
import { Store, select } from '@ngrx/store';
|
import { Store, select } from '@ngrx/store';
|
||||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||||
import { KEY_LOGIN_RES_INFO } from '@app/types';
|
|
||||||
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
||||||
import { OrganizationService } from '@ucap-webmessenger/ui-organization';
|
import { OrganizationService } from '@ucap-webmessenger/ui-organization';
|
||||||
import { NGXLogger } from 'ngx-logger';
|
import { NGXLogger } from 'ngx-logger';
|
||||||
|
@ -171,38 +168,106 @@ export class Effects {
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
switchMap(([req, loginResInfo]) => {
|
switchMap(([req, loginResInfo]) => {
|
||||||
return this.organizationService
|
const pageListCount = 180;
|
||||||
.getDeptUser({
|
const pageCurrent = !!req.pageCurrent ? req.pageCurrent : 1;
|
||||||
divCd: 'INT_SRCH',
|
const request = {
|
||||||
companyCode: req.companyCode,
|
divCd: 'INT_SRCH',
|
||||||
search: req.search,
|
companyCode: req.companyCode,
|
||||||
searchRange: DeptSearchType.All,
|
search: req.search,
|
||||||
senderCompanyCode: loginResInfo.companyCode,
|
searchRange: DeptSearchType.All,
|
||||||
senderEmployeeType: loginResInfo.userInfo.employeeType
|
senderCompanyCode: loginResInfo.companyCode,
|
||||||
})
|
senderEmployeeType: loginResInfo.userInfo.employeeType,
|
||||||
.pipe(
|
pageListCount,
|
||||||
map(datas => {
|
pageCurrent
|
||||||
const userInfos: UserInfoSS[] = datas.userInfos;
|
} as DeptUserRequest;
|
||||||
this.store.dispatch(
|
|
||||||
integrateSearchDeptUserSuccess({
|
|
||||||
userInfos
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// 검색 결과에 따른 프레즌스 조회.
|
let mergedUserList: UserInfoSS[] = !!req.userList ? req.userList : [];
|
||||||
const userSeqList: number[] = [];
|
|
||||||
userInfos.map(user => userSeqList.push(user.seq));
|
const userInfos: UserInfoSS[] = [];
|
||||||
if (userSeqList.length > 0) {
|
return this.queryProtocolService.deptUser(request).pipe(
|
||||||
this.store.dispatch(
|
map(res => {
|
||||||
StatusStore.bulkInfo({
|
switch (res.SSVC_TYPE) {
|
||||||
divCd: 'inttrSrch',
|
case SSVC_TYPE_QUERY_DEPT_USER_DATA:
|
||||||
userSeqs: userSeqList
|
userInfos.push(...(res as DeptUserData).userInfos);
|
||||||
})
|
break;
|
||||||
);
|
case SSVC_TYPE_QUERY_DEPT_USER_RES:
|
||||||
}
|
if (!!userInfos && userInfos.length > 0) {
|
||||||
}),
|
mergedUserList = [...mergedUserList, ...userInfos];
|
||||||
catchError(error => of(integrateSearchDeptUserFailure({ error })))
|
}
|
||||||
);
|
|
||||||
|
// 검색 결과에 따른 프레즌스 조회.
|
||||||
|
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]) => {
|
switchMap(([req, loginResInfo]) => {
|
||||||
return this.organizationService
|
const pageListCount = 180;
|
||||||
.getDeptUser({
|
const pageCurrent = !!req.pageCurrent ? req.pageCurrent : 1;
|
||||||
divCd: 'ORG_SRCH',
|
const request = {
|
||||||
companyCode: req.companyCode,
|
divCd: 'ORG_SRCH',
|
||||||
search: req.search,
|
companyCode: req.companyCode,
|
||||||
searchRange: DeptSearchType.All,
|
search: req.search,
|
||||||
senderCompanyCode: loginResInfo.companyCode,
|
searchRange: DeptSearchType.All,
|
||||||
senderEmployeeType: loginResInfo.userInfo.employeeType
|
senderCompanyCode: loginResInfo.companyCode,
|
||||||
})
|
senderEmployeeType: loginResInfo.userInfo.employeeType,
|
||||||
.pipe(
|
pageListCount,
|
||||||
map(datas => {
|
pageCurrent
|
||||||
const userInfos: UserInfoSS[] = datas.userInfos;
|
} as DeptUserRequest;
|
||||||
this.store.dispatch(
|
|
||||||
searchDeptUserSuccess({
|
|
||||||
userInfos
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
// 검색 결과에 따른 프레즌스 조회.
|
let mergedUserList: UserInfoSS[] = !!req.userList ? req.userList : [];
|
||||||
const userSeqList: number[] = [];
|
|
||||||
userInfos.map(user => userSeqList.push(user.seq));
|
const userInfos: UserInfoSS[] = [];
|
||||||
if (userSeqList.length > 0) {
|
return this.queryProtocolService.deptUser(request).pipe(
|
||||||
this.store.dispatch(
|
map(res => {
|
||||||
StatusStore.bulkInfo({
|
switch (res.SSVC_TYPE) {
|
||||||
divCd: 'orgtrSrch',
|
case SSVC_TYPE_QUERY_DEPT_USER_DATA:
|
||||||
userSeqs: userSeqList
|
userInfos.push(...(res as DeptUserData).userInfos);
|
||||||
})
|
break;
|
||||||
);
|
case SSVC_TYPE_QUERY_DEPT_USER_RES:
|
||||||
}
|
if (!!userInfos && userInfos.length > 0) {
|
||||||
}),
|
mergedUserList = [...mergedUserList, ...userInfos];
|
||||||
catchError(error => of(deptUserFailure({ error })))
|
}
|
||||||
);
|
|
||||||
|
// 검색 결과에 따른 프레즌스 조회.
|
||||||
|
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 })))
|
||||||
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
<perfect-scrollbar
|
<cdk-virtual-scroll-viewport
|
||||||
class="scrollbar"
|
perfectScrollbar
|
||||||
*ngIf="!!sortedData && 0 < sortedData.length"
|
tvsItemSize="53"
|
||||||
|
headerHeight="56"
|
||||||
|
style="height: 100%;"
|
||||||
>
|
>
|
||||||
<table
|
<table
|
||||||
mat-table
|
mat-table
|
||||||
matSort
|
matSort
|
||||||
[dataSource]="sortedData"
|
[dataSource]="dataSource"
|
||||||
(matSortChange)="sortData($event)"
|
(matSortChange)="sortData($event)"
|
||||||
>
|
>
|
||||||
<ng-container matColumnDef="profileImage">
|
<ng-container matColumnDef="profileImage">
|
||||||
|
@ -151,7 +153,7 @@
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container matColumnDef="checkable" stickyEnd>
|
<ng-container matColumnDef="checkable">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
<mat-checkbox
|
<mat-checkbox
|
||||||
#checkbox
|
#checkbox
|
||||||
|
@ -175,7 +177,7 @@
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||||
</table>
|
</table>
|
||||||
</perfect-scrollbar>
|
</cdk-virtual-scroll-viewport>
|
||||||
<div
|
<div
|
||||||
class="no-search-result"
|
class="no-search-result"
|
||||||
fxFlexFill
|
fxFlexFill
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
import { Sort } from '@angular/material/sort';
|
import { Sort } from '@angular/material/sort';
|
||||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||||
import { Observable, Subscription } from 'rxjs';
|
import { Observable, Subscription } from 'rxjs';
|
||||||
|
import { TableVirtualScrollDataSource } from 'ng-table-virtual-scroll';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ucap-organization-detail-table',
|
selector: 'ucap-organization-detail-table',
|
||||||
|
@ -29,6 +30,7 @@ export class DetailTableComponent implements OnInit, OnDestroy {
|
||||||
set userInfoListIn(userInfo: UserInfoSS[]) {
|
set userInfoListIn(userInfo: UserInfoSS[]) {
|
||||||
this.departmentUserInfoList = userInfo;
|
this.departmentUserInfoList = userInfo;
|
||||||
this.sortedData = userInfo;
|
this.sortedData = userInfo;
|
||||||
|
this.dataSource.data = !!userInfo ? userInfo : [];
|
||||||
}
|
}
|
||||||
@Input()
|
@Input()
|
||||||
loginRes: LoginResponse;
|
loginRes: LoginResponse;
|
||||||
|
@ -60,6 +62,7 @@ export class DetailTableComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
departmentUserInfoList: UserInfoSS[];
|
departmentUserInfoList: UserInfoSS[];
|
||||||
sortedData: UserInfoSS[] = [];
|
sortedData: UserInfoSS[] = [];
|
||||||
|
dataSource = new TableVirtualScrollDataSource<UserInfoSS>([]);
|
||||||
|
|
||||||
PresenceType = PresenceType;
|
PresenceType = PresenceType;
|
||||||
displayedColumns: string[] = [
|
displayedColumns: string[] = [
|
||||||
|
@ -227,6 +230,7 @@ export class DetailTableComponent implements OnInit, OnDestroy {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.dataSource.data = this.sortedData;
|
||||||
}
|
}
|
||||||
compare(a: number | string, b: number | string, isAsc: boolean) {
|
compare(a: number | string, b: number | string, isAsc: boolean) {
|
||||||
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { MatTreeModule } from '@angular/material/tree';
|
||||||
|
|
||||||
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
|
||||||
import { VirtualScrollerModule } from 'ngx-virtual-scroller';
|
import { VirtualScrollerModule } from 'ngx-virtual-scroller';
|
||||||
|
import { TableVirtualScrollModule } from 'ng-table-virtual-scroll';
|
||||||
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { UCapUiModule } from '@ucap-webmessenger/ui';
|
import { UCapUiModule } from '@ucap-webmessenger/ui';
|
||||||
|
@ -56,6 +57,7 @@ const DIRECTIVES = [];
|
||||||
|
|
||||||
PerfectScrollbarModule,
|
PerfectScrollbarModule,
|
||||||
VirtualScrollerModule,
|
VirtualScrollerModule,
|
||||||
|
TableVirtualScrollModule,
|
||||||
|
|
||||||
UCapUiModule
|
UCapUiModule
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue
Block a user