diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.html index 71ca26b3..f79dbd28 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.html @@ -162,6 +162,8 @@ (toggleAllUser)="onToggleAllUser($event)" (toggleUser)="onToggleUser($event)" (gotoDeptTree)="onClickGotoDeptTree($event)" + (sendCall)="onClickCall($event)" + (sendSms)="onClickSMS($event)" class="detail-table" > @@ -224,6 +226,16 @@ {{ 'organization.startVideoConference' | translate }} +
  • + +
  • diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.ts index 560d4af4..ba4aa9a5 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.ts @@ -5,7 +5,9 @@ import { OnDestroy, Output, EventEmitter, - ViewChild + ViewChild, + NgZone, + Inject } from '@angular/core'; import { SelectedDept, @@ -14,7 +16,15 @@ import { } from '@ucap-webmessenger/protocol-query'; import { NGXLogger } from 'ngx-logger'; import { TranslateService, LangChangeEvent } from '@ngx-translate/core'; -import { DialogService } from '@ucap-webmessenger/ui'; +import { + DialogService, + ConfirmDialogComponent, + ConfirmDialogResult, + ConfirmDialogData, + AlertDialogComponent, + AlertDialogResult, + AlertDialogData +} from '@ucap-webmessenger/ui'; import { SessionStorageService } from '@ucap-webmessenger/web-storage'; import { Store, select } from '@ngrx/store'; @@ -23,14 +33,20 @@ import * as SettingsStore from '@app/store/messenger/settings'; import * as SyncStore from '@app/store/messenger/sync'; import * as ChatStore from '@app/store/messenger/chat'; -import { Observable, Subscription, BehaviorSubject, merge } from 'rxjs'; +import { Observable, Subscription, BehaviorSubject, merge, of } from 'rxjs'; import { PresenceType, StatusCode } from '@ucap-webmessenger/core'; import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; -import { KEY_VER_INFO, KEY_AUTH_INFO, MainMenu } from '@app/types'; +import { + KEY_VER_INFO, + KEY_AUTH_INFO, + MainMenu, + EnvironmentsInfo, + KEY_ENVIRONMENTS_INFO +} from '@app/types'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; -import { tap } from 'rxjs/operators'; +import { tap, take, map, catchError } from 'rxjs/operators'; import { SelectGroupDialogComponent, SelectGroupDialogData, @@ -41,6 +57,17 @@ import { TranslateService as UCapTranslateService } from '@ucap-webmessenger/ui' import { FormControl } from '@angular/forms'; import { MatSelect } from '@angular/material/select'; import { MatOption } from '@angular/material/core'; +import { + MessageWriteDialogComponent, + MessageWriteDialogResult, + MessageWriteDialogData +} from '../../dialogs/message/message-write.dialog.component'; +import { + PromptMessageStatusCode, + CallService +} from '@ucap-webmessenger/api-prompt'; +import { SmsUtils } from '@ucap-webmessenger/daesang'; +import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; @Component({ selector: 'app-layout-messenger-organization', @@ -84,6 +111,7 @@ export class OrganizationComponent implements OnInit, OnDestroy { loginRes: LoginResponse; loginResSubscription: Subscription; + environmentsInfo: EnvironmentsInfo; sessionVerinfo: VersionInfo2Response; authInfo: AuthResponse; ucapLangChangeSubscription: Subscription; @@ -109,14 +137,21 @@ export class OrganizationComponent implements OnInit, OnDestroy { StatusCode = StatusCode; constructor( + @Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService, private store: Store, private sessionStorageService: SessionStorageService, private dialogService: DialogService, private translateService: TranslateService, private ucapTranslateService: UCapTranslateService, + private callService: CallService, private changeDetectorRef: ChangeDetectorRef, - private logger: NGXLogger + private logger: NGXLogger, + private ngZone: NgZone ) { + this.environmentsInfo = this.sessionStorageService.get( + KEY_ENVIRONMENTS_INFO + ); + this.sessionVerinfo = this.sessionStorageService.get( KEY_VER_INFO ); @@ -324,9 +359,124 @@ export class OrganizationComponent implements OnInit, OnDestroy { const targetUserSeqs = this.selectedUserList.map(userInfo => userInfo.seq); this.createConference.emit(targetUserSeqs); } + onClickMessage() { + this.ngZone.run(() => { + const receiverList: UserInfoSS[] = this.selectedUserList.slice(); + + if (receiverList.length > 0) { + this.dialogService.open< + MessageWriteDialogComponent, + MessageWriteDialogData, + MessageWriteDialogResult + >(MessageWriteDialogComponent, { + width: '600px', + height: '600px', + disableClose: true, + hasBackdrop: false, + data: { + loginRes: this.loginRes, + environmentsInfo: this.environmentsInfo, + receiverList + } + }); + } + }); + } onClickOpenProfile(userSeq: number) { this.openProfile.emit(userSeq); } + async onClickCall(calleeNumber: string) { + const madn = this.loginRes.madn; + if (!madn || madn.trim().length === 0) { + this.dialogService.open< + AlertDialogComponent, + AlertDialogData, + AlertDialogResult + >(AlertDialogComponent, { + data: { + title: this.translateService.instant('call.errors.label'), + html: this.translateService.instant('call.errors.cannotCallToUser') + } + }); + + return false; + } + + calleeNumber = calleeNumber.replace(/\D/g, ''); + + if (!!calleeNumber && calleeNumber.length > 0) { + const result = await this.dialogService.open< + ConfirmDialogComponent, + ConfirmDialogData, + ConfirmDialogResult + >(ConfirmDialogComponent, { + width: '360px', + data: { + title: this.translateService.instant('call.callTo'), + html: this.translateService.instant('call.callWithNumber', { + phoneNumber: calleeNumber + }) + } + }); + + if (!!result && !!result.choice && result.choice) { + this.callService + .sendCall({ + userSeq: this.loginRes.userSeq, + deviceType: this.environmentsInfo.deviceType, + tokenKey: this.loginRes.tokenString, + calleeNumber + }) + .pipe( + take(1), + map(res => { + if (res.responseCode === PromptMessageStatusCode.Success) { + this.logger.debug('SUCCESS'); + this.logger.debug(res); + } else { + this.logger.error(res); + } + }), + catchError(error => of(this.logger.debug(error))) + ) + .subscribe(); + } + } else { + this.dialogService.open< + AlertDialogComponent, + AlertDialogData, + AlertDialogResult + >(AlertDialogComponent, { + data: { + title: this.translateService.instant('call.errors.label'), + html: this.translateService.instant( + 'call.errors.cannotCallToUserWithoutPhomeNumber' + ) + } + }); + } + } + onClickSMS(employeeNum: string) { + const smsUtil = new SmsUtils( + this.sessionStorageService, + this.nativeService + ); + if (!smsUtil.getAuthSms()) { + this.dialogService.open< + AlertDialogComponent, + AlertDialogData, + AlertDialogResult + >(AlertDialogComponent, { + data: { + title: this.translateService.instant('sms.errors.label'), + html: this.translateService.instant('sms.errors.haveNoPermission') + } + }); + return false; + } + + smsUtil.openSendSms(this.loginRes.tokenString, employeeNum); + } onClickGotoDeptTree(deptSeq: number) { this.gotoDeptTree.emit(deptSeq); } diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.html index 69314fe7..f5096c23 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.html +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.html @@ -39,7 +39,8 @@ (openProfile)="onClickOpenProfile($event)" (toggleAllUser)="onToggleAllUser($event)" (toggleUser)="onToggleUser($event)" - class="detail-table" + (sendCall)="onClickCall($event)" + class="integrate-search-org detail-table" > @@ -115,12 +128,12 @@
    diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.scss b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.scss index 679adfc4..dc54373b 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.scss +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.scss @@ -10,7 +10,3 @@ color: #444444; } } - -.hideDialog { - display: none; -} diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.ts b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.ts index a8f9e671..28ee3546 100644 --- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.ts +++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/dialogs/search/integrated-search.dialog.component.ts @@ -3,7 +3,8 @@ import { OnInit, Inject, OnDestroy, - ChangeDetectorRef + ChangeDetectorRef, + NgZone } from '@angular/core'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { KEY_VER_INFO, MainMenu, KEY_AUTH_INFO } from '@app/types'; @@ -18,8 +19,8 @@ import * as SyncStore from '@app/store/messenger/sync'; import { UserInfoSS, AuthResponse } from '@ucap-webmessenger/protocol-query'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; -import { map, take, tap } from 'rxjs/operators'; -import { Subscription, Observable, BehaviorSubject } from 'rxjs'; +import { map, take, tap, catchError } from 'rxjs/operators'; +import { Subscription, Observable, BehaviorSubject, of } from 'rxjs'; import { EnvironmentsInfo, KEY_ENVIRONMENTS_INFO } from '@app/types'; import { NGXLogger } from 'ngx-logger'; import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native'; @@ -27,7 +28,15 @@ import { environment } from '../../../../../environments/environment'; import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { DaesangProtocolService } from '@ucap-webmessenger/daesang'; -import { DialogService } from '@ucap-webmessenger/ui'; +import { + DialogService, + AlertDialogComponent, + AlertDialogData, + AlertDialogResult, + ConfirmDialogComponent, + ConfirmDialogData, + ConfirmDialogResult +} from '@ucap-webmessenger/ui'; import { ProfileDialogComponent, ProfileDialogData, @@ -40,7 +49,16 @@ import { } from '../group/select-group.dialog.component'; import { TranslateService } from '@ngx-translate/core'; import { GroupDetailData } from '@ucap-webmessenger/protocol-sync'; -import { ConferenceService } from '@ucap-webmessenger/api-prompt'; +import { + ConferenceService, + PromptMessageStatusCode, + CallService +} from '@ucap-webmessenger/api-prompt'; +import { + MessageWriteDialogComponent, + MessageWriteDialogResult, + MessageWriteDialogData +} from '../message/message-write.dialog.component'; export interface IntegratedSearchDialogData { keyword: string; @@ -88,10 +106,12 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy { private dialogService: DialogService, private translateService: TranslateService, private conferenceService: ConferenceService, + private callService: CallService, private store: Store, private changeDetectorRef: ChangeDetectorRef, - private logger: NGXLogger + private logger: NGXLogger, + private ngZone: NgZone ) { this.environmentsInfo = this.sessionStorageService.get( KEY_ENVIRONMENTS_INFO @@ -282,6 +302,29 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy { }); } } + onClickMessage() { + this.ngZone.run(() => { + const receiverList: UserInfoSS[] = this.selectedUserList.slice(); + + if (receiverList.length > 0) { + this.dialogService.open< + MessageWriteDialogComponent, + MessageWriteDialogData, + MessageWriteDialogResult + >(MessageWriteDialogComponent, { + width: '600px', + height: '600px', + disableClose: true, + hasBackdrop: false, + data: { + loginRes: this.loginRes, + environmentsInfo: this.environmentsInfo, + receiverList + } + }); + } + }); + } onClickOpenProfile(userSeq: number) { if (!userSeq || userSeq < 0) { return; @@ -318,6 +361,77 @@ export class IntegratedSearchDialogComponent implements OnInit, OnDestroy { ) .subscribe(); } + async onClickCall(calleeNumber: string) { + const madn = this.loginRes.madn; + if (!madn || madn.trim().length === 0) { + this.dialogService.open< + AlertDialogComponent, + AlertDialogData, + AlertDialogResult + >(AlertDialogComponent, { + data: { + title: this.translateService.instant('call.errors.label'), + html: this.translateService.instant('call.errors.cannotCallToUser') + } + }); + + return false; + } + + calleeNumber = calleeNumber.replace(/\D/g, ''); + + if (!!calleeNumber && calleeNumber.length > 0) { + const result = await this.dialogService.open< + ConfirmDialogComponent, + ConfirmDialogData, + ConfirmDialogResult + >(ConfirmDialogComponent, { + width: '360px', + data: { + title: this.translateService.instant('call.callTo'), + html: this.translateService.instant('call.callWithNumber', { + phoneNumber: calleeNumber + }) + } + }); + + if (!!result && !!result.choice && result.choice) { + this.callService + .sendCall({ + userSeq: this.loginRes.userSeq, + deviceType: this.environmentsInfo.deviceType, + tokenKey: this.loginRes.tokenString, + calleeNumber + }) + .pipe( + take(1), + map(res => { + if (res.responseCode === PromptMessageStatusCode.Success) { + this.logger.debug('SUCCESS'); + this.logger.debug(res); + } else { + this.logger.error(res); + } + }), + catchError(error => of(this.logger.debug(error))) + ) + .subscribe(); + } + } else { + this.dialogService.open< + AlertDialogComponent, + AlertDialogData, + AlertDialogResult + >(AlertDialogComponent, { + data: { + title: this.translateService.instant('call.errors.label'), + html: this.translateService.instant( + 'call.errors.cannotCallToUserWithoutPhomeNumber' + ) + } + }); + } + } onClickHide(): void { this.dialogRef.addPanelClass('hideDialog'); diff --git a/projects/ucap-webmessenger-app/src/assets/i18n/en.json b/projects/ucap-webmessenger-app/src/assets/i18n/en.json index 50624275..65ad546b 100644 --- a/projects/ucap-webmessenger-app/src/assets/i18n/en.json +++ b/projects/ucap-webmessenger-app/src/assets/i18n/en.json @@ -77,6 +77,9 @@ "search": { "label": "User search", "searchFormPlaceholder": "Name, department, position, phone number, email", + "fold": "Folding", + "unfold": "Unfolding", + "clearAndColse": "Data clear & Close", "fieldProfile": "Profile", "fieldName": "Name", "fieldDeptartment": "Department", @@ -279,6 +282,8 @@ "addToGroup": "Add to group", "startChat": "Chat", "startVideoConference": "Video conference", + "startMessage": "Message", + "startSMS": "SMS", "makeExtensionCall": "Make extension call", "makeMobileCall": "Make mobile call", "sendMessage": "Send message", diff --git a/projects/ucap-webmessenger-app/src/assets/i18n/ko.json b/projects/ucap-webmessenger-app/src/assets/i18n/ko.json index ddd3d532..af76a184 100644 --- a/projects/ucap-webmessenger-app/src/assets/i18n/ko.json +++ b/projects/ucap-webmessenger-app/src/assets/i18n/ko.json @@ -77,6 +77,9 @@ "search": { "label": "사용자 검색", "searchFormPlaceholder": "이름, 부서, 직위, 전화번호, 이메일", + "fold": "접어두기", + "unfold": "펼쳐보기", + "clearAndColse": "검색 초기화 & 닫기", "fieldProfile": "프로필", "fieldName": "이름", "fieldDeptartment": "부서", @@ -279,6 +282,8 @@ "addToGroup": "그룹에 추가", "startChat": "대화", "startVideoConference": "화상회의", + "startMessage": "쪽지", + "startSMS": "SMS", "makeExtensionCall": "내선번호 전화걸기", "makeMobileCall": "모바일 전화걸기", "sendMessage": "쪽지 보내기", diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.html b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.html index 1e9de22a..cbc7114a 100644 --- a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.html +++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.html @@ -89,7 +89,7 @@
    {{ element.companyName }}
    -
    +
    {{ element.hpNumber | ucapStringFormatterPhone }}
    @@ -107,7 +107,7 @@
    {{ element.workplace }}
    -
    +
    {{ element.lineNumber | ucapStringFormatterPhone }}
    diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.scss b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.scss index 9fa4e3e1..e0967bb7 100644 --- a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.scss +++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.scss @@ -90,6 +90,8 @@ td.mat-cell { } &.profileInfo { + cursor: pointer; + .baseInfo { display: flex; width: 200px; @@ -103,6 +105,13 @@ td.mat-cell { } } } + + .hpNumber { + cursor: pointer; + } + .lineNumber { + cursor: pointer; + } } .work-status { @@ -127,3 +136,11 @@ td.mat-cell { justify-items: center; font-size: 1.1em; } + +::ng-deep .integrate-search-org { + td.mat-cell { + &.profileInfo { + cursor: initial !important; + } + } +} diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.ts b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.ts index 4ee94b96..262e81db 100644 --- a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.ts +++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.ts @@ -43,6 +43,10 @@ export class DetailTableComponent implements OnInit, OnDestroy { @Output() gotoDeptTree = new EventEmitter(); @Output() + sendCall = new EventEmitter(); + @Output() + sendSms = new EventEmitter(); + @Output() toggleAllUser = new EventEmitter<{ isChecked: boolean; userInfos: UserInfoSS[]; @@ -287,4 +291,17 @@ export class DetailTableComponent implements OnInit, OnDestroy { event.stopPropagation(); this.gotoDeptTree.emit(Number(deptSeq)); } + onClickCall(type: string, userInfo: UserInfoSS) { + let calleeNumber = ''; + + if (type === 'LINE') { + calleeNumber = userInfo.lineNumber; + } else { + calleeNumber = userInfo.hpNumber; + } + this.sendCall.emit(calleeNumber); + } + onClickSMS(userInfo: UserInfoSS) { + this.sendSms.emit(userInfo.employeeNum); + } } diff --git a/projects/ucap-webmessenger-ui/src/lib/components/integrated-search-form.component.html b/projects/ucap-webmessenger-ui/src/lib/components/integrated-search-form.component.html index 1ef80a41..c9f7afa9 100644 --- a/projects/ucap-webmessenger-ui/src/lib/components/integrated-search-form.component.html +++ b/projects/ucap-webmessenger-ui/src/lib/components/integrated-search-form.component.html @@ -15,6 +15,7 @@ class="icon-img" *ngIf="isShowOpenIcon" matSuffix + matTooltip="{{ 'search.unfold' | translate }}" (click)="onClickShowDialog()" >