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'; import { MatDialogRef } from '@angular/material/dialog'; 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; loginRes: LoginResponse; loginResSubscription: Subscription; sessionVerinfo: VersionInfo2Response; updateInfo$: Observable; 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 = ''; integratedIsShowOpenIcon = false; constructor( private store: Store, @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( 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( 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( 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( 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 url = link.url .replace(/(\(%USER_TOKEN%\))/g, token) .replace(/(\(%USER_ID%\))/g, loginId) .replace(/(\(%USER_PASS%\))/g, loginPw); 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.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(KEY_LOGIN_INFO); const environmentsInfo = this.sessionStorageService.get( 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 }) ); } onIntegratedSearch(keyword: string) { if (!keyword || keyword.trim().length === 0) { return; } this.integratedSearchWord = keyword; this.integratedIsShowOpenIcon = true; let interval = 0; let reopen = false; const matDialogRef: MatDialogRef< IntegratedSearchDialogComponent, IntegratedSearchDialogResult > = this.dialogService.getDialogById('IntegratedSearchDialog'); if (!!matDialogRef) { matDialogRef.close({ clear: false }); interval = 500; } setTimeout(async () => { const result = await this.dialogService.open< IntegratedSearchDialogComponent, IntegratedSearchDialogData, IntegratedSearchDialogResult >(IntegratedSearchDialogComponent, { height: '90vh', width: '90vw', data: { keyword }, restoreFocus: false, hasBackdrop: false, id: 'IntegratedSearchDialog' }); if (!!result) { this.integratedIsShowOpenIcon = false; if (!!result.clear) { this.integratedSearchWord = ''; } } }, interval); } onIntegratedDialogOpen() { const matDialogRef: MatDialogRef< IntegratedSearchDialogComponent, IntegratedSearchDialogResult > = this.dialogService.getDialogById('IntegratedSearchDialog'); if (!!matDialogRef) { matDialogRef.removePanelClass('hideDialog'); } } }