화상회의 상세보기 팝업 작성.

This commit is contained in:
leejinho 2020-02-24 09:38:44 +09:00
parent b08f37f375
commit d9b512df45
17 changed files with 389 additions and 21 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "ucap-webmessenger", "name": "ucap-webmessenger",
"version": "1.0.1", "version": "1.0.2",
"author": { "author": {
"name": "LG CNS", "name": "LG CNS",
"email": "lgucap@lgcns.com" "email": "lgucap@lgcns.com"

View File

@ -27,4 +27,17 @@ export class JsonAnalization {
throw new Error('Invalid Json String'); throw new Error('Invalid Json String');
} }
} }
/**
* Convert String Array from String array type Raw strings.
*/
public static convertStringToArray(str: string): string[] {
let rtnArr: string[] = [];
try {
rtnArr = str.replace(/([\[\]"])/gi, '').split(',');
} catch (e) {}
return rtnArr;
}
} }

View File

@ -214,6 +214,8 @@
(massTranslationDetail)="onMassTranslationDetail($event)" (massTranslationDetail)="onMassTranslationDetail($event)"
(save)="onSave($event)" (save)="onSave($event)"
(fileViewer)="onFileViewer($event)" (fileViewer)="onFileViewer($event)"
(conferenceDetail)="onClickConferenceDetail($event)"
(conferenceJoin)="onClickConferenceJoin($event)"
(contextMenu)="onContextMenuMessage($event)" (contextMenu)="onContextMenuMessage($event)"
(openProfile)="onClickOpenProfile($event)" (openProfile)="onClickOpenProfile($event)"
(scrollUp)="onScrollupMessages($event)" (scrollUp)="onScrollupMessages($event)"

View File

@ -45,7 +45,8 @@ import {
StickerEventJson, StickerEventJson,
MassTextEventJson, MassTextEventJson,
TranslationEventJson, TranslationEventJson,
MassTranslationEventJson MassTranslationEventJson,
VideoConferenceEventJson
} from '@ucap-webmessenger/protocol-event'; } from '@ucap-webmessenger/protocol-event';
import * as AppStore from '@app/store'; import * as AppStore from '@app/store';
@ -128,6 +129,11 @@ import {
} from '../dialogs/chat/clipboard.dialog.component'; } from '../dialogs/chat/clipboard.dialog.component';
import { AppFileService } from '@app/services/file.service'; import { AppFileService } from '@app/services/file.service';
import { FileType } from '@ucap-webmessenger/protocol-file'; import { FileType } from '@ucap-webmessenger/protocol-file';
import {
ConferenceDetailDialogComponent,
ConferenceDetailDialogResult,
ConferenceDetailDialogData
} from '../dialogs/conference/conference-detail.dialog.component';
@Component({ @Component({
selector: 'app-layout-messenger-messages', selector: 'app-layout-messenger-messages',
@ -1197,6 +1203,27 @@ export class MessagesComponent implements OnInit, OnDestroy, AfterViewInit {
); );
} }
/** [Event] Conference Detail View */
onClickConferenceDetail(param: VideoConferenceEventJson) {
this.dialogService.open<
ConferenceDetailDialogComponent,
ConferenceDetailDialogData,
ConferenceDetailDialogResult
>(ConferenceDetailDialogComponent, {
width: '600px',
hasBackdrop: false,
data: {
detail: param
}
});
}
/** [Event] Conference Join */
onClickConferenceJoin(param: VideoConferenceEventJson) {
// this.conferenceJoin.emit(param);
console.log('aaa', param);
}
onContextMenuMessage(params: { onContextMenuMessage(params: {
event: MouseEvent; event: MouseEvent;
message: Info<EventJson>; message: Info<EventJson>;

View File

@ -0,0 +1,78 @@
<mat-card class="confirm-card mat-elevation-z">
<mat-card-header>
<mat-card-title
cdkDrag
cdkDragRootElement=".cdk-overlay-pane"
cdkDragHandle
>
<ng-container [ngSwitch]="conferenceDetail.contents">
<span *ngSwitchCase="VideoConferenceContentsType.Now">{{
'conference.videoConferenceTypeNow' | translate
}}</span>
<span *ngSwitchCase="VideoConferenceContentsType.New">{{
'conference.videoConferenceTypeNew' | translate
}}</span>
<span *ngSwitchCase="VideoConferenceContentsType.Update">{{
'conference.videoConferenceTypeUpdate' | translate
}}</span>
<span *ngSwitchCase="VideoConferenceContentsType.Delete">{{
'conference.videoConferenceTypeDelete' | translate
}}</span>
</ng-container>
</mat-card-title>
<button class="icon-button btn-dialog-close" (click)="onClickConfirm()">
<i class="mdi mdi-window-close"></i>
</button>
</mat-card-header>
<mat-card-content class="message-container">
<div fxFlex fxLayout="column" fxLayoutAlign="stretch" class="message-info">
<div class="title text-accent-darkest">
{{ conferenceDetail.title }}
</div>
<div class="normal">
<span class="normal label bg-accent-color">{{ 'conference.videoConferenceRegister' | translate}}</span>
<span class="name">{{ conferenceDetail.register }}</span>
</div>
<div class="underline">
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<span class="label bg-accent-color bg-warn-color">{{ 'conference.videoConferenceAttendee' | translate}}</span>
</mat-panel-title>
<mat-panel-description>
{{ conferenceDetail.attendee }}
</mat-panel-description>
</mat-expansion-panel-header>
<mat-chip-list>
<mat-chip *ngFor="let attendee of conferenceDetail.attendees">{{
attendee
}}</mat-chip>
</mat-chip-list>
</mat-expansion-panel>
</mat-accordion>
</div>
<div class="normal">
<span class="label bg-accent-color">{{ 'conference.videoConferenceDate' | translate}}</span>
<span
>{{
conferenceDetail.startDate | ucapDate: 'YYYY.MM.DD (ddd) a hh:mm'
}}
~
{{
conferenceDetail.endDate | ucapDate: 'YYYY.MM.DD (ddd) a hh:mm'
}}</span
>
</div>
<div class="underline">
<span class="label bg-accent-color">{{ 'conference.videoConferenceRoom' | translate}}</span>
<span>{{ getJoinArray(conferenceDetail.conferenceRooms) }}</span>
</div>
</div>
</mat-card-content>
<mat-card-actions class="button-farm flex-row">
<button mat-stroked-button (click)="onClickConfirm()" class="mat-primary">
{{ 'common.messages.confirm' | translate }}
</button>
</mat-card-actions>
</mat-card>

View File

@ -0,0 +1,125 @@
.mat-card-header {
.mat-card-header-text {
margin: 0;
}
.btn-dialog-close {
font-size: 20px;
display: flex;
margin-left: auto;
align-self: flex-start;
color: #444444;
}
}
.confirm-card {
min-width: 500px;
.button-farm {
text-align: right;
.mat-primary {
margin-left: 4px;
}
}
}
.message-container {
background-color: #ffffff !important;
.message-info {
.title {
display: flex;
flex-flow: row;
align-items: center;
font-size: 18px;
font-weight: 600;
padding: 10px 0 6px;
line-height: 24px;
color: #222222;
border-bottom: 1px solid #dddddd;
.btn-menu {
margin-left: auto;
color: #333333;
}
}
.normal {
display: flex;
flex-flow: row;
align-items: center;
padding-top: 10px;
padding-bottom: 14px;
font-size: 1em;
.label {
display: inline-flex;
flex: 0 0 auto;
border-radius: 14px;
padding: 2px 10px;
margin-right: 10px;
color: #ffffff;
line-height: 20px;
width: 120px;
justify-content: center;
}
.name {
display: inline-flex;
flex: 1 1 auto;
}
}
.underline {
border-bottom: 1px solid #dddddd;
padding-bottom: 10px;
font-size: 1em;
.label {
display: inline-block;
border-radius: 14px;
padding: 2px 10px;
margin-right: 10px;
color: #ffffff;
line-height: 20px;
width: 120px;
text-align: center;
}
}
.ps {
align-items: flex-start;
}
.attachFile {
border-top: 1px solid #dddddd;
.attachFileList {
height: 80px;
li {
display: flex;
flex-flow: row;
line-height: 2em;
flex: 1 1 auto;
margin-right: 10px;
.file-name {
display: inline-flex;
flex-flow: row;
flex: 1 1 auto;
border: 1px solid red;
white-space: nowrap;
word-wrap: normal;
overflow: hidden;
margin-right: 10px;
span:last-child {
overflow: hidden;
text-overflow: ellipsis;
display: block;
width: calc(100% - 40px);
}
}
.file-size {
display: flex;
margin-left: auto;
align-self: flex-end;
flex: 0 0 auto;
}
a {
display: inline-block;
width: 20px;
height: 100%;
margin-left: 10px;
}
}
}
}
}
}

View File

@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ConferenceDetailDialogComponent } from './conference-detail.dialog.component';
describe('app::layouts::messenger::MessageDetailDialogComponent', () => {
let component: ConferenceDetailDialogComponent;
let fixture: ComponentFixture<ConferenceDetailDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ConferenceDetailDialogComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ConferenceDetailDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,48 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DialogService, SnackBarService } from '@ucap-webmessenger/ui';
import { NGXLogger } from 'ngx-logger';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import { TranslateService } from '@ngx-translate/core';
import { VideoConferenceEventJson } from '@ucap-webmessenger/protocol-event';
import { VideoConferenceContentsType } from '@ucap-webmessenger/protocol-event';
export interface ConferenceDetailDialogData {
detail: VideoConferenceEventJson;
}
export interface ConferenceDetailDialogResult {}
@Component({
selector: 'app-layout-messenger-conference-detail',
templateUrl: './conference-detail.dialog.component.html',
styleUrls: ['./conference-detail.dialog.component.scss']
})
export class ConferenceDetailDialogComponent implements OnInit {
conferenceDetail: VideoConferenceEventJson;
VideoConferenceContentsType = VideoConferenceContentsType;
constructor(
public dialogRef: MatDialogRef<
ConferenceDetailDialogData,
ConferenceDetailDialogResult
>,
@Inject(MAT_DIALOG_DATA) public data: ConferenceDetailDialogData,
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private translateService: TranslateService
) {}
ngOnInit(): void {
this.conferenceDetail = this.data.detail;
}
getJoinArray(arr: string[]): string {
return arr.join(',');
}
onClickConfirm(): void {
this.dialogRef.close({});
}
}

View File

@ -0,0 +1,3 @@
import { ConferenceDetailDialogComponent } from './conference-detail.dialog.component';
export const DIALOGS = [ConferenceDetailDialogComponent];

View File

@ -1,5 +1,6 @@
import { DIALOGS as ACCOUNT_DIALOGS } from './account'; import { DIALOGS as ACCOUNT_DIALOGS } from './account';
import { DIALOGS as CHAT_DIALOGS } from './chat'; import { DIALOGS as CHAT_DIALOGS } from './chat';
import { DIALOGS as CONFERENCE_DIALOGS } from './conference';
import { DIALOGS as GROUP_DIALOGS } from './group'; import { DIALOGS as GROUP_DIALOGS } from './group';
import { DIALOGS as MESSAGE_DIALOGS } from './message'; import { DIALOGS as MESSAGE_DIALOGS } from './message';
import { DIALOGS as NOTICE_DIALOGS } from './notice'; import { DIALOGS as NOTICE_DIALOGS } from './notice';
@ -11,6 +12,7 @@ import { DIALOGS as SETTINGS_DIALOGS } from './settings';
export const DIALOGS = [ export const DIALOGS = [
...ACCOUNT_DIALOGS, ...ACCOUNT_DIALOGS,
...CHAT_DIALOGS, ...CHAT_DIALOGS,
...CONFERENCE_DIALOGS,
...GROUP_DIALOGS, ...GROUP_DIALOGS,
...MESSAGE_DIALOGS, ...MESSAGE_DIALOGS,
...NOTICE_DIALOGS, ...NOTICE_DIALOGS,

View File

@ -10,6 +10,8 @@ export interface VideoConferenceEventJson {
endDate?: string; endDate?: string;
register?: string; register?: string;
attendee?: string; attendee?: string;
attendees?: string[];
conferenceRooms?: string[];
} }
export const decodeVideoConferenceEventJson: EventJsonDecoder<VideoConferenceEventJson> = ( export const decodeVideoConferenceEventJson: EventJsonDecoder<VideoConferenceEventJson> = (
@ -19,13 +21,15 @@ export const decodeVideoConferenceEventJson: EventJsonDecoder<VideoConferenceEve
const json = JsonAnalization.receiveAnalization(message); const json = JsonAnalization.receiveAnalization(message);
return { return {
conferenceSeq: Number(json.confSeq), conferenceSeq: Number(json.roomSeq),
title: json.title, title: json.title,
contents: json.contents, contents: json.contents,
startDate: json.startDate, startDate: json.startDate,
endDate: json.endDate, endDate: json.endDate,
register: json.register, register: json.register,
attendee: json.attendee attendee: json.attendee,
attendees: JsonAnalization.convertStringToArray(json.attendees),
conferenceRooms: JsonAnalization.convertStringToArray(json.videoRooms)
} as VideoConferenceEventJson; } as VideoConferenceEventJson;
} catch (e) { } catch (e) {
return {} as VideoConferenceEventJson; return {} as VideoConferenceEventJson;

View File

@ -166,6 +166,8 @@
<ucap-chat-message-box-video-conference <ucap-chat-message-box-video-conference
*ngSwitchCase="EventType.VideoConference" *ngSwitchCase="EventType.VideoConference"
[message]="message" [message]="message"
(conferenceDetail)="onClickConferenceDetail($event)"
(conferenceJoin)="onClickConferenceJoin($event)"
> >
</ucap-chat-message-box-video-conference> </ucap-chat-message-box-video-conference>

View File

@ -15,10 +15,10 @@ import { shakeAnimation } from 'angular-animations';
import { import {
Info, Info,
EventType, EventType,
InfoResponse,
EventJson, EventJson,
FileEventJson, FileEventJson,
MassTranslationEventJson MassTranslationEventJson,
VideoConferenceEventJson
} from '@ucap-webmessenger/protocol-event'; } from '@ucap-webmessenger/protocol-event';
import { NGXLogger } from 'ngx-logger'; import { NGXLogger } from 'ngx-logger';
import moment from 'moment'; import moment from 'moment';
@ -87,6 +87,12 @@ export class MessageBoxComponent implements OnInit, AfterViewInit {
type: string; type: string;
}>(); }>();
@Output()
conferenceDetail = new EventEmitter<VideoConferenceEventJson>();
@Output()
conferenceJoin = new EventEmitter<VideoConferenceEventJson>();
@Output() @Output()
contextMenu = new EventEmitter<{ contextMenu = new EventEmitter<{
event: MouseEvent; event: MouseEvent;
@ -181,6 +187,13 @@ export class MessageBoxComponent implements OnInit, AfterViewInit {
this.save.emit(value); this.save.emit(value);
} }
onClickConferenceDetail(param: VideoConferenceEventJson) {
this.conferenceDetail.emit(param);
}
onClickConferenceJoin(param: VideoConferenceEventJson) {
this.conferenceJoin.emit(param);
}
/** [Event] Context Menu */ /** [Event] Context Menu */
onContextMenu(event: any, message: Info<EventJson>) { onContextMenu(event: any, message: Info<EventJson>) {
if ( if (

View File

@ -5,16 +5,16 @@
> >
<ng-container [ngSwitch]="message.sentMessageJson.contents"> <ng-container [ngSwitch]="message.sentMessageJson.contents">
<ng-container *ngSwitchCase="VideoConferenceContentsType.Now"> <ng-container *ngSwitchCase="VideoConferenceContentsType.Now">
{{ 'chat.event.videoConferenceTypeNow' | translate }} {{ 'conference.videoConferenceTypeNow' | translate }}
</ng-container> </ng-container>
<ng-container *ngSwitchCase="VideoConferenceContentsType.New"> <ng-container *ngSwitchCase="VideoConferenceContentsType.New">
{{ 'chat.event.videoConferenceTypeNew' | translate }} {{ 'conference.videoConferenceTypeNew' | translate }}
</ng-container> </ng-container>
<ng-container *ngSwitchCase="VideoConferenceContentsType.Update"> <ng-container *ngSwitchCase="VideoConferenceContentsType.Update">
{{ 'chat.event.videoConferenceTypeUpdate' | translate }} {{ 'conference.videoConferenceTypeUpdate' | translate }}
</ng-container> </ng-container>
<ng-container *ngSwitchCase="VideoConferenceContentsType.Delete"> <ng-container *ngSwitchCase="VideoConferenceContentsType.Delete">
{{ 'chat.event.videoConferenceTypeDelete' | translate }} {{ 'conference.videoConferenceTypeDelete' | translate }}
</ng-container> </ng-container>
</ng-container> </ng-container>
</ng-container> </ng-container>
@ -22,19 +22,19 @@
<ul class="event-info"> <ul class="event-info">
<li class="event-date bg-accent-brightest"> <li class="event-date bg-accent-brightest">
<label class="text-accent-darkest">{{ <label class="text-accent-darkest">{{
'chat.event.videoConferenceRegister' | translate 'conference.videoConferenceRegister' | translate
}}</label }}</label
><span>{{ message.sentMessageJson.register }}</span> ><span>{{ message.sentMessageJson.register }}</span>
</li> </li>
<li class="event-time bg-accent-brightest"> <li class="event-time bg-accent-brightest">
<label class="text-accent-darkest">{{ <label class="text-accent-darkest">{{
'chat.event.videoConferenceAttendee' | translate 'conference.videoConferenceAttendee' | translate
}}</label }}</label
><span>{{ message.sentMessageJson.attendee }}</span> ><span>{{ message.sentMessageJson.attendee }}</span>
</li> </li>
<li class="event-time bg-accent-brightest"> <li class="event-time bg-accent-brightest">
<label class="text-accent-darkest">{{ <label class="text-accent-darkest">{{
'chat.event.videoConferenceDate' | translate 'conference.videoConferenceDate' | translate
}}</label }}</label
><span>{{ ><span>{{
message.sentMessageJson.startDate | ucapDate: 'YYYY.MM.DD (ddd) a hh:mm' message.sentMessageJson.startDate | ucapDate: 'YYYY.MM.DD (ddd) a hh:mm'
@ -45,18 +45,18 @@
</li> </li>
</ul> </ul>
<!-- <div class="btn-box"> <div class="btn-box">
<ul> <ul>
<li> <li>
<button mat-button (click)="onClickDetailView()"> <button mat-button (click)="onClickDetailView()">
{{ 'chat.detailView' | translate }} {{ 'conference.detailView' | translate }}
</button> </button>
</li> </li>
<li> <li>
<button mat-button (click)="onClickEnjoyConference()"> <button mat-button (click)="onClickEnjoyConference()">
{{ 'chat.event.videoConferenceEnjoy' | translate }} {{ 'conference.videoConferenceEnjoy' | translate }}
</button> </button>
</li> </li>
</ul> </ul>
</div> --> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { VideoConferenceContentsType } from '@ucap-webmessenger/protocol-event'; import { VideoConferenceContentsType } from '@ucap-webmessenger/protocol-event';
import { import {
VideoConferenceEventJson, VideoConferenceEventJson,
@ -14,13 +14,23 @@ export class VideoConferenceComponent implements OnInit {
@Input() @Input()
message: Info<VideoConferenceEventJson>; message: Info<VideoConferenceEventJson>;
@Output()
conferenceDetail = new EventEmitter<VideoConferenceEventJson>();
@Output()
conferenceJoin = new EventEmitter<VideoConferenceEventJson>();
VideoConferenceContentsType = VideoConferenceContentsType; VideoConferenceContentsType = VideoConferenceContentsType;
constructor() {} constructor() {}
ngOnInit() {} ngOnInit() {}
onClickDetailView() {} onClickDetailView() {
this.conferenceDetail.emit(this.message.sentMessageJson);
}
onClickEnjoyConference() {} onClickEnjoyConference() {
this.conferenceJoin.emit(this.message.sentMessageJson);
}
} }

View File

@ -75,6 +75,8 @@
(massTranslationDetail)="onMassTranslationDetail($event)" (massTranslationDetail)="onMassTranslationDetail($event)"
(fileViewer)="onFileViewer($event)" (fileViewer)="onFileViewer($event)"
(save)="onSave($event)" (save)="onSave($event)"
(conferenceDetail)="onClickConferenceDetail($event)"
(conferenceJoin)="onClickConferenceJoin($event)"
(contextMenu)="onContextMenu($event)" (contextMenu)="onContextMenu($event)"
> >
</ucap-chat-message-box> </ucap-chat-message-box>

View File

@ -19,7 +19,8 @@ import {
InfoResponse, InfoResponse,
EventJson, EventJson,
FileEventJson, FileEventJson,
MassTranslationEventJson MassTranslationEventJson,
VideoConferenceEventJson
} from '@ucap-webmessenger/protocol-event'; } from '@ucap-webmessenger/protocol-event';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { UserInfo, RoomInfo, RoomType } from '@ucap-webmessenger/protocol-room'; import { UserInfo, RoomInfo, RoomType } from '@ucap-webmessenger/protocol-room';
@ -94,6 +95,10 @@ export class MessagesComponent implements OnInit, OnDestroy {
type: string; type: string;
}>(); }>();
@Output() @Output()
conferenceDetail = new EventEmitter<VideoConferenceEventJson>();
@Output()
conferenceJoin = new EventEmitter<VideoConferenceEventJson>();
@Output()
contextMenu = new EventEmitter<{ contextMenu = new EventEmitter<{
event: MouseEvent; event: MouseEvent;
message: Info<EventJson>; message: Info<EventJson>;
@ -663,6 +668,16 @@ export class MessagesComponent implements OnInit, OnDestroy {
this.save.emit(value); this.save.emit(value);
} }
/** [Event] Conference Detail View */
onClickConferenceDetail(param: VideoConferenceEventJson) {
this.conferenceDetail.emit(param);
}
/** [Event] Conference Join */
onClickConferenceJoin(param: VideoConferenceEventJson) {
this.conferenceJoin.emit(param);
}
/** [Event] Context Menu */ /** [Event] Context Menu */
onContextMenu(event: { onContextMenu(event: {
event: MouseEvent; event: MouseEvent;