667 lines
18 KiB
TypeScript

import {
Component,
OnInit,
Inject,
OnDestroy,
ChangeDetectorRef,
ViewChild
} from '@angular/core';
import {
UCAP_NATIVE_SERVICE,
NativeService,
WindowState,
UpdateInfo
} from '@ucap-webmessenger/native';
import { Observable, Subscription, of } from 'rxjs';
import { Store, select } from '@ngrx/store';
import semver from 'semver';
import * as AppStore from '@app/store';
import * as ChatStore from '@app/store/messenger/chat';
import * as AuthenticationStore from '@app/store/account/authentication';
import * as SettingsStore from '@app/store/messenger/settings';
import * as UpdateStore from '@app/store/setting/update';
import * as SettingNativeStore from '@app/store/setting/native';
import * as StatusStore from '@app/store/messenger/status';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { tap, take, map, catchError } from 'rxjs/operators';
import {
RightDrawer,
KEY_URL_INFO,
LoginInfo,
KEY_LOGIN_INFO,
KEY_VER_INFO,
EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO
} from '@app/types';
import {
WebLink,
DaesangUrlInfoResponse
} from '@ucap-webmessenger/api-external';
import {
SessionStorageService,
LocalStorageService
} from '@ucap-webmessenger/web-storage';
import { AppUserInfo, KEY_APP_USER_INFO } from '@app/types/app-user-info.type';
import { environment } from '../../../../environments/environment';
import {
DaesangApiService,
DaesangProtocolService,
WebLinkType,
DaesangCipherService
} from '@ucap-webmessenger/daesang';
import { NGXLogger } from 'ngx-logger';
import {
VersionInfo2Response,
PublicApiService
} from '@ucap-webmessenger/api-public';
import {
ProfileDialogComponent,
ProfileDialogResult,
ProfileDialogData
} from '@app/layouts/messenger/dialogs/profile/profile.dialog.component';
import { DialogService } from '@ucap-webmessenger/ui';
import { DOCUMENT } from '@angular/common';
import { MatMenu, MatMenuTrigger } from '@angular/material/menu';
import { StatusCode, StatusType, WindowUtil } from '@ucap-webmessenger/core';
import {
StatusInfo,
MessageIndexType,
MessageUpdateRequest
} from '@ucap-webmessenger/protocol-status';
import {
IntegratedSearchDialogComponent,
IntegratedSearchDialogResult,
IntegratedSearchDialogData
} from '@app/layouts/messenger/dialogs/search/integrated-search.dialog.component';
import { MatRadioChange } from '@angular/material/radio';
const zoomFactors = [60, 70, 85, 100, 120, 145, 170, 200];
@Component({
selector: 'app-layout-native-top-bar',
templateUrl: './top-bar.component.html',
styleUrls: ['./top-bar.component.scss']
})
export class TopBarComponent implements OnInit, OnDestroy {
windowStateChanged$: Observable<WindowState>;
WindowState = WindowState;
loginRes: LoginResponse;
loginResSubscription: Subscription;
sessionVerinfo: VersionInfo2Response;
updateInfo$: Observable<UpdateInfo>;
myStatus: StatusInfo;
myStatusSubscription: Subscription;
myIdleCheckTime: number;
myIdleCheckTimeSubscription: Subscription;
zoom: number;
zoomSubscription: Subscription;
loginInfo: LoginInfo;
weblink: WebLink[] = [];
webLinkBadgeMail = 0;
webLinkBadgePayment = 0;
appVersion: string;
WebLinkType = WebLinkType;
StatusCode = StatusCode;
checkingUpdate = false;
checkingUpdateIsProcessing = false;
checkingUpdateAppVersion: string;
checkingUpdateIsExist = false;
readonly awayTimeList = [10, 20, 30];
@ViewChild('profileMenuTrigger', { static: false })
profileMenuTrigger: MatMenuTrigger;
@ViewChild('profileMenu', { static: true })
profileMenu: MatMenu;
integratedSearchWord = '';
constructor(
private store: Store<any>,
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private changeDetectorRef: ChangeDetectorRef,
private dialogService: DialogService,
private daesangCipherService: DaesangCipherService,
private localStorageService: LocalStorageService,
private sessionStorageService: SessionStorageService,
private publicApiService: PublicApiService,
private daesangApiService: DaesangApiService,
private daesangProtocolService: DaesangProtocolService,
@Inject(DOCUMENT) private document: Document,
private logger: NGXLogger
) {}
ngOnInit() {
this.windowStateChanged$ = this.nativeService.windowStateChanged();
this.loginResSubscription = this.store
.pipe(
select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
tap(loginRes => {
this.loginRes = loginRes;
this.loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
this.sessionVerinfo = this.sessionStorageService.get<
VersionInfo2Response
>(KEY_VER_INFO);
// WebLink init..
this.initWebLink(loginRes);
})
)
.subscribe();
this.myStatusSubscription = this.store
.pipe(select(AppStore.MessengerSelector.StatusSelector.selectMyStatus))
.subscribe(myStatus => {
this.myStatus = myStatus;
});
this.myIdleCheckTimeSubscription = this.store
.pipe(
select(AppStore.MessengerSelector.StatusSelector.selectMyIdleCheckTime)
)
.subscribe(myIdleCheckTime => {
this.myIdleCheckTime = myIdleCheckTime;
});
this.zoomSubscription = this.store
.pipe(select(AppStore.SettingSelector.NativeSelector.selectZoom))
.subscribe(zoom => {
this.zoom = zoom;
});
this.updateInfo$ = this.store.pipe(
select(AppStore.SettingSelector.UpdateSelector.updateInfo)
);
this.nativeService.getVersionInfo().then(ver => {
this.appVersion = ver;
});
}
ngOnDestroy(): void {
if (!!this.loginResSubscription) {
this.loginResSubscription.unsubscribe();
this.loginResSubscription = undefined;
}
if (!!this.myStatusSubscription) {
this.myStatusSubscription.unsubscribe();
this.myStatusSubscription = undefined;
}
if (!!this.myIdleCheckTimeSubscription) {
this.myIdleCheckTimeSubscription.unsubscribe();
this.myIdleCheckTimeSubscription = undefined;
}
if (!!this.zoomSubscription) {
this.zoomSubscription.unsubscribe();
this.zoomSubscription = undefined;
}
}
initWebLink(loginRes: LoginResponse): void {
if (!!loginRes) {
const urlInfo: DaesangUrlInfoResponse = this.sessionStorageService.get<
DaesangUrlInfoResponse
>(KEY_URL_INFO);
if (!!urlInfo && !!urlInfo.webLink) {
// order by webLinkAllowedList..
this.weblink = urlInfo.webLinkAllowedList
.filter(
showWebLink =>
urlInfo.webLink.filter(wl => wl.key === showWebLink).length > 0
)
.map(showWeblink =>
urlInfo.webLink.find(weblink => weblink.key === showWeblink)
);
if (urlInfo.webLinkAllowedList.indexOf(WebLinkType.Mail) > -1) {
// 메일 카운트 체크.
const link = urlInfo.webLink.filter(
weblink => weblink.key === WebLinkType.MailCnt
);
if (link.length > 0) {
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
KEY_APP_USER_INFO,
environment.customConfig.appKey
);
const WebLinkMailCnt = link[0];
const loginPw = appUserInfo.loginPw;
const loginPw2 = this.loginInfo.loginPw;
const loginId = this.loginInfo.loginId;
const token = loginRes.tokenString;
const url = WebLinkMailCnt.url
.replace(/(\(%USER_TOKEN%\))/g, token)
.replace(/(\(%USER_ID%\))/g, loginId)
.replace(/(\(%USER_PASS%\))/g, loginPw);
this.daesangApiService
.retrieveMailCount(url)
.pipe(
take(1),
map(res => (this.webLinkBadgeMail = res.count)),
catchError(error => of(this.logger.log(error)))
)
.subscribe();
}
}
if (urlInfo.webLinkAllowedList.indexOf(WebLinkType.Payment) > -1) {
// 결제 카운트 체크.
const link = urlInfo.webLink.filter(
weblink => weblink.key === WebLinkType.PaymentCnt
);
if (link.length > 0) {
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
KEY_APP_USER_INFO,
environment.customConfig.appKey
);
const WebLinkPaymentCnt = link[0];
const loginPw = appUserInfo.loginPw;
const loginPw2 = this.loginInfo.loginPw;
const loginId = this.loginInfo.loginId;
const token = loginRes.tokenString;
const url = WebLinkPaymentCnt.url
.replace(/(\(%USER_TOKEN%\))/g, token)
.replace(/(\(%USER_ID%\))/g, loginId)
.replace(/(\(%USER_PASS%\))/g, loginPw);
this.daesangApiService
.retrievePaymentCount(url)
.pipe(
take(1),
map(res => {
this.webLinkBadgePayment = res.count;
}),
catchError(error => of(this.logger.log(error)))
)
.subscribe();
}
}
}
}
}
onClickClose() {
this.nativeService.windowClose();
}
onClickMinimize() {
this.nativeService.windowMinimize();
}
onClickMaxmize() {
this.nativeService.windowMaximize();
}
onClickSettings(): void {
this.store.dispatch(SettingsStore.showDialog());
}
onClickLogout(): void {
this.store.dispatch(AuthenticationStore.logoutConfirmation());
}
onClickQuit(): void {
this.nativeService.appExit();
}
getMyProfileImageWidget(): string {
if (!!this.loginRes) {
return this.loginRes.userInfo.profileImageFile;
} else {
return '';
}
}
onClickOpenProfile(event: Event) {
// [GROUP]
// this.queryProtocolService
// .dataUser({
// divCd: 'OPENPROF',
// seq: userInfo.seq,
// senderCompanyCode: this.loginRes.userInfo.companyCode,
// senderEmployeeType: this.loginRes.userInfo.employeeType
// })
// .pipe(
// take(1),
// map(res => {
// if (!!res && !!res.userInfo) {
// this.dialogService.open<
// ProfileDialogComponent,
// ProfileDialogData,
// ProfileDialogResult
// >(ProfileDialogComponent, {
// data: {
// userInfo: res.userInfo
// }
// });
// }
// })
// )
// .subscribe();
event.preventDefault();
// [Daesang]
this.daesangProtocolService
.dataUserDaesang({
divCd: 'OPENPROF',
seq: this.loginRes.userSeq,
senderCompanyCode: this.loginRes.userInfo.companyCode,
senderEmployeeType: this.loginRes.userInfo.employeeType
})
.pipe(
take(1),
map(res => {
if (!!res && !!res.userInfo) {
this.dialogService.open<
ProfileDialogComponent,
ProfileDialogData,
ProfileDialogResult
>(ProfileDialogComponent, {
data: {
userInfo: res.userInfo
}
});
}
})
)
.subscribe();
}
onClickNotice(): void {
this.store.dispatch(
ChatStore.selectedRightDrawer({
req: RightDrawer.Notice
})
);
}
/** About WebLink */
onClickWebLink(link: WebLink): void {
const appUserInfo = this.localStorageService.encGet<AppUserInfo>(
KEY_APP_USER_INFO,
environment.customConfig.appKey
);
const loginPw = appUserInfo.loginPw;
const loginPw2 = this.loginInfo.loginPw;
const loginId = this.loginInfo.loginId;
const token = this.loginRes.tokenString;
const erpPw = this.daesangCipherService.encryptForSapErp(
'aes256-daesang-key!!',
this.loginRes.userInfo.employeeNum
);
const url = link.url
.replace(/(\(%USER_TOKEN%\))/g, token)
.replace(/(\(%USER_ID%\))/g, loginId)
.replace(/(\(%USER_PASS%\))/g, loginPw)
.replace(/(\(%ENC_PASSWD%\))/g, erpPw);
let width = 1160;
let height = 800;
let openType = 'INNER-POPUP';
switch (link.key) {
case WebLinkType.Sms:
/** SMS URL */
{
width = 685;
height = 640;
}
break;
// case WebLinkType.Itsvcdesk:
// /** IT서비스데스크 URL */
// {
// width = 1400;
// height = 1000;
// }
// break;
case WebLinkType.Conf:
/** 화상회의 URL */
{
}
break;
case WebLinkType.Itsvcdesk:
/** IT서비스데스크 URL */
case WebLinkType.Dsp:
/** DSP URL */
case WebLinkType.Webhard:
/** 웹하드 URL */
case WebLinkType.Ep:
/** EP URL */
case WebLinkType.Sop:
/** S&OP회의 URL */
case WebLinkType.Som:
/** S&OM회의 URL */
case WebLinkType.Elephant:
/** 코끼리 URL */
case WebLinkType.UrgntNews:
/** 개인속보 URL */
case WebLinkType.MailCnt:
/** 메일Count URL */
case WebLinkType.Mail:
/** 메일 링크 URL */
case WebLinkType.PaymentCnt:
/** 결재Count URL */
case WebLinkType.Payment:
/** 결재링크 URL */
case WebLinkType.Erp:
/** Erp URL */
case WebLinkType.ChgPassword:
/** 비밀번호변경 URL ; PC 메신저만 해당 비밀번호 만료시 */
{
openType = 'DEFAULT-BROWSER';
}
break;
}
if (openType === 'DEFAULT-BROWSER') {
// // Old popup open.. >> default browser open.
// this.nativeService.openDefaultBrowser(url, {
// features:
// 'menubar=no,location=no,resizable=yes,scrollbars=yes,status=no,width=400,height=400'
// });
this.nativeService.openDefaultBrowser(url);
} else {
WindowUtil.popupOpen(url, link.title, width, height);
}
}
onClosedProfileMenu() {
this.checkingUpdate = false;
this.checkingUpdateIsProcessing = false;
this.checkingUpdateAppVersion = undefined;
this.checkingUpdateIsExist = false;
}
onClickUpdate() {
this.store.dispatch(UpdateStore.applyInstantUpdate());
}
onClickZoomOut(event: Event) {
const i = zoomFactors.indexOf(this.zoom);
if (-1 === i || 0 === i) {
return;
}
const zoom = zoomFactors[i - 1];
this.store.dispatch(SettingNativeStore.changeZoom({ zoom }));
}
onClickZoomLabel(event: Event) {
this.store.dispatch(SettingNativeStore.changeZoom({ zoom: 100 }));
}
onClickZoomIn(event: Event) {
const i = zoomFactors.indexOf(this.zoom);
if (-1 === i || zoomFactors.length - 1 === i) {
return;
}
const zoom = zoomFactors[i + 1];
this.store.dispatch(SettingNativeStore.changeZoom({ zoom }));
}
onClickRemoteSupport(event: Event) {
this.nativeService.executeProcess('AeroAdmin');
}
onClickStatusOnline(event: Event) {
this.store.dispatch(
StatusStore.status({
req: {
statusDivisionType: StatusType.Messenger,
statusType: StatusCode.OnLine
}
})
);
}
onClickStatusAway(event: Event) {
this.store.dispatch(
StatusStore.status({
req: {
statusDivisionType: StatusType.Messenger,
statusType: StatusCode.Away
}
})
);
}
onClickStatusBusy(event: Event, index: number) {
let statusMessage = '';
switch (index) {
case 1:
statusMessage = this.loginRes.statusMessage1;
break;
case 2:
statusMessage = this.loginRes.statusMessage2;
break;
case 3:
statusMessage = this.loginRes.statusMessage3;
break;
}
this.store.dispatch(
StatusStore.status({
req: {
statusDivisionType: StatusType.Messenger,
statusType: StatusCode.Busy,
statusMessage
}
})
);
}
onApplyStatusMessage(index: MessageIndexType, statusMessage: string) {
this.logger.debug('StatusMessage', index, statusMessage);
this.store.dispatch(
StatusStore.messageUpdate({
index,
statusMessage
} as MessageUpdateRequest)
);
}
onClickChangeStatusBusy(event: Event, index: number) {
event.stopPropagation();
}
onChangeAwayTime(event: MatRadioChange) {
this.store.dispatch(
StatusStore.changeMyIdleCheckTime({ checkTime: Number(event.value) })
);
}
onMenuOpenedinformationMenu() {
if (this.checkingUpdate) {
return;
}
this.checkForUpdates();
}
checkForUpdates() {
this.checkingUpdate = true;
this.checkingUpdateIsProcessing = true;
const loginInfo = this.sessionStorageService.get<LoginInfo>(KEY_LOGIN_INFO);
const environmentsInfo = this.sessionStorageService.get<EnvironmentsInfo>(
KEY_ENVIRONMENTS_INFO
);
this.publicApiService
.versionInfo2({
deviceType: environmentsInfo.deviceType,
companyGroupType: loginInfo.companyGroupType,
companyCode: loginInfo.companyCode,
loginId: loginInfo.loginId
})
.pipe(take(1))
.subscribe(
res => {
this.checkingUpdateAppVersion = res.appVersion;
if (semver.lt(this.appVersion, res.appVersion)) {
this.checkingUpdateIsExist = true;
} else {
this.checkingUpdateIsExist = false;
}
},
error => {},
() => {
this.checkingUpdateIsProcessing = false;
}
);
}
onClickApplyUpdate(event: Event) {
// this.profileMenuTrigger.closeMenu();
this.store.dispatch(
UpdateStore.applyUpdate({ currentVersion: this.checkingUpdateAppVersion })
);
}
async onIntegratedSearch(keyword: string) {
if (!keyword || keyword.trim().length === 0) {
return;
}
this.integratedSearchWord = keyword;
const result = await this.dialogService.open<
IntegratedSearchDialogComponent,
IntegratedSearchDialogData,
IntegratedSearchDialogResult
>(IntegratedSearchDialogComponent, {
data: {
keyword
},
restoreFocus: false
});
this.integratedSearchWord = '';
}
}