next-ucap-messenger/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/chat/create-chat.dialog.component.ts
2019-11-04 11:36:58 +09:00

469 lines
13 KiB
TypeScript

import { UserSelectDialogType } from './../../../../types/userselect.dialog.type';
import {
Component,
OnInit,
OnDestroy,
Inject,
EventEmitter
} from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {
MatDialogRef,
MAT_DIALOG_DATA,
MatTabChangeEvent
} from '@angular/material';
import { NGXLogger } from 'ngx-logger';
import { Observable, combineLatest, Subscription, of } from 'rxjs';
import { map, tap, catchError } from 'rxjs/operators';
import { Store, select } from '@ngrx/store';
import * as AppStore from '@app/store';
import * as QueryStore from '@app/store/messenger/query';
import * as StatusStore from '@app/store/messenger/status';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { Company } from '@ucap-webmessenger/api-external';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
import { KEY_VER_INFO } from '@app/types/ver-info.type';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import {
UserInfo,
GroupDetailData,
RoomUserDetailData,
RoomUserData
} from '@ucap-webmessenger/protocol-sync';
import {
DeptSearchType,
UserInfoSS,
UserInfoF,
UserInfoDN,
QueryProtocolService,
SSVC_TYPE_QUERY_DEPT_USER_DATA,
DeptUserData,
SSVC_TYPE_QUERY_DEPT_USER_RES
} from '@ucap-webmessenger/protocol-query';
import {
RoomInfo,
UserInfoShort,
UserInfo as RoomUserInfo
} from '@ucap-webmessenger/protocol-room';
export interface CreateChatDialogData {
type?: string;
title: string;
/** CASE :: EditMember */
group?: GroupDetailData;
/** CASE :: EventForward */
ignoreRoom?: RoomInfo[];
/** CASE :: EditCharMember */
curRoomUser?: (
| UserInfo
| UserInfoSS
| UserInfoF
| UserInfoDN
| RoomUserInfo)[];
}
export interface CreateChatDialogResult {
choice: boolean;
selectedUserList?: (
| UserInfo
| UserInfoSS
| UserInfoF
| UserInfoDN
| RoomUserInfo)[];
selectedRoom?: RoomInfo;
groupName?: string;
oldGroup?: GroupDetailData;
}
@Component({
selector: 'app-layout-messenger-create-chat',
templateUrl: './create-chat.dialog.component.html',
styleUrls: ['./create-chat.dialog.component.scss']
})
export class CreateChatDialogComponent implements OnInit, OnDestroy {
constructor(
public dialogRef: MatDialogRef<
CreateChatDialogData,
CreateChatDialogResult
>,
@Inject(MAT_DIALOG_DATA) public data: CreateChatDialogData,
private store: Store<any>,
private sessionStorageService: SessionStorageService,
private queryProtocolService: QueryProtocolService,
private formBuilder: FormBuilder,
private logger: NGXLogger
) {
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
KEY_VER_INFO
);
}
UserSelectDialogType = UserSelectDialogType;
loginRes: LoginResponse;
loginResSubscription: Subscription;
sessionVerinfo: VersionInfo2Response;
// 검색
isShowSearch = false;
searchProcessing = false;
searchUserInfos: UserInfoSS[] = [];
// 그룹
companyList$: Observable<Company[]>;
companyCode: string;
groupBuddyList$: Observable<
{ group: GroupDetailData; buddyList: UserInfo[] }[]
>;
favoritBuddyList$: Observable<UserInfo[]>;
// 대화방
roomList: RoomInfo[];
roomUserList: RoomUserDetailData[];
roomUserShortList: RoomUserData[];
roomSubscription: Subscription;
// 수집 데이터
selectedUserList: (
| UserInfo
| UserInfoSS
| UserInfoF
| UserInfoDN
| RoomUserInfo)[] = [];
isShowSelectedUserList = true;
selectedRoom: RoomInfo;
inputForm: FormGroup;
ngOnInit() {
const loginInfo = this.sessionStorageService.get<LoginInfo>(KEY_LOGIN_INFO);
this.companyCode = loginInfo.companyCode;
this.companyList$ = this.store.pipe(
select(AppStore.SettingSelector.CompanySelector.companyList)
);
this.loginResSubscription = this.store
.pipe(
select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
tap(loginRes => {
this.loginRes = loginRes;
})
)
.subscribe();
this.groupBuddyList$ = combineLatest([
this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.selectAllBuddy2)
),
this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.selectAllGroup2)
)
]).pipe(
map(([buddyList, groupList]) => {
const groupBuddyList: {
group: GroupDetailData;
buddyList: UserInfo[];
}[] = [];
for (const group of groupList) {
const data = {
group,
buddyList: buddyList.filter(buddy => {
return group.userSeqs.indexOf(buddy.seq) > -1;
})
};
groupBuddyList.push(data);
/** 그룹 멤버 변경일 경우 그룹원을 기본 셀렉트 한다. */
if (
this.data.type === UserSelectDialogType.EditMember &&
!!this.data.group &&
this.data.group.seq === group.seq
) {
this.selectedUserList = [...data.buddyList];
}
}
return groupBuddyList;
})
);
this.favoritBuddyList$ = this.store
.pipe(select(AppStore.MessengerSelector.SyncSelector.selectAllBuddy2))
.pipe(
map(buddyInfoList => {
return buddyInfoList
.filter(buddy => buddy.isFavorit)
.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
})
);
this.roomSubscription = combineLatest([
this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.selectAllRoom)
),
this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.selectAllRoomUser)
),
this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.selectAllRoomUserShort)
)
])
.pipe(
tap(([room, roomUser, roomUserShort]) => {
this.roomList = room;
this.roomUserList = roomUser;
this.roomUserShortList = roomUserShort;
})
)
.subscribe();
this.inputForm = this.formBuilder.group({
groupName: ['', [Validators.required]]
});
if (this.data.type === UserSelectDialogType.EditChatMember) {
this.selectedUserList = this.data.curRoomUser;
}
}
ngOnDestroy(): void {
if (!!this.roomSubscription) {
this.roomSubscription.unsubscribe();
}
if (!!this.loginResSubscription) {
this.loginResSubscription.unsubscribe();
}
}
getRoomUserList(roomInfo: RoomInfo): RoomUserInfo[] | UserInfoShort[] {
if (!!this.roomUserList && 0 < this.roomUserList.length) {
const i = this.roomUserList.findIndex(
value => roomInfo.roomSeq === value.roomSeq
);
if (-1 < i) {
return this.roomUserList[i].userInfos;
}
}
if (!!this.roomUserShortList && 0 < this.roomUserShortList.length) {
const i = this.roomUserShortList.findIndex(
value => roomInfo.roomSeq === value.roomSeq
);
if (-1 < i) {
return this.roomUserShortList[i].userInfos;
}
}
}
getChipsRemoveYn(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
if (
this.data.type === UserSelectDialogType.EditChatMember &&
!!this.data.curRoomUser &&
this.data.curRoomUser.length > 0
) {
return !(
this.data.curRoomUser.filter(user => user.seq === userInfo.seq).length >
0
);
} else {
return true;
}
}
onSelectedTabChange(tabChangeEvent: MatTabChangeEvent): void {
if (tabChangeEvent.index === 2) {
this.selectedUserList = [];
this.isShowSelectedUserList = false;
} else {
this.selectedRoom = null;
this.isShowSelectedUserList = true;
}
}
/** 유저검색 */
onKeyDownEnterOrganizationTenantSearch(params: {
companyCode: string;
searchWord: string;
}) {
if (params.searchWord.trim().length > 1) {
this.isShowSearch = true;
this.searchProcessing = true;
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:
searchUserInfos.push(...(res as DeptUserData).userInfos);
break;
case SSVC_TYPE_QUERY_DEPT_USER_RES:
{
// 검색 결과 처리.
this.searchUserInfos = searchUserInfos;
this.searchProcessing = false;
// 검색 결과에 따른 프레즌스 조회.
const userSeqList: number[] = [];
this.searchUserInfos.map(user => userSeqList.push(user.seq));
if (userSeqList.length > 0) {
this.store.dispatch(
StatusStore.bulkInfo({
divCd: 'groupSrch',
userSeqs: userSeqList
})
);
}
}
break;
}
}),
catchError(error => {
this.searchProcessing = false;
return of(this.logger.error(error));
})
)
.subscribe();
}
}
/** 검색 취소 */
onClickCancel() {
this.isShowSearch = false;
this.searchUserInfos = [];
}
/** 동료그룹 :: 그룹의 checkbox 의 이벤트를 받아 선택된 유저리스트를 수집. */
onCheckGroup(params: {
isChecked: boolean;
groupBuddyList: { group: GroupDetailData; buddyList: UserInfo[] };
}) {
if (params.isChecked) {
params.groupBuddyList.buddyList.forEach(item => {
if (
this.selectedUserList.filter(user => user.seq === item.seq).length ===
0
) {
this.selectedUserList = [...this.selectedUserList, item];
}
});
} else {
this.selectedUserList = this.selectedUserList.filter(
item =>
params.groupBuddyList.buddyList.filter(del => del.seq === item.seq)
.length === 0
);
}
}
onCheckAllUser(params: {
isChecked: boolean;
userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[];
}) {
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
);
}
});
}
/** 동료그룹>부서원, 조직도>부서원 :: 리스트의 checkbox 의 이벤트를 받아 선택된 유저리스트를 수집. */
onCheckUser(params: {
isChecked: boolean;
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
}) {
if (params.isChecked) {
if (
this.selectedUserList.filter(user => user.seq === params.userInfo.seq)
.length === 0 &&
params.userInfo
) {
this.selectedUserList = [...this.selectedUserList, params.userInfo];
}
} else {
this.selectedUserList = this.selectedUserList.filter(
item => item.seq !== params.userInfo.seq
);
}
}
/** 대화방 > 대화방 선택 :: 해당 팝업에서는 대화방을 중복 선택하지 않는다 */
onCheckRoom(params: { isChecked: boolean; roomInfo: RoomInfo }) {
if (params.isChecked) {
this.selectedRoom = params.roomInfo;
} else {
this.selectedRoom = null;
}
}
/** 그룹>부서원 리스트의 ischecked 를 판단. */
getCheckedUser(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
return (
this.selectedUserList.filter(item => item.seq === userInfo.seq).length >
0
);
}
return false;
}
getCheckableRoom(roomInfo: RoomInfo) {
if (!!this.data.ignoreRoom && this.data.ignoreRoom.length > 0) {
return !(
this.data.ignoreRoom.filter(room => room.roomSeq === roomInfo.roomSeq)
.length > 0
);
}
return true;
}
getCheckedRoom(roomInfo: RoomInfo) {
if (!!this.selectedRoom) {
return this.selectedRoom.roomSeq === roomInfo.roomSeq;
}
return false;
}
/** 선택된 사용자 취소 */
onClickDeleteUser(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
this.selectedUserList = this.selectedUserList.filter(
item => item.seq !== userInfo.seq
);
}
/** 팝업의 선택 이벤트 전달. */
onClickChoice(choice: boolean): void {
this.dialogRef.close({
choice,
selectedUserList: this.selectedUserList,
selectedRoom: this.selectedRoom,
groupName:
this.data.type === UserSelectDialogType.NewGroup
? this.inputForm.get('groupName').value
: '',
oldGroup:
this.data.type === UserSelectDialogType.EditMember
? this.data.group
: undefined
});
}
}