통합검색에 UX 적용.
This commit is contained in:
parent
3cfa9a39ac
commit
05a148d30a
|
@ -152,7 +152,7 @@ export class OrganizationTreeComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
/** 검색 취소 */
|
||||
onClickCancel() {
|
||||
this.store.dispatch(QueryStore.cancelSearchDeptUser({}));
|
||||
this.store.dispatch(QueryStore.clearSearchDeptUser({}));
|
||||
}
|
||||
|
||||
/** 조직도 부서 선택 */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
></div>
|
||||
<div class="organization-info">
|
||||
<h3 class="organization-name">
|
||||
<ng-container *ngIf="!(isSearch | async)">
|
||||
<ng-container *ngIf="!isSearch">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
!!(selectedDepartmentProcessing$ | async);
|
||||
|
@ -21,7 +21,7 @@
|
|||
{{ selectedDepartment$ | async | ucapTranslate: 'name' }}
|
||||
</ng-template>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!!(isSearch | async)">
|
||||
<ng-container *ngIf="!!isSearch">
|
||||
{{ 'common.searchResult' | translate
|
||||
}}<span class="text-accent-color"
|
||||
>({{ departmentUserInfoList.length }}
|
||||
|
|
|
@ -259,7 +259,6 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
/** Handling chipset for selectedUserList */
|
||||
/** 선택된 사용자 취소 */
|
||||
onClickDeleteUser(userInfo: UserInfoSS) {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
item => item.seq !== userInfo.seq
|
||||
|
|
|
@ -12,20 +12,127 @@
|
|||
</button>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<ucap-integrated-search
|
||||
#integratedSearch
|
||||
[sessionVerinfo]="sessionVerinfo"
|
||||
[presence]="presence$ | async"
|
||||
[searchWord]="!!data.keyword ? data.keyword : ''"
|
||||
[searchingProcessing]="searchingProcessing"
|
||||
[searchUserInfos]="searchUserInfos"
|
||||
[totalCount]="totalCount"
|
||||
[pageCurrent]="pageCurrent"
|
||||
[pageListCount]="pageListCount"
|
||||
(search)="onReSearch($event)"
|
||||
(changePage)="onChangePage($event)"
|
||||
(openProfile)="onClickOpenProfile($event)"
|
||||
<div fxLayout="column" fxFlex="1 1 auto" class="rightDrawer-notice">
|
||||
<div class="search-area">
|
||||
<ucap-integrated-search-form
|
||||
[searchWord]="!!currentSearchWord ? currentSearchWord : ''"
|
||||
(search)="onSearch($event)"
|
||||
>
|
||||
</ucap-integrated-search>
|
||||
</ucap-integrated-search-form>
|
||||
</div>
|
||||
<div style="position: relative;">
|
||||
<div
|
||||
*ngIf="searchingProcessing$ | async"
|
||||
style="position: absolute; width: 100%; z-index: 101;"
|
||||
>
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contents-table">
|
||||
<div fxFlex="0 0 auto" class="table-box">
|
||||
<ucap-organization-detail-table
|
||||
[loginRes]="loginRes"
|
||||
[presence$]="presenceSubject.asObservable()"
|
||||
[departmentUserInfoList]="departmentUserInfoList"
|
||||
[profileImageRoot]="profileImageRoot"
|
||||
[selectedUserList]="selectedUserList"
|
||||
(openProfile)="onClickOpenProfile($event)"
|
||||
(toggleAllUser)="onToggleAllUser($event)"
|
||||
(toggleUser)="onToggleUser($event)"
|
||||
class="detail-table"
|
||||
></ucap-organization-detail-table>
|
||||
</div>
|
||||
<div class="footer-fix search-result-footer">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
{{ 'organization.selectedUser' | translate }}
|
||||
<span *ngIf="selectedUserList.length > 0">
|
||||
({{ selectedUserList.length }})
|
||||
{{ 'common.units.persons' | translate }}
|
||||
</span>
|
||||
</mat-panel-title>
|
||||
<mat-panel-description> </mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<div class="list-chip">
|
||||
<mat-chip-list aria-label="User selection">
|
||||
<mat-chip
|
||||
*ngFor="let userInfo of selectedUserList"
|
||||
(removed)="onClickDeleteUser(userInfo)"
|
||||
>
|
||||
{{ userInfo.name }}
|
||||
<mat-icon matChipRemove>clear</mat-icon>
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
</div>
|
||||
<div class="btn-box">
|
||||
<ul>
|
||||
<li>
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="
|
||||
selectedUserList.length > 0 ? 'false' : 'true'
|
||||
"
|
||||
(click)="onClickAddGroup()"
|
||||
class="mat-primary"
|
||||
>
|
||||
{{ 'organization.addToGroup' | translate }}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="
|
||||
selectedUserList.length > 0 ? 'false' : 'true'
|
||||
"
|
||||
(click)="onClickChatOpen()"
|
||||
class="mat-primary"
|
||||
>
|
||||
{{ 'organization.startChat' | translate }}
|
||||
</button>
|
||||
</li>
|
||||
<li *ngIf="!!authInfo && authInfo.canVideoConference">
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="
|
||||
selectedUserList.length > 0 ? 'false' : 'true'
|
||||
"
|
||||
(click)="onClickConference()"
|
||||
class="mat-primary"
|
||||
>
|
||||
{{ 'organization.startVideoConference' | translate }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-fix search-result-footer">
|
||||
<ul>
|
||||
<li>
|
||||
<button
|
||||
mat-flat-button
|
||||
(click)="onClickAddGroup()"
|
||||
class="mat-primary"
|
||||
>
|
||||
검색 초기화 & 닫기
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
mat-flat-button
|
||||
(click)="onClickChatOpen()"
|
||||
class="mat-primary"
|
||||
>
|
||||
접어두기
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
import { Component, OnInit, Inject, OnDestroy, ViewChild } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
Inject,
|
||||
OnDestroy,
|
||||
ChangeDetectorRef
|
||||
} from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { KEY_VER_INFO } from '@app/types';
|
||||
import { KEY_VER_INFO, MainMenu, KEY_AUTH_INFO } from '@app/types';
|
||||
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
||||
|
||||
import { Store, select } from '@ngrx/store';
|
||||
import * as AppStore from '@app/store';
|
||||
import * as StatusStore from '@app/store/messenger/status';
|
||||
import {
|
||||
UserInfoSS,
|
||||
QueryProtocolService,
|
||||
DeptSearchType,
|
||||
SSVC_TYPE_QUERY_DEPT_USER_DATA,
|
||||
DeptUserData,
|
||||
SSVC_TYPE_QUERY_DEPT_USER_RES,
|
||||
DeptUserResponse
|
||||
} from '@ucap-webmessenger/protocol-query';
|
||||
import * as QueryStore from '@app/store/messenger/query';
|
||||
import * as ChatStore from '@app/store/messenger/chat';
|
||||
import * as SettingsStore from '@app/store/messenger/settings';
|
||||
import * as SyncStore from '@app/store/messenger/sync';
|
||||
|
||||
import { UserInfoSS, AuthResponse } from '@ucap-webmessenger/protocol-query';
|
||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||
import { map, catchError, take, tap } from 'rxjs/operators';
|
||||
import { Subscription, of, Observable } from 'rxjs';
|
||||
import { map, take, tap } from 'rxjs/operators';
|
||||
import { Subscription, Observable, BehaviorSubject } from 'rxjs';
|
||||
import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
|
||||
|
@ -25,16 +27,20 @@ import { environment } from '../../../../../environments/environment';
|
|||
import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status';
|
||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
||||
import { DaesangProtocolService } from '@ucap-webmessenger/daesang';
|
||||
import {
|
||||
DialogService,
|
||||
IntegratedSearchComponent
|
||||
} from '@ucap-webmessenger/ui';
|
||||
import { DialogService } from '@ucap-webmessenger/ui';
|
||||
import {
|
||||
ProfileDialogComponent,
|
||||
ProfileDialogData,
|
||||
ProfileDialogResult
|
||||
} from '../profile/profile.dialog.component';
|
||||
import { PageEvent } from '@angular/material/paginator';
|
||||
import {
|
||||
SelectGroupDialogComponent,
|
||||
SelectGroupDialogData,
|
||||
SelectGroupDialogResult
|
||||
} from '../group/select-group.dialog.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { GroupDetailData } from '@ucap-webmessenger/protocol-sync';
|
||||
import { ConferenceService } from '@ucap-webmessenger/api-prompt';
|
||||
|
||||
export interface IntegratedSearchDialogData {
|
||||
keyword: string;
|
||||
|
@ -52,19 +58,21 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
|
|||
loginResSubscription: Subscription;
|
||||
sessionVerinfo: VersionInfo2Response;
|
||||
environmentsInfo: EnvironmentsInfo;
|
||||
authInfo: AuthResponse;
|
||||
|
||||
presence$: Observable<StatusBulkInfo[]>;
|
||||
searchSubscription: Subscription;
|
||||
searchUserInfos: UserInfoSS[] = [];
|
||||
searchingProcessing = false;
|
||||
searchDepartmentUserInfoListSubscription: Subscription;
|
||||
searchingProcessing$: Observable<boolean>;
|
||||
|
||||
departmentUserInfoList: UserInfoSS[] = [];
|
||||
originDepartmentUserInfoList: UserInfoSS[] = [];
|
||||
|
||||
selectedUserList: UserInfoSS[] = []; // selected user in departmentUserList detail
|
||||
|
||||
profileImageRoot: string;
|
||||
presenceSubscription: Subscription;
|
||||
presenceSubject = new BehaviorSubject<StatusBulkInfo[]>(undefined);
|
||||
|
||||
currentSearchWord: string;
|
||||
totalCount = 0;
|
||||
pageCurrent = 1;
|
||||
pageListCount = 20;
|
||||
|
||||
@ViewChild('integratedSearch', { static: false })
|
||||
integratedSearchComponent: IntegratedSearchComponent;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<
|
||||
|
@ -73,22 +81,30 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
|
|||
>,
|
||||
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: IntegratedSearchDialogData,
|
||||
private queryProtocolService: QueryProtocolService,
|
||||
private sessionStorageService: SessionStorageService,
|
||||
private daesangProtocolService: DaesangProtocolService,
|
||||
private dialogService: DialogService,
|
||||
private translateService: TranslateService,
|
||||
private conferenceService: ConferenceService,
|
||||
|
||||
private store: Store<any>,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private logger: NGXLogger
|
||||
) {
|
||||
this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
|
||||
KEY_ENVIRONMENTS_INFO
|
||||
);
|
||||
|
||||
this.authInfo = this.sessionStorageService.get<AuthResponse>(KEY_AUTH_INFO);
|
||||
|
||||
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
|
||||
KEY_VER_INFO
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.profileImageRoot = this.sessionVerinfo.profileRoot;
|
||||
|
||||
this.loginResSubscription = this.store
|
||||
.pipe(
|
||||
select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
|
||||
|
@ -98,26 +114,48 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
|
|||
)
|
||||
.subscribe();
|
||||
|
||||
this.onSearch(this.data.keyword);
|
||||
this.searchDepartmentUserInfoListSubscription = this.store
|
||||
.pipe(
|
||||
select(
|
||||
AppStore.MessengerSelector.QuerySelector
|
||||
.integrateSearchDepartmentUserInfoList
|
||||
)
|
||||
)
|
||||
.subscribe(list => {
|
||||
this.departmentUserInfoList = list;
|
||||
this.originDepartmentUserInfoList = list;
|
||||
});
|
||||
|
||||
this.presence$ = this.store.pipe(
|
||||
select(AppStore.MessengerSelector.StatusSelector.selectAllStatusBulkInfo)
|
||||
this.searchingProcessing$ = this.store.pipe(
|
||||
select(
|
||||
AppStore.MessengerSelector.QuerySelector
|
||||
.integrateSearchDepartmentProcessing
|
||||
)
|
||||
);
|
||||
|
||||
this.presenceSubscription = this.store
|
||||
.pipe(
|
||||
select(
|
||||
AppStore.MessengerSelector.StatusSelector.selectAllStatusBulkInfo
|
||||
)
|
||||
)
|
||||
.subscribe(presence => {
|
||||
this.presenceSubject.next(presence);
|
||||
});
|
||||
|
||||
this.onSearch(this.data.keyword);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (!!this.searchSubscription) {
|
||||
this.searchSubscription.unsubscribe();
|
||||
}
|
||||
if (!!this.loginResSubscription) {
|
||||
this.loginResSubscription.unsubscribe();
|
||||
}
|
||||
if (!!this.searchDepartmentUserInfoListSubscription) {
|
||||
this.searchDepartmentUserInfoListSubscription.unsubscribe();
|
||||
}
|
||||
if (!!this.presenceSubscription) {
|
||||
this.presenceSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
onReSearch(searchWord: string) {
|
||||
this.pageCurrent = 1;
|
||||
this.integratedSearchComponent.paginator.pageIndex = 0;
|
||||
this.onSearch(searchWord);
|
||||
}
|
||||
|
||||
onSearch(searchWord: string) {
|
||||
|
@ -126,78 +164,122 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
if (searchWord.trim().length > 0) {
|
||||
this.searchingProcessing = true;
|
||||
const searchUserInfos: UserInfoSS[] = [];
|
||||
|
||||
this.searchSubscription = this.queryProtocolService
|
||||
.deptUser({
|
||||
divCd: 'INT_SRCH',
|
||||
companyCode: this.loginRes.companyCode,
|
||||
searchRange: DeptSearchType.All,
|
||||
search: searchWord.trim(),
|
||||
senderCompanyCode: this.loginRes.companyCode,
|
||||
senderEmployeeType: this.loginRes.userInfo.employeeType,
|
||||
pageCurrent: this.pageCurrent,
|
||||
pageListCount: this.pageListCount
|
||||
})
|
||||
.pipe(
|
||||
map(res => {
|
||||
switch (res.SSVC_TYPE) {
|
||||
case SSVC_TYPE_QUERY_DEPT_USER_DATA:
|
||||
const userInfos = (res as DeptUserData).userInfos;
|
||||
searchUserInfos.push(...userInfos);
|
||||
break;
|
||||
case SSVC_TYPE_QUERY_DEPT_USER_RES:
|
||||
{
|
||||
const response = res as DeptUserResponse;
|
||||
|
||||
// 검색 결과 처리.
|
||||
this.searchUserInfos = searchUserInfos.sort((a, b) =>
|
||||
a.name < b.name ? -1 : a.name > b.name ? 1 : 0
|
||||
);
|
||||
|
||||
this.totalCount = response.pageTotalCount;
|
||||
this.pageCurrent = response.pageCurrent;
|
||||
this.pageListCount = response.pageListCount;
|
||||
this.searchingProcessing = false;
|
||||
|
||||
// 검색 결과에 따른 프레즌스 조회.
|
||||
if (searchUserInfos.length > 0) {
|
||||
this.store.dispatch(
|
||||
StatusStore.bulkInfo({
|
||||
divCd: 'INT_SRCH',
|
||||
userSeqs: this.searchUserInfos.map(user => user.seq)
|
||||
QueryStore.integrateSearchDeptUser({
|
||||
companyCode: this.loginRes.companyCode,
|
||||
search: searchWord.trim()
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}),
|
||||
catchError(error => {
|
||||
this.searchingProcessing = false;
|
||||
return of(this.logger.error(error));
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
} else {
|
||||
// clear list.
|
||||
this.searchingProcessing = false;
|
||||
this.searchUserInfos = [];
|
||||
this.store.dispatch(QueryStore.integrateClearSearchDeptUser({}));
|
||||
}
|
||||
}
|
||||
|
||||
onCancel(): void {
|
||||
this.dialogRef.close({});
|
||||
/** Selected User Handling */
|
||||
onToggleAllUser(params: { isChecked: boolean; userInfos: UserInfoSS[] }) {
|
||||
params.userInfos.forEach(userInfo => {
|
||||
if (params.isChecked) {
|
||||
if (
|
||||
this.selectedUserList.filter(user => user.seq === userInfo.seq)
|
||||
.length === 0
|
||||
) {
|
||||
this.selectedUserList = [...this.selectedUserList, userInfo];
|
||||
}
|
||||
} else {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
user => user.seq !== userInfo.seq
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
onToggleUser(userInfo: UserInfoSS) {
|
||||
if (userInfo.seq === this.loginRes.userSeq) {
|
||||
return;
|
||||
}
|
||||
|
||||
onChangePage(event: PageEvent) {
|
||||
this.pageCurrent = event.pageIndex + 1;
|
||||
this.pageListCount = event.pageSize;
|
||||
|
||||
this.onSearch(this.currentSearchWord);
|
||||
if (
|
||||
this.selectedUserList.filter(user => user.seq === userInfo.seq).length ===
|
||||
0
|
||||
) {
|
||||
this.selectedUserList = [...this.selectedUserList, userInfo];
|
||||
} else {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
item => item.seq !== userInfo.seq
|
||||
);
|
||||
}
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
/** Handling chipset for selectedUserList */
|
||||
onClickDeleteUser(userInfo: UserInfoSS) {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
item => item.seq !== userInfo.seq
|
||||
);
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
/** Handling Button */
|
||||
async onClickAddGroup() {
|
||||
this.logger.debug('onClickAddGroup', this.selectedUserList);
|
||||
|
||||
const result = await this.dialogService.open<
|
||||
SelectGroupDialogComponent,
|
||||
SelectGroupDialogData,
|
||||
SelectGroupDialogResult
|
||||
>(SelectGroupDialogComponent, {
|
||||
width: '600px',
|
||||
data: {
|
||||
title: this.translateService.instant('group.selectTargetGroup')
|
||||
}
|
||||
});
|
||||
|
||||
if (!!result && !!result.choice && result.choice) {
|
||||
if (!!result.group) {
|
||||
const oldGroup: GroupDetailData = result.group;
|
||||
const trgtUserSeq: number[] = [];
|
||||
result.group.userSeqs.map(seq => trgtUserSeq.push(seq));
|
||||
this.selectedUserList
|
||||
.filter(v => result.group.userSeqs.indexOf(v.seq) < 0)
|
||||
.forEach(user => {
|
||||
trgtUserSeq.push(user.seq);
|
||||
});
|
||||
|
||||
this.store.dispatch(
|
||||
SyncStore.updateGroupMember({
|
||||
oldGroup,
|
||||
trgtUserSeq
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
onClickChatOpen() {
|
||||
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
|
||||
// Open Room.
|
||||
const seq: number[] = [];
|
||||
this.selectedUserList.map(user => seq.push(user.seq));
|
||||
this.store.dispatch(ChatStore.openRoom({ userSeqList: seq }));
|
||||
|
||||
// GNB Change to Chat
|
||||
this.store.dispatch(
|
||||
SettingsStore.selectedGnbMenuIndex({
|
||||
menuIndex: MainMenu.Chat
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
onClickConference() {
|
||||
const targetUserSeqs = this.selectedUserList.map(userInfo => userInfo.seq);
|
||||
if (!!targetUserSeqs && targetUserSeqs.length > 0) {
|
||||
this.conferenceService.conferenceCreate({
|
||||
userSeq: this.loginRes.userSeq,
|
||||
deviceType: this.environmentsInfo.deviceType,
|
||||
tokenKey: this.loginRes.tokenString,
|
||||
targetUserSeqs
|
||||
});
|
||||
}
|
||||
}
|
||||
onClickOpenProfile(userSeq: number) {
|
||||
if (!userSeq || userSeq < 0) {
|
||||
return;
|
||||
|
@ -234,4 +316,7 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
|
|||
)
|
||||
.subscribe();
|
||||
}
|
||||
onCancel(): void {
|
||||
this.dialogRef.close({});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,10 +100,34 @@ export const searchDeptUserSuccess = createAction(
|
|||
|
||||
export const searchDeptUserFailure = createAction(
|
||||
'[Messenger::Query] Search Dept User Failure',
|
||||
props<{ error: any }>()
|
||||
);
|
||||
|
||||
export const clearSearchDeptUser = createAction(
|
||||
'[Messenger::Query] Clear Search Dept User Success',
|
||||
props()
|
||||
);
|
||||
|
||||
export const cancelSearchDeptUser = createAction(
|
||||
'[Messenger::Query] Cancel Search Dept User Success',
|
||||
/** 통합검색 > 조회 */
|
||||
export const integrateSearchDeptUser = createAction(
|
||||
'[Messenger::Query] Integration Search Dept User',
|
||||
props<{
|
||||
companyCode: string;
|
||||
search: string;
|
||||
}>()
|
||||
);
|
||||
|
||||
export const integrateSearchDeptUserSuccess = createAction(
|
||||
'[Messenger::Query] Integration Search Dept User Success.',
|
||||
props<{ userInfos: UserInfoSS[] }>()
|
||||
);
|
||||
|
||||
export const integrateSearchDeptUserFailure = createAction(
|
||||
'[Messenger::Query] Integration Search Dept User Failure.',
|
||||
props<{ error: any }>()
|
||||
);
|
||||
|
||||
export const integrateClearSearchDeptUser = createAction(
|
||||
'[Messenger::Query] Integration Clear Search Dept User Success',
|
||||
props()
|
||||
);
|
||||
|
|
|
@ -28,7 +28,11 @@ import {
|
|||
selectedDeptSuccess,
|
||||
searchDeptUser,
|
||||
searchDeptUserSuccess,
|
||||
cancelSearchDeptUser
|
||||
clearSearchDeptUser,
|
||||
integrateSearchDeptUser,
|
||||
integrateSearchDeptUserSuccess,
|
||||
integrateSearchDeptUserFailure,
|
||||
searchDeptUserFailure
|
||||
} from './actions';
|
||||
|
||||
import {
|
||||
|
@ -146,7 +150,58 @@ export class Effects {
|
|||
|
||||
this.store.dispatch(selectedDeptSuccess({}));
|
||||
}),
|
||||
catchError(error => of(deptUserFailure({ error })))
|
||||
catchError(error => of(searchDeptUserFailure({ error })))
|
||||
);
|
||||
})
|
||||
);
|
||||
},
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
integrateSearchDeptUser$ = createEffect(
|
||||
() => {
|
||||
return this.actions$.pipe(
|
||||
ofType(integrateSearchDeptUser),
|
||||
withLatestFrom(
|
||||
this.store.pipe(
|
||||
select(
|
||||
(state: any) =>
|
||||
state.account.authentication.loginRes as LoginResponse
|
||||
)
|
||||
)
|
||||
),
|
||||
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 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 })))
|
||||
);
|
||||
})
|
||||
);
|
||||
|
@ -179,7 +234,6 @@ export class Effects {
|
|||
.pipe(
|
||||
map(datas => {
|
||||
const userInfos: UserInfoSS[] = datas.userInfos;
|
||||
|
||||
this.store.dispatch(
|
||||
searchDeptUserSuccess({
|
||||
userInfos
|
||||
|
|
|
@ -11,8 +11,12 @@ import {
|
|||
searchDeptUserSuccess,
|
||||
searchDeptUserFailure,
|
||||
deptUserFailure,
|
||||
cancelSearchDeptUser,
|
||||
myDeptUserFailure
|
||||
clearSearchDeptUser,
|
||||
myDeptUserFailure,
|
||||
integrateSearchDeptUser,
|
||||
integrateSearchDeptUserSuccess,
|
||||
integrateSearchDeptUserFailure,
|
||||
integrateClearSearchDeptUser
|
||||
} from './actions';
|
||||
|
||||
import * as AuthenticationStore from '@app/store/account/authentication';
|
||||
|
@ -96,7 +100,7 @@ export const reducer = createReducer(
|
|||
};
|
||||
}),
|
||||
|
||||
on(cancelSearchDeptUser, (state, action) => {
|
||||
on(clearSearchDeptUser, (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
isSearch: false,
|
||||
|
@ -104,6 +108,35 @@ export const reducer = createReducer(
|
|||
};
|
||||
}),
|
||||
|
||||
on(integrateSearchDeptUser, (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
integrateSearchDepartmentProcessing: true
|
||||
};
|
||||
}),
|
||||
|
||||
on(integrateSearchDeptUserSuccess, (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
integrateSearchDepartmentUserInfoList: action.userInfos,
|
||||
integrateSearchDepartmentProcessing: false
|
||||
};
|
||||
}),
|
||||
|
||||
on(integrateSearchDeptUserFailure, (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
integrateSearchDepartmentProcessing: false
|
||||
};
|
||||
}),
|
||||
|
||||
on(integrateClearSearchDeptUser, (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
integrateSearchDepartmentUserInfoList: null
|
||||
};
|
||||
}),
|
||||
|
||||
on(AuthenticationStore.logoutInitialize, (state, action) => {
|
||||
return {
|
||||
...initialState
|
||||
|
|
|
@ -18,6 +18,9 @@ export interface State {
|
|||
searchDepartmentUserInfoList: UserInfoSS[] | null;
|
||||
departmentUserInfoList: UserInfoSS[] | null;
|
||||
myDepartmentUserInfoList: UserInfoSS[] | null;
|
||||
|
||||
integrateSearchDepartmentProcessing: boolean;
|
||||
integrateSearchDepartmentUserInfoList: UserInfoSS[] | null;
|
||||
}
|
||||
|
||||
export const initialState: State = {
|
||||
|
@ -30,7 +33,10 @@ export const initialState: State = {
|
|||
|
||||
searchDepartmentUserInfoList: null,
|
||||
departmentUserInfoList: null,
|
||||
myDepartmentUserInfoList: null
|
||||
myDepartmentUserInfoList: null,
|
||||
|
||||
integrateSearchDepartmentProcessing: false,
|
||||
integrateSearchDepartmentUserInfoList: null
|
||||
};
|
||||
|
||||
export function selectors<S>(selector: Selector<any, State>) {
|
||||
|
@ -62,6 +68,15 @@ export function selectors<S>(selector: Selector<any, State>) {
|
|||
myDepartmentUserInfoList: createSelector(
|
||||
selector,
|
||||
(state: State) => state.myDepartmentUserInfoList
|
||||
),
|
||||
|
||||
integrateSearchDepartmentProcessing: createSelector(
|
||||
selector,
|
||||
(state: State) => state.integrateSearchDepartmentProcessing
|
||||
),
|
||||
integrateSearchDepartmentUserInfoList: createSelector(
|
||||
selector,
|
||||
(state: State) => state.integrateSearchDepartmentUserInfoList
|
||||
)
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user