next-ucap-messenger/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/left-sidenav/message.component.ts
2020-02-05 15:29:29 +09:00

467 lines
12 KiB
TypeScript

import {
Component,
OnInit,
OnDestroy,
Output,
EventEmitter,
ViewChild,
Input,
AfterViewChecked
} from '@angular/core';
import { Observable, Subscription, merge } from 'rxjs';
import { Store, select } from '@ngrx/store';
import { NGXLogger } from 'ngx-logger';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
DialogService,
AlertDialogComponent,
AlertDialogResult,
AlertDialogData
} from '@ucap-webmessenger/ui';
import {
LoginResponse,
RoleCode
} from '@ucap-webmessenger/protocol-authentication';
import { KEY_LOGIN_RES_INFO } from '@app/types/login-res-info.type';
import {
MessageApiService,
MessageType,
MessageList,
MessageSearchType,
MessageDetailInfo
} from '@ucap-webmessenger/api-message';
import { MessageStatusCode } from '@ucap-webmessenger/api';
import { ContentType } from '@ucap-webmessenger/api-message';
import { FormGroup, FormBuilder } from '@angular/forms';
import {
MatTabGroup,
MatSelectChange,
MatRadioChange
} from '@angular/material';
import {
MessageDetailDialogComponent,
MessageDetailDialogResult,
MessageDetailDialogData
} from '../../dialogs/message/message-detail.dialog.component';
import {
EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO,
KEY_VER_INFO
} from '@app/types';
import * as AppStore from '@app/store';
import * as MessageStore from '@app/store/messenger/message';
import { TranslateService } from '@ngx-translate/core';
import {
MessageWriteDialogComponent,
MessageWriteDialogResult,
MessageWriteDialogData
} from '../../dialogs/message/message-write.dialog.component';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
import { EmployeeType } from '@ucap-webmessenger/protocol-room';
export interface MessageTypeData {
displayName: string;
name: string;
}
@Component({
selector: 'app-layout-chat-left-sidenav-message',
templateUrl: './message.component.html',
styleUrls: ['./message.component.scss']
})
export class MessageBoxComponent
implements OnInit, OnDestroy, AfterViewChecked {
@Input()
isVisible = false;
@Output()
doRefreshUnReadCount = new EventEmitter();
@ViewChild('tabs', { static: false }) tabs: MatTabGroup;
isInitTabs = false;
fgSearch: FormGroup;
fgSearchType: FormGroup;
loginRes: LoginResponse;
sessionVerinfo: VersionInfo2Response;
environmentsInfo: EnvironmentsInfo;
messageRetrieveList$: Observable<MessageList[]>;
messageSendList$: Observable<MessageList[]>;
messageReservationList$: Observable<MessageList[]>;
messageSearchList$: Observable<MessageList[]>;
messageDetailInfo: Subscription;
currentTabIndex = 0;
defaultPageSize = 1000; // default
currentTotalCount = 0;
currentPage = 0;
ContentType = ContentType;
MessageType = MessageType;
MessageSearchType = MessageSearchType;
isSearch = false;
messageTypeList: MessageTypeData[] = [];
langChangeSubscription: Subscription;
constructor(
private store: Store<any>,
private formBuilder: FormBuilder,
private sessionStorageService: SessionStorageService,
private dialogService: DialogService,
private translateService: TranslateService,
private messageApiService: MessageApiService,
private logger: NGXLogger
) {
this.loginRes = this.sessionStorageService.get<LoginResponse>(
KEY_LOGIN_RES_INFO
);
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
KEY_VER_INFO
);
this.environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
KEY_ENVIRONMENTS_INFO
);
}
ngOnInit() {
this.fgSearch = this.formBuilder.group({
searchInput: null
});
this.fgSearchType = this.formBuilder.group({
searchMessageType: [MessageType.All],
searchMessageSearchType: [MessageSearchType.Name]
});
this.messageRetrieveList$ = this.store.pipe(
select(AppStore.MessengerSelector.MessageSelector.selectAllReceiveList)
);
this.messageSendList$ = this.store.pipe(
select(AppStore.MessengerSelector.MessageSelector.selectAllSendList)
);
this.messageReservationList$ = this.store.pipe(
select(
AppStore.MessengerSelector.MessageSelector.selectAllReservationList
)
);
this.messageSearchList$ = this.store.pipe(
select(AppStore.MessengerSelector.MessageSelector.selectAllSearchList)
);
this.messageDetailInfo = this.store
.pipe(
select(AppStore.MessengerSelector.MessageSelector.detailMessageInfo)
)
.subscribe(async info => {
if (!!info && info.responseCode === MessageStatusCode.Success) {
// Badge Refresh in case Receive Message..
if (info.msgInfo.type === MessageType.Receive) {
this.doRefreshUnReadCount.emit();
// Clear Receive Message New Badge..
this.store.dispatch(
MessageStore.clearNewFlagReceiveMessage({
msgId: info.msgInfo.msgId
})
);
}
// detail view..
const result = await this.dialogService.open<
MessageDetailDialogComponent,
MessageDetailDialogData,
MessageDetailDialogResult
>(MessageDetailDialogComponent, {
width: '600px',
hasBackdrop: false,
data: {
detail: info,
loginRes: this.loginRes,
environmentsInfo: this.environmentsInfo
}
});
if (!!result) {
// Clear detail Info in state
this.store.dispatch(MessageStore.detailMessageClear({}));
switch (result.returnType) {
case 'DEL':
// 단건 삭제.
this.doMessageDelete([result.messageInfo]);
break;
case 'CANCEL_RESERVATION':
// 단건 발송취소(예약)
this.doMessageCancelReservation(result.messageInfo);
break;
case 'REPLY':
// 답장
this.doMessageReply(result.messageInfo);
break;
case 'UPDATE':
// 예약 수정
this.getRetrieveMessage(MessageType.Reservation, 0);
break;
}
}
} else if (
!!info &&
info.responseCode === MessageStatusCode.Fail_Cancelled_Msg
) {
this.dialogService.open<
AlertDialogComponent,
AlertDialogData,
AlertDialogResult
>(AlertDialogComponent, {
width: '360px',
data: {
title: this.translateService.instant('message.errors.label'),
message: this.translateService.instant(
'message.errors.cancelledMessage'
)
}
});
}
});
// 초기 검색은 수신함.
this.getRetrieveMessage(MessageType.Receive, 0);
if (!!this.tabs) {
this.tabs.realignInkBar();
}
this.setMessageTypeData();
this.langChangeSubscription = merge(
this.translateService.onLangChange,
this.translateService.onDefaultLangChange,
this.translateService.onTranslationChange
).subscribe(() => {
this.setMessageTypeData();
});
}
ngAfterViewChecked(): void {
if (!!this.tabs && !this.isInitTabs && this.isVisible) {
this.isInitTabs = true;
this.tabs.realignInkBar();
}
}
ngOnDestroy(): void {
if (!!this.messageDetailInfo) {
this.messageDetailInfo.unsubscribe();
}
if (!!this.langChangeSubscription) {
this.langChangeSubscription.unsubscribe();
}
}
onSelectedIndexTab(value: number) {
this.tabs.selectedIndex = value;
}
onSelectedIndexChange(value: number) {
this.currentTabIndex = value;
let messageType: MessageType;
switch (value) {
case 0:
// Recieve
messageType = MessageType.Receive;
break;
case 1:
// Send
messageType = MessageType.Send;
break;
case 2:
// Reservation
messageType = MessageType.Reservation;
break;
}
this.getRetrieveMessage(messageType, 0);
}
/** 쪽지 검색 관련 */
onChangeSelection(event: MatSelectChange) {
this.getSearchMessage(
event.value,
this.fgSearchType.get('searchMessageSearchType').value,
this.fgSearch.get('searchInput').value
);
}
onChangeSearchType(event: MatRadioChange) {
this.getSearchMessage(
this.fgSearchType.get('searchMessageType').value,
event.value,
this.fgSearch.get('searchInput').value
);
}
onKeyDownEnter(event: KeyboardEvent, search: string) {
event.preventDefault();
event.stopPropagation();
if (!search || search.trim().length === 0) {
return;
}
this.getSearchMessage(
MessageType.All,
MessageSearchType.Name,
search.trim()
);
}
getSearchMessage(
messageType: MessageType,
searchType: MessageSearchType,
searchStr: string
) {
this.isSearch = true;
this.store.dispatch(
MessageStore.searchMessage({
messageType,
searchType,
searchStr
})
);
}
onClickSearchCancel() {
this.isSearch = false;
this.store.dispatch(MessageStore.clearSearchMessage({}));
// this.getRetrieveMessage(MessageType.Receive, 0);
}
/** 쪽지 타입별 조회 */
getRetrieveMessage(messageType: MessageType, trgtPageIndex: number) {
this.store.dispatch(
MessageStore.retrieveMessage({
messageType
})
);
}
/** 쪽지 상세보기 */
onClickDetail(message: MessageList) {
this.store.dispatch(
MessageStore.detailMessage({
messageType: message.type,
msgId: message.msgId
})
);
}
/** 쪽지(수신,발신) 삭제 */
doMessageDelete(messageInfo: MessageDetailInfo[]): void {
const msgList: { msgId: number }[] = [];
messageInfo.forEach(info => msgList.push({ msgId: info.msgId }));
this.store.dispatch(
MessageStore.deleteMessage({
messageType: messageInfo[0].type,
msgList
})
);
}
/** 쪽지(예약) 삭제 */
doMessageCancelReservation(messageInfo: MessageDetailInfo): void {
this.store.dispatch(
MessageStore.cancelReservationMessage({
messageType: messageInfo.type,
msgId: messageInfo.msgId
})
);
}
doMessageReply(messageInfo: MessageDetailInfo): void {
this.dialogService.open<
MessageWriteDialogComponent,
MessageWriteDialogData,
MessageWriteDialogResult
>(MessageWriteDialogComponent, {
width: '600px',
height: '600px',
disableClose: true,
hasBackdrop: false,
data: {
loginRes: this.loginRes,
environmentsInfo: this.environmentsInfo,
receiverList: [this.convertDetailReceivertoUserInfo(messageInfo)]
}
});
}
private setMessageTypeData() {
const messageTypeData = this.translateService.instant('message.type');
const messageTypeList: MessageTypeData[] = [];
for (const key in messageTypeData) {
if (messageTypeData.hasOwnProperty(key)) {
let name = 'A';
switch (key) {
case 'messageTypeAll':
name = MessageType.All;
break;
case 'messageTypeReceiving':
name = MessageType.Receive;
break;
case 'messageTypeOutgoing':
name = MessageType.Send;
break;
case 'messageTypeReservation':
name = MessageType.Reservation;
break;
}
messageTypeList.push({ displayName: messageTypeData[key], name });
}
}
this.messageTypeList = messageTypeList;
}
private convertDetailReceivertoUserInfo(base: MessageDetailInfo): UserInfo {
return {
seq: base.sendUserSeq,
name: base.sendUserName,
profileImageFile: '',
grade: '',
intro: '',
companyCode: '',
hpNumber: '',
lineNumber: '',
email: '',
isMobile: false,
deptName: '',
isFavorit: false,
isBuddy: false,
isActive: false,
roleCd: RoleCode.Self,
employeeNum: '',
madn: '',
hardSadn: '',
fmcSadn: '',
nameEn: '',
nameCn: '',
gradeEn: '',
gradeCn: '',
deptNameEn: '',
deptNameCn: '',
isPrivacyAgree: false,
isValidLogin: false,
employeeType: EmployeeType.Regular,
nickName: '',
order: ''
};
}
}