From b314a72badcf464ceb87f94b9fb467fae0be0955 Mon Sep 17 00:00:00 2001 From: richard-loafle <44828666+richard-loafle@users.noreply.github.com> Date: Tue, 4 Feb 2020 11:27:48 +0900 Subject: [PATCH] refactoring of organization --- .../src/app/app.module.ts | 2 + .../left-sidenav/organization.component.ts | 242 +++++++++++------- .../src/app/store/messenger/query/actions.ts | 19 +- .../src/app/store/messenger/query/effects.ts | 30 +-- .../src/app/store/messenger/query/reducers.ts | 32 +-- .../src/app/store/messenger/query/state.ts | 22 +- .../src/lib/components/tree.component.ts | 6 +- .../lib/services/organization.service.spec.ts | 12 + .../src/lib/services/organization.service.ts | 64 +++++ .../src/lib/ucap-ui-organization.module.ts | 11 +- .../src/public-api.ts | 2 + 11 files changed, 256 insertions(+), 186 deletions(-) create mode 100644 projects/ucap-webmessenger-ui-organization/src/lib/services/organization.service.spec.ts create mode 100644 projects/ucap-webmessenger-ui-organization/src/lib/services/organization.service.ts diff --git a/projects/ucap-webmessenger-app/src/app/app.module.ts b/projects/ucap-webmessenger-app/src/app/app.module.ts index 223220c2..9c356ee8 100644 --- a/projects/ucap-webmessenger-app/src/app/app.module.ts +++ b/projects/ucap-webmessenger-app/src/app/app.module.ts @@ -32,6 +32,7 @@ import { UCapSyncProtocolModule } from '@ucap-webmessenger/protocol-sync'; import { UCapUiModule } from '@ucap-webmessenger/ui'; import { UCapUiAccountModule } from '@ucap-webmessenger/ui-account'; +import { UCapUiOrganizationModule } from '@ucap-webmessenger/ui-organization'; import { UCapDaesangModule } from '@ucap-webmessenger/daesang'; @@ -86,6 +87,7 @@ import { environment } from '../environments/environment'; UCapUiModule.forRoot(), UCapUiAccountModule.forRoot(), + UCapUiOrganizationModule.forRoot(), UCapWebStorageModule.forRoot(), diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/organization.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/organization.component.ts index 3dc8047a..2442c79a 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/organization.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/organization.component.ts @@ -67,6 +67,7 @@ import { import { TranslateService } from '@ngx-translate/core'; import { StringFormatterPhonePipe } from 'projects/ucap-webmessenger-ui/src/lib/pipes/string.pipe'; import { VirtualScrollerComponent } from 'ngx-virtual-scroller'; +import { OrganizationService } from '@ucap-webmessenger/ui-organization'; @Component({ selector: 'app-layout-chat-left-sidenav-organization', @@ -132,17 +133,17 @@ export class OrganizationComponent companyCode: string; departmentInfoList$: Observable; - selectedDepartmentUserInfoList: UserInfoSS[] = []; - selectedDepartmentUserInfoListSubscription: Subscription; - selectedDepartmentStatus$: Observable; + selectedDepartmentUserInfoList: UserInfoSS[]; selectedDepartmentProcessing = false; - selectedDepartmentProcessingSubscription: Subscription; selectedDepartmentName: { name: string; nameEn: string; nameCn: string; }; + myDepartmentUserInfoList: UserInfoSS[] = []; + myDepartmentUserInfoListSubscription: Subscription; + loginInfo: LoginInfo; loginRes: LoginResponse; sessionVerinfo: VersionInfo2Response; @@ -159,6 +160,7 @@ export class OrganizationComponent private store: Store, private sessionStorageService: SessionStorageService, private queryProtocolService: QueryProtocolService, + private organizationService: OrganizationService, private dialogService: DialogService, private translateService: TranslateService, private changeDetectorRef: ChangeDetectorRef, @@ -184,41 +186,25 @@ export class OrganizationComponent select(AppStore.MessengerSelector.QuerySelector.departmentInfoList) ); - this.selectedDepartmentProcessingSubscription = this.store + this.myDepartmentUserInfoListSubscription = this.store .pipe( - delay(0), select( - AppStore.MessengerSelector.QuerySelector.selectedDepartmentProcessing - ), - tap(processing => { - this.selectedDepartmentProcessing = processing; - }) + AppStore.MessengerSelector.QuerySelector.myDepartmentUserInfoList + ) ) - .subscribe(); - - this.selectedDepartmentUserInfoListSubscription = this.store - .pipe( - select( - AppStore.MessengerSelector.QuerySelector - .selectedDepartmentUserInfoList - ), - map(list => { + .subscribe(list => { + this.myDepartmentUserInfoList = list; + if (!this.selectedDepartmentUserInfoList) { this.selectedDepartmentUserInfoList = list; - }), - tap(() => { - if (!!this.vsDeptUser) { - this.vsDeptUser.scrollToIndex(0, true, 0, 0); - } - if (!!this.psDirectiveRef) { - this.psDirectiveRef.update(); - } - }) - ) - .subscribe(); + } - this.selectedDepartmentStatus$ = this.store.pipe( - select(AppStore.MessengerSelector.QuerySelector.selectedDepartmentStatus) - ); + if (!!this.vsDeptUser) { + this.vsDeptUser.scrollToIndex(0, true, 0, 0); + } + if (!!this.psDirectiveRef) { + this.psDirectiveRef.update(); + } + }); this.store .pipe( @@ -226,7 +212,7 @@ export class OrganizationComponent select(AppStore.AccountSelector.AuthenticationSelector.loginRes), map(loginRes => { this.store.dispatch( - QueryStore.deptUser({ + QueryStore.myDeptUser({ divCd: 'ORG', companyCode: this.loginInfo.companyCode, seq: loginRes.departmentCode, @@ -263,11 +249,8 @@ export class OrganizationComponent } ngOnDestroy(): void { - if (!!this.selectedDepartmentUserInfoListSubscription) { - this.selectedDepartmentUserInfoListSubscription.unsubscribe(); - } - if (!!this.selectedDepartmentProcessingSubscription) { - this.selectedDepartmentProcessingSubscription.unsubscribe(); + if (!!this.myDepartmentUserInfoListSubscription) { + this.myDepartmentUserInfoListSubscription.unsubscribe(); } } @@ -279,9 +262,9 @@ export class OrganizationComponent if (params.searchWord.trim().length > 1) { this.isShowSearch = true; this.selectedDepartmentProcessing = true; - const searchUserInfos: UserInfoSS[] = []; - this.queryProtocolService - .deptUser({ + + this.organizationService + .getDeptUser({ divCd: 'GRP', companyCode: params.companyCode, searchRange: DeptSearchType.All, @@ -289,40 +272,71 @@ export class OrganizationComponent senderCompanyCode: params.companyCode, senderEmployeeType: this.loginRes.userInfo.employeeType }) - .pipe( - map(res => { - switch (res.SSVC_TYPE) { - case SSVC_TYPE_QUERY_DEPT_USER_DATA: - const userInfos = (res as DeptUserData).userInfos; - // searchUserInfos.push( - // ...userInfos.filter( - // userInfo => userInfo.seq !== this.loginRes.userSeq - // ) - // ); - searchUserInfos.push(...userInfos); - break; - case SSVC_TYPE_QUERY_DEPT_USER_RES: - { - // 검색 결과 처리. - this.searchUserInfos = searchUserInfos; - this.selectedDepartmentProcessing = false; - - if (!!this.vsDeptSearchUser) { - this.vsDeptSearchUser.scrollToIndex(0); - } - if (!!this.psDirectiveRef) { - this.psDirectiveRef.update(); - } - } - break; - } - }), - catchError(error => { + .pipe(take(1)) + .subscribe( + datas => { + this.searchUserInfos = datas.userInfos; this.selectedDepartmentProcessing = false; - return of(this.logger.error(error)); - }) - ) - .subscribe(); + + if (!!this.vsDeptSearchUser) { + this.vsDeptSearchUser.scrollToIndex(0); + } + if (!!this.psDirectiveRef) { + this.psDirectiveRef.update(); + } + }, + error => { + this.logger.error(error); + }, + () => { + this.selectedDepartmentProcessing = false; + } + ); + + // const searchUserInfos: UserInfoSS[] = []; + // this.queryProtocolService + // .deptUser({ + // divCd: 'GRP', + // companyCode: params.companyCode, + // searchRange: DeptSearchType.All, + // search: params.searchWord, + // senderCompanyCode: params.companyCode, + // senderEmployeeType: this.loginRes.userInfo.employeeType + // }) + // .pipe( + // map(res => { + // switch (res.SSVC_TYPE) { + // case SSVC_TYPE_QUERY_DEPT_USER_DATA: + // const userInfos = (res as DeptUserData).userInfos; + // // searchUserInfos.push( + // // ...userInfos.filter( + // // userInfo => userInfo.seq !== this.loginRes.userSeq + // // ) + // // ); + // searchUserInfos.push(...userInfos); + // break; + // case SSVC_TYPE_QUERY_DEPT_USER_RES: + // { + // // 검색 결과 처리. + // this.searchUserInfos = searchUserInfos; + // this.selectedDepartmentProcessing = false; + + // if (!!this.vsDeptSearchUser) { + // this.vsDeptSearchUser.scrollToIndex(0); + // } + // if (!!this.psDirectiveRef) { + // this.psDirectiveRef.update(); + // } + // } + // break; + // } + // }), + // catchError(error => { + // this.selectedDepartmentProcessing = false; + // return of(this.logger.error(error)); + // }) + // ) + // .subscribe(); } } /** 검색 취소 */ @@ -334,28 +348,68 @@ export class OrganizationComponent onSelectedOrganization(deptInfo: DeptInfo) { this.onClickCancel(); + this.selectedDepartmentName = deptInfo; + this.selectedDepartmentProcessing = true; this.store .pipe( take(1), - select(AppStore.AccountSelector.AuthenticationSelector.loginRes), - map(loginRes => { - this.store.dispatch( - QueryStore.deptUser({ - divCd: 'ORG', - companyCode: this.loginInfo.companyCode, - seq: deptInfo.seq, - search: '', - searchRange: DeptSearchType.All, - senderCompanyCode: this.loginInfo.companyCode, - senderEmployeeType: loginRes.userInfo.employeeType - }) - ); - }), - map(() => { - this.selectedDepartmentName = deptInfo; - }) + select(AppStore.AccountSelector.AuthenticationSelector.loginRes) ) - .subscribe(); + .subscribe(loginRes => { + this.organizationService + .getDeptUser({ + divCd: 'ORG', + companyCode: this.loginInfo.companyCode, + seq: deptInfo.seq, + search: '', + searchRange: DeptSearchType.All, + senderCompanyCode: this.loginInfo.companyCode, + senderEmployeeType: loginRes.userInfo.employeeType + }) + .pipe(take(1)) + .subscribe( + datas => { + // this.logger.debug('onSelectedOrganization', datas); + this.selectedDepartmentUserInfoList = datas.userInfos; + + if (!!this.vsDeptUser) { + this.vsDeptUser.scrollToIndex(0, true, 0, 0); + } + if (!!this.psDirectiveRef) { + this.psDirectiveRef.update(); + } + }, + error => { + this.logger.error(error); + }, + () => { + this.selectedDepartmentProcessing = false; + } + ); + }); + + // this.store + // .pipe( + // take(1), + // select(AppStore.AccountSelector.AuthenticationSelector.loginRes), + // map(loginRes => { + // this.store.dispatch( + // QueryStore.deptUser({ + // divCd: 'ORG', + // companyCode: this.loginInfo.companyCode, + // seq: deptInfo.seq, + // search: '', + // searchRange: DeptSearchType.All, + // senderCompanyCode: this.loginInfo.companyCode, + // senderEmployeeType: loginRes.userInfo.employeeType + // }) + // ); + // }), + // map(() => { + // this.selectedDepartmentName = deptInfo; + // }) + // ) + // .subscribe(); } /** 전체 체크여부 */ diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/query/actions.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/query/actions.ts index a6613ed0..ccf61a5b 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/query/actions.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/query/actions.ts @@ -39,22 +39,17 @@ export const deptFailure = createAction( '[Messenger::Query] Dept Failure', props<{ error: any }>() ); -export const deptUser = createAction( - '[Messenger::Query] Dept User', +export const myDeptUser = createAction( + '[Messenger::Query] My Dept User', props() ); -export const deptUserSuccess = createAction( - '[Messenger::Query] Dept User Success', - props<{ userInfos: UserInfoSS[]; res: DeptUserResponse }>() -); - -export const deptUserFailure = createAction( - '[Messenger::Query] Dept User Failure', - props<{ error: any }>() -); - export const myDeptUserSuccess = createAction( '[Messenger::Query] My Dept User Success', props<{ userInfos: UserInfoSS[] }>() ); + +export const myDeptUserFailure = createAction( + '[Messenger::Query] My Dept User Failure', + props<{ error: any }>() +); diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/query/effects.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/query/effects.ts index 0e7d922a..46c3ac06 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/query/effects.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/query/effects.ts @@ -9,10 +9,9 @@ import { dept, deptSuccess, deptFailure, - deptUser, - deptUserSuccess, - deptUserFailure, - myDeptUserSuccess + myDeptUserSuccess, + myDeptUser, + myDeptUserFailure } from './actions'; import { @@ -71,12 +70,12 @@ export class Effects { { dispatch: false } ); - deptUser$ = createEffect( + myDeptUser$ = createEffect( () => { let userInfos: UserInfoSS[]; return this.actions$.pipe( - ofType(deptUser), + ofType(myDeptUser), tap(() => { userInfos = []; }), @@ -101,27 +100,14 @@ export class Effects { ); this.store.dispatch( - deptUserSuccess({ - userInfos, - res: res as DeptUserResponse + myDeptUserSuccess({ + userInfos }) ); - - const loginResInfo: LoginResponse = this.sessionStorageService.get< - LoginResponse - >(KEY_LOGIN_RES_INFO); - - if (req.seq === loginResInfo.departmentCode) { - this.store.dispatch( - myDeptUserSuccess({ - userInfos - }) - ); - } break; } }), - catchError(error => of(deptUserFailure({ error }))) + catchError(error => of(myDeptUserFailure({ error }))) ); }) ); diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/query/reducers.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/query/reducers.ts index 8238fd93..72f9c4e2 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/query/reducers.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/query/reducers.ts @@ -1,13 +1,6 @@ import { createReducer, on } from '@ngrx/store'; import { initialState } from './state'; -import { - authSuccess, - deptSuccess, - deptUserSuccess, - deptUser, - deptUserFailure, - myDeptUserSuccess -} from './actions'; +import { authSuccess, deptSuccess, myDeptUserSuccess } from './actions'; import * as AuthenticationStore from '@app/store/account/authentication'; @@ -27,29 +20,6 @@ export const reducer = createReducer( }; }), - on(deptUser, (state, action) => { - return { - ...state, - selectedDepartmentProcessing: true - }; - }), - - on(deptUserSuccess, (state, action) => { - return { - ...state, - selectedDepartmentUserInfoList: action.userInfos, - selectedDepartmentStatus: action.res, - selectedDepartmentProcessing: false - }; - }), - - on(deptUserFailure, (state, action) => { - return { - ...state, - selectedDepartmentProcessing: false - }; - }), - on(myDeptUserSuccess, (state, action) => { return { ...state, diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/query/state.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/query/state.ts index 4b1cbcec..8f93b6f0 100644 --- a/projects/ucap-webmessenger-app/src/app/store/messenger/query/state.ts +++ b/projects/ucap-webmessenger-app/src/app/store/messenger/query/state.ts @@ -2,8 +2,7 @@ import { Selector, createSelector } from '@ngrx/store'; import { AuthResponse, DeptInfo, - UserInfoSS, - DeptUserResponse + UserInfoSS } from '@ucap-webmessenger/protocol-query'; export interface State { @@ -11,19 +10,12 @@ export interface State { departmentInfoList: DeptInfo[] | null; - selectedDepartmentUserInfoList: UserInfoSS[] | null; - selectedDepartmentStatus: DeptUserResponse | null; - selectedDepartmentProcessing: boolean; - myDepartmentUserInfoList: UserInfoSS[] | null; } export const initialState: State = { auth: null, departmentInfoList: null, - selectedDepartmentUserInfoList: null, - selectedDepartmentStatus: null, - selectedDepartmentProcessing: false, myDepartmentUserInfoList: null }; @@ -34,18 +26,6 @@ export function selectors(selector: Selector) { selector, (state: State) => state.departmentInfoList ), - selectedDepartmentUserInfoList: createSelector( - selector, - (state: State) => state.selectedDepartmentUserInfoList - ), - selectedDepartmentStatus: createSelector( - selector, - (state: State) => state.selectedDepartmentStatus - ), - selectedDepartmentProcessing: createSelector( - selector, - (state: State) => state.selectedDepartmentProcessing - ), myDepartmentUserInfoList: createSelector( selector, (state: State) => state.myDepartmentUserInfoList diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/tree.component.ts b/projects/ucap-webmessenger-ui-organization/src/lib/components/tree.component.ts index 04c4dafa..57cc3bf8 100644 --- a/projects/ucap-webmessenger-ui-organization/src/lib/components/tree.component.ts +++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/tree.component.ts @@ -54,9 +54,6 @@ interface FlatNode { ] }) export class TreeComponent implements OnInit, OnDestroy, AfterViewInit { - @Output() - selected = new EventEmitter(); - @Input() loginRes: LoginResponse; @@ -106,6 +103,9 @@ export class TreeComponent implements OnInit, OnDestroy, AfterViewInit { this.dataSource.data = rootNodeList; } + @Output() + selected = new EventEmitter(); + @ViewChild('cvsvOrganization', { static: false }) cvsvOrganization: CdkVirtualScrollViewport; diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/services/organization.service.spec.ts b/projects/ucap-webmessenger-ui-organization/src/lib/services/organization.service.spec.ts new file mode 100644 index 00000000..559d262b --- /dev/null +++ b/projects/ucap-webmessenger-ui-organization/src/lib/services/organization.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { OrganizationService } from './organization.service'; + +describe('UIOrganization::OrganizationService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: OrganizationService = TestBed.get(OrganizationService); + expect(service).toBeTruthy(); + }); +}); diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/services/organization.service.ts b/projects/ucap-webmessenger-ui-organization/src/lib/services/organization.service.ts new file mode 100644 index 00000000..2199d081 --- /dev/null +++ b/projects/ucap-webmessenger-ui-organization/src/lib/services/organization.service.ts @@ -0,0 +1,64 @@ +import { Injectable } from '@angular/core'; +import { + QueryProtocolService, + DeptUserRequest, + UserInfoSS, + DeptUserResponse, + SSVC_TYPE_QUERY_DEPT_USER_DATA, + DeptUserData, + SSVC_TYPE_QUERY_DEPT_USER_RES +} from '@ucap-webmessenger/protocol-query'; +import { Observable } from 'rxjs'; +import { map, tap } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class OrganizationService { + constructor(private queryProtocolService: QueryProtocolService) {} + + getDeptUser( + req: DeptUserRequest + ): Observable<{ userInfos: UserInfoSS[]; res: DeptUserResponse }> { + return new Observable<{ userInfos: UserInfoSS[]; res: DeptUserResponse }>( + subscriber => { + const userInfos: UserInfoSS[] = []; + + this.queryProtocolService + .deptUser(req) + .pipe() + .subscribe( + 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: + userInfos.sort((a, b) => + a.order < b.order + ? -1 + : a.order > b.order + ? 1 + : a.name < b.name + ? -1 + : a.name > b.name + ? 1 + : 0 + ); + + subscriber.next({ userInfos, res: res as DeptUserResponse }); + + break; + } + }, + error => { + subscriber.error(error); + }, + () => { + subscriber.complete(); + } + ); + } + ); + } +} diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/ucap-ui-organization.module.ts b/projects/ucap-webmessenger-ui-organization/src/lib/ucap-ui-organization.module.ts index b67ee813..40695659 100644 --- a/projects/ucap-webmessenger-ui-organization/src/lib/ucap-ui-organization.module.ts +++ b/projects/ucap-webmessenger-ui-organization/src/lib/ucap-ui-organization.module.ts @@ -15,14 +15,18 @@ import { MatSelectModule } from '@angular/material/select'; import { MatTreeModule } from '@angular/material/tree'; import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; +import { VirtualScrollerModule } from 'ngx-virtual-scroller'; + import { TranslateModule } from '@ngx-translate/core'; import { UCapUiModule } from '@ucap-webmessenger/ui'; import { TenantSearchComponent } from './components/tenant-search.component'; import { TreeComponent } from './components/tree.component'; +import { OrganizationService } from './services/organization.service'; const COMPONENTS = [TenantSearchComponent, TreeComponent]; -const SERVICES = []; +const SERVICES = [OrganizationService]; +const DIRECTIVES = []; @NgModule({ imports: [ @@ -42,11 +46,12 @@ const SERVICES = []; TranslateModule, PerfectScrollbarModule, + VirtualScrollerModule, UCapUiModule ], - exports: [...COMPONENTS], - declarations: [...COMPONENTS] + exports: [...COMPONENTS, ...DIRECTIVES], + declarations: [...COMPONENTS, ...DIRECTIVES] }) export class UCapUiOrganizationModule { public static forRoot(): ModuleWithProviders { diff --git a/projects/ucap-webmessenger-ui-organization/src/public-api.ts b/projects/ucap-webmessenger-ui-organization/src/public-api.ts index d0409ad6..f16cc2e0 100644 --- a/projects/ucap-webmessenger-ui-organization/src/public-api.ts +++ b/projects/ucap-webmessenger-ui-organization/src/public-api.ts @@ -4,4 +4,6 @@ export * from './lib/components/tenant-search.component'; export * from './lib/components/tree.component'; +export * from './lib/services/organization.service'; + export * from './lib/ucap-ui-organization.module';