refactoring of organization

This commit is contained in:
richard-loafle 2020-02-04 11:27:48 +09:00
parent af582b0c8e
commit b314a72bad
11 changed files with 256 additions and 186 deletions

View File

@ -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(),

View File

@ -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<DeptInfo[]>;
selectedDepartmentUserInfoList: UserInfoSS[] = [];
selectedDepartmentUserInfoListSubscription: Subscription;
selectedDepartmentStatus$: Observable<DeptUserResponse>;
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<any>,
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)
);
});
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,22 +272,10 @@ 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;
.pipe(take(1))
.subscribe(
datas => {
this.searchUserInfos = datas.userInfos;
this.selectedDepartmentProcessing = false;
if (!!this.vsDeptSearchUser) {
@ -313,16 +284,59 @@ export class OrganizationComponent
if (!!this.psDirectiveRef) {
this.psDirectiveRef.update();
}
}
break;
}
}),
catchError(error => {
},
error => {
this.logger.error(error);
},
() => {
this.selectedDepartmentProcessing = false;
return of(this.logger.error(error));
})
)
.subscribe();
}
);
// 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,13 +348,16 @@ 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({
select(AppStore.AccountSelector.AuthenticationSelector.loginRes)
)
.subscribe(loginRes => {
this.organizationService
.getDeptUser({
divCd: 'ORG',
companyCode: this.loginInfo.companyCode,
seq: deptInfo.seq,
@ -349,13 +366,50 @@ export class OrganizationComponent
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;
}
);
}),
map(() => {
this.selectedDepartmentName = deptInfo;
})
)
.subscribe();
});
// 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();
}
/** 전체 체크여부 */

View File

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

View File

@ -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 = [];
}),
@ -100,28 +99,15 @@ export class Effects {
: 0
);
this.store.dispatch(
deptUserSuccess({
userInfos,
res: res as DeptUserResponse
})
);
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 })))
);
})
);

View File

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

View File

@ -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<S>(selector: Selector<any, State>) {
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

View File

@ -54,9 +54,6 @@ interface FlatNode {
]
})
export class TreeComponent implements OnInit, OnDestroy, AfterViewInit {
@Output()
selected = new EventEmitter<DeptInfo>();
@Input()
loginRes: LoginResponse;
@ -106,6 +103,9 @@ export class TreeComponent implements OnInit, OnDestroy, AfterViewInit {
this.dataSource.data = rootNodeList;
}
@Output()
selected = new EventEmitter<DeptInfo>();
@ViewChild('cvsvOrganization', { static: false })
cvsvOrganization: CdkVirtualScrollViewport;

View File

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

View File

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

View File

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

View File

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