사용자 검색 >> 프레즌스 적용

This commit is contained in:
leejinho 2020-01-29 11:15:57 +09:00
parent 790e8ac060
commit ded09a9c83
5 changed files with 129 additions and 18 deletions

View File

@ -305,16 +305,6 @@ export class OrganizationComponent
// 검색 결과 처리. // 검색 결과 처리.
this.searchUserInfos = searchUserInfos; this.searchUserInfos = searchUserInfos;
this.selectedDepartmentProcessing = false; this.selectedDepartmentProcessing = false;
// 검색 결과에 따른 프레즌스 조회.
const userSeqList: number[] = [];
if (userSeqList.length > 0) {
this.store.dispatch(
StatusStore.bulkInfo({
divCd: 'orgSrch',
userSeqs: this.searchUserInfos.map(user => user.seq)
})
);
}
if (!!this.cvsvDeptSearchUser) { if (!!this.cvsvDeptSearchUser) {
this.cvsvDeptSearchUser.scrollToOffset(0); this.cvsvDeptSearchUser.scrollToOffset(0);

View File

@ -1,4 +1,6 @@
<ucap-integrated-search <ucap-integrated-search
[sessionVerinfo]="sessionVerinfo"
[presence]="presence$ | async"
[searchWord]="!!data.keyword ? data.keyword : ''" [searchWord]="!!data.keyword ? data.keyword : ''"
[searchingProcessing]="searchingProcessing" [searchingProcessing]="searchingProcessing"
[searchUserInfos]="searchUserInfos" [searchUserInfos]="searchUserInfos"

View File

@ -1,9 +1,10 @@
import { Component, OnInit, Inject, OnDestroy } from '@angular/core'; import { Component, OnInit, Inject, OnDestroy } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA, PageEvent } from '@angular/material'; import { MatDialogRef, MAT_DIALOG_DATA, PageEvent } from '@angular/material';
import { KEY_LOGIN_RES_INFO } from '@app/types'; import { KEY_LOGIN_RES_INFO, KEY_VER_INFO } from '@app/types';
import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { Store } from '@ngrx/store'; import { Store, select } from '@ngrx/store';
import * as AppStore from '@app/store';
import * as StatusStore from '@app/store/messenger/status'; import * as StatusStore from '@app/store/messenger/status';
import { import {
UserInfoSS, UserInfoSS,
@ -16,12 +17,14 @@ import {
} from '@ucap-webmessenger/protocol-query'; } from '@ucap-webmessenger/protocol-query';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { map, catchError } from 'rxjs/operators'; import { map, catchError } from 'rxjs/operators';
import { Subscription, of } from 'rxjs'; import { Subscription, of, Observable } from 'rxjs';
import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types'; import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { environment } from '../../../../../environments/environment'; import { environment } from '../../../../../environments/environment';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
export interface IntegratedSearchDialogData { export interface IntegratedSearchDialogData {
keyword: string; keyword: string;
@ -36,8 +39,10 @@ export interface IntegratedSearchDialogResult {}
}) })
export class IntegratedSearchDialogComponent implements OnInit, OnDestroy { export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
loginRes: LoginResponse; loginRes: LoginResponse;
sessionVerinfo: VersionInfo2Response;
environmentsInfo: EnvironmentsInfo; environmentsInfo: EnvironmentsInfo;
presence$: Observable<StatusBulkInfo[]>;
searchSubscription: Subscription; searchSubscription: Subscription;
searchUserInfos: UserInfoSS[] = []; searchUserInfos: UserInfoSS[] = [];
searchingProcessing = false; searchingProcessing = false;
@ -65,10 +70,17 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>( this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
KEY_ENVIRONMENTS_INFO KEY_ENVIRONMENTS_INFO
); );
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
KEY_VER_INFO
);
} }
ngOnInit() { ngOnInit() {
this.onSearch(this.data.keyword); this.onSearch(this.data.keyword);
this.presence$ = this.store.pipe(
select(AppStore.MessengerSelector.StatusSelector.selectAllStatusBulkInfo)
);
} }
onSearch(searchWord: string) { onSearch(searchWord: string) {
@ -109,8 +121,7 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy {
this.searchingProcessing = false; this.searchingProcessing = false;
// 검색 결과에 따른 프레즌스 조회. // 검색 결과에 따른 프레즌스 조회.
const userSeqList: number[] = []; if (searchUserInfos.length > 0) {
if (userSeqList.length > 0) {
this.store.dispatch( this.store.dispatch(
StatusStore.bulkInfo({ StatusStore.bulkInfo({
divCd: 'INT_SRCH', divCd: 'INT_SRCH',

View File

@ -39,7 +39,17 @@
</th> </th>
<td mat-cell *matCellDef="let element"> <td mat-cell *matCellDef="let element">
<div class="profile"> <div class="profile">
{{ element.name }} {{ getPresence(element, PresenceType.PC) }} /
{{ getPresence(element, PresenceType.MOBILE) }} /
{{ getWorkstatus(element) }} /
<img
class="thumbnail"
ucapImage
[base]="profileImageRoot"
[path]="element.profileImageFile"
[default]="'assets/images/img_nophoto_50.png'"
(click)="onClickOpenProfile($event, element.seq)"
/>
</div> </div>
</td> </td>
</ng-container> </ng-container>

View File

@ -10,7 +10,22 @@ import {
} from '@angular/core'; } from '@angular/core';
import { ucapAnimations } from '../animations'; import { ucapAnimations } from '../animations';
import { UserInfoSS } from '@ucap-webmessenger/protocol-query'; import { UserInfoSS } from '@ucap-webmessenger/protocol-query';
import { MatPaginator, PageEvent, MatTabLabel } from '@angular/material'; import { MatPaginator, PageEvent } from '@angular/material';
import {
StatusBulkInfo,
WorkStatusType
} from '@ucap-webmessenger/protocol-status';
import { StatusCode } from '@ucap-webmessenger/core';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
export enum PresenceType {
PC = 'pc',
MOBILE = 'mobile',
CONFERENCE = 'conference',
MOBILE_CONFERENCE = 'mobileConference',
PHONE = 'phone',
IMESSENER = 'imessenger'
}
@Component({ @Component({
selector: 'ucap-integrated-search', selector: 'ucap-integrated-search',
@ -19,6 +34,12 @@ import { MatPaginator, PageEvent, MatTabLabel } from '@angular/material';
animations: ucapAnimations animations: ucapAnimations
}) })
export class IntegratedSearchComponent implements OnInit { export class IntegratedSearchComponent implements OnInit {
@Input()
profileImageRoot?: string;
@Input()
sessionVerinfo: VersionInfo2Response;
@Input()
presence?: StatusBulkInfo[] = [];
@Input() @Input()
searchWord?: string; searchWord?: string;
@Input() @Input()
@ -36,6 +57,8 @@ export class IntegratedSearchComponent implements OnInit {
search = new EventEmitter<string>(); search = new EventEmitter<string>();
@Output() @Output()
changePage = new EventEmitter<PageEvent>(); changePage = new EventEmitter<PageEvent>();
@Output()
openProfile = new EventEmitter<number>();
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
displayedColumns: string[] = [ displayedColumns: string[] = [
@ -58,12 +81,17 @@ export class IntegratedSearchComponent implements OnInit {
resizableFnMousemove: () => void; resizableFnMousemove: () => void;
resizableFnMouseup: () => void; resizableFnMouseup: () => void;
PresenceType = PresenceType;
constructor( constructor(
private changeDetectorRef: ChangeDetectorRef, private changeDetectorRef: ChangeDetectorRef,
private renderer: Renderer2 private renderer: Renderer2
) {} ) {}
ngOnInit() {} ngOnInit() {
this.profileImageRoot =
this.profileImageRoot || this.sessionVerinfo.profileRoot;
}
onSearch(keyword: string) { onSearch(keyword: string) {
this.search.emit(keyword); this.search.emit(keyword);
@ -73,6 +101,76 @@ export class IntegratedSearchComponent implements OnInit {
this.changePage.emit(event); this.changePage.emit(event);
} }
getPresence(userInfo: UserInfoSS, type: PresenceType): string {
const presences = this.presence.filter(p => p.userSeq === userInfo.seq);
let status: string;
let rtnClass = '';
if (!!presences && presences.length > 0) {
const presence = presences[0];
switch (type) {
case PresenceType.PC:
status = !!presence ? presence.pcStatus : undefined;
break;
case PresenceType.MOBILE:
status = !!presence ? presence.mobileStatus : undefined;
break;
}
if (!!status) {
switch (status) {
case StatusCode.OnLine:
rtnClass = type + 'On';
break;
case StatusCode.Away:
rtnClass = type + 'Out';
break;
case StatusCode.Busy:
rtnClass = type + 'Other';
break;
default:
rtnClass = type + 'Off';
break;
}
}
} else {
rtnClass = type + 'Off';
}
return rtnClass;
}
getWorkstatus(userInfo: UserInfoSS): string {
let workstatus = '';
if (!!userInfo && !!userInfo.workstatus) {
switch (userInfo.workstatus) {
case WorkStatusType.VacationAM:
workstatus = '오전';
break;
case WorkStatusType.VacationPM:
workstatus = '오후';
break;
case WorkStatusType.VacationAll:
workstatus = '휴가';
break;
case WorkStatusType.LeaveOfAbsence:
workstatus = '휴직';
break;
case WorkStatusType.LongtermRefresh:
workstatus = '장기';
break;
}
}
return workstatus;
}
onClickOpenProfile(event: MouseEvent, userSeq: number) {
event.preventDefault();
event.stopPropagation();
this.openProfile.emit(userSeq);
}
resizeTable(event: any, column: any) { resizeTable(event: any, column: any) {
this.start = event.target; this.start = event.target;
this.pressed = true; this.pressed = true;