467 lines
12 KiB
TypeScript
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: ''
|
|
};
|
|
}
|
|
}
|