This commit is contained in:
Park Byung Eun 2020-05-15 18:03:46 +09:00
parent a3bb007dfb
commit 344a105583
13 changed files with 1275 additions and 0 deletions

View File

@ -0,0 +1,187 @@
<ng-template ucapGroupExpansionBuddyHeader let-node>
<span
class="header-buddy"
*ngIf="
!curGroup || (!!curGroup && curGroup.seq !== node.groupDetail.seq)
"
>
<span>{{ node.groupDetail.name }}</span>
<span>
{{ node.children?.length }}
</span>
</span>
<span
class="header-buddy"
*ngIf="!!curGroup && curGroup.seq === node.groupDetail.seq"
(click)="$event.stopPropagation()"
>
<mat-form-field>
<input
matInput
#groupInput
placeholder=""
[value]="node.groupDetail.name"
/>
<button
mat-button
matSuffix
mat-icon-button
aria-label="Clear"
(click)="groupInput.value = ''"
>
<mat-icon>close</mat-icon>
</button>
<button
mat-button
mat-icon-button
aria-label="Done"
(click)="onModifyGroupName(groupInput.value, node.groupDetail)"
>
<mat-icon>done</mat-icon>
</button>
</mat-form-field>
</span>
</ng-template>
<button mat-button (click)="onCancel()">취소</button>
<button mat-button (click)="onConfirm()">
완료
</button>
<button mat-button (click)="onCompleteConfirm()">
그룹지정후 완료
</button>
<form name="inputForm" [formGroup]="inputForm" novalidate>
<mat-form-field
hintLabel="금지단어[-,_]"
style="display: block; margin-bottom: 10px;"
>
<input
matInput
#input
maxlength="20"
placeholder="{{ inputPlacholder }}"
formControlName="groupName"
(keyup)="onKeyupGroupName()"
/>
<mat-hint align="end">{{ input.value?.length || 0 }}/20</mat-hint>
<!-- <mat-error *ngIf="inputForm.get('groupName').hasError('groupNameBanned')"> -->
<!-- {{
'group.errors.bannedWords'
| translate: { bannedWords: appService.bannedGroupNames.join(',') }
}} -->
<!-- 금지단어[-,_] -->
<!-- </mat-error> -->
<!-- <mat-error *ngIf="inputForm.get('groupName').hasError('groupNameSamed')"> -->
<!-- {{ 'group.errors.sameNameExist' | translate }} -->
<!-- 이미 존재하는 그룹명입니다. -->
<!-- </mat-error> -->
</mat-form-field>
</form>
@Component({
selector: 'app-group-input',
templateUrl: './group-input.component.html',
styleUrls: ['./group-input.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class GroupInputComponent implements OnInit, OnDestroy {
private ngOnDestroySubject = new Subject<boolean>();
@Input()
set groupName(g: string) {
this._groupName = g;
}
get groupName(): string {
return this._groupName;
}
_groupName: string;
@Input()
inputPlacholder: string;
@Input()
dialogType: SelectUserDialogType;
@Input()
componentSeq: number;
@Input()
groupList?: GroupDetailData[];
@Output()
cancel = new EventEmitter();
@Output()
confirm = new EventEmitter();
@Output()
completeConfirm = new EventEmitter();
constructor(
private formBuilder: FormBuilder,
private i18nService: I18nService
) {}
inputForm: FormGroup;
ngOnInit(): void {
this.inputForm = this.formBuilder.group({
groupName: [
this.groupName,
[
Validators.required
// StringUtil.includes(, CharactorType.Special),
// this.checkBanWords(),
// this.checkSameName()
]
]
});
}
ngOnDestroy(): void {
if (!!this.ngOnDestroySubject) {
this.ngOnDestroySubject.complete();
}
}
getGroupName(): string {
return this.inputForm.get('groupName').value;
}
onKeyupGroupName() {
this.inputForm.get('groupName').markAsTouched();
}
checkSameName(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } | null => {
if (
!control ||
!control.value ||
!this.groupList ||
0 === this.groupList.length
) {
return null;
}
const v = (control.value as string).trim();
const ban = -1 < this.groupList.findIndex((g) => g.name === v);
return ban ? { groupNameSamed: { value: control.value } } : null;
};
}
onCancel() {
this.cancel.emit();
}
onConfirm() {
this.confirm.emit();
}
onCompleteConfirm() {
this.completeConfirm.emit();
}
}

View File

@ -0,0 +1 @@
5, 22, 23, 0, 16

View File

@ -0,0 +1,80 @@
<ucap-group-expansion
#groupExpansion
[displayOrder]="displayOrder"
[profile]="loginRes?.userInfo"
[favorites]="favorites"
[groupBuddies]="groupBuddies"
(clickMoreMenu)="onClickMoreMenu($event)"
>
<ng-template ucapGroupExpansionNode let-node>
<app-group-profile-list-item
[userInfo]="node.userInfo"
defaultProfileImage="assets/images/img_nophoto_50.png"
[profileImageRoot]="versionInfo2Res?.profileRoot"
[checkable]="checkable"
(checkUser)="onCheckUser($event)"
(click)="onClickUser($event, node.userInfo)"
></app-group-profile-list-item>
</ng-template>
<ng-template ucapGroupExpansionFavoriteHeader let-node>
<span class="header-favorite">
<span>
{{ 'category.favorite' | ucapI18n }}
</span>
<span>{{ node.children?.length }}</span>
</span>
</ng-template>
<ng-template ucapGroupExpansionBuddyHeader let-node>
<span
class="header-buddy"
*ngIf="
!curGroup || (!!curGroup && curGroup.seq !== node.groupDetail.seq)
"
>
<span>{{ node.groupDetail.name }}</span>
<span>
{{ node.children?.length }}
</span>
</span>
<span
class="header-buddy"
*ngIf="!!curGroup && curGroup.seq === node.groupDetail.seq"
(click)="$event.stopPropagation()"
>
<mat-form-field>
<input
matInput
#groupInput
placeholder=""
[value]="node.groupDetail.name"
/>
<button
mat-button
matSuffix
mat-icon-button
aria-label="Clear"
(click)="groupInput.value = ''"
>
<mat-icon>close</mat-icon>
</button>
<button
mat-button
mat-icon-button
aria-label="Done"
(click)="onModifyGroupName(groupInput.value, node.groupDetail)"
>
<mat-icon>done</mat-icon>
</button>
</mat-form-field>
</span>
</ng-template>
<ng-template ucapGroupExpansionDefaultHeader let-node>
<span class="header-default">
<span>
{{ 'category.default' | ucapI18n }}
</span>
<span>{{ node.children?.length }}</span>
</span>
</ng-template>
</ucap-group-expansion>

View File

@ -0,0 +1,71 @@
<mat-card class="confirm-card mat-elevation-z dialog-creat-chat">
<mat-card-header>
<mat-card-title
cdkDrag
cdkDragRootElement=".cdk-overlay-pane"
cdkDragHandle
>{{ data.title }}</mat-card-title
>
<button class="icon-button btn-dialog-close" (click)="onClickChoice(false)">
<i class="mdi mdi-window-close"></i>
</button>
</mat-card-header>
<mat-card-content>
<div>
<ng-template #dialogContainer></ng-template>
</div>
<ng-template [ngTemplateOutlet]="selectedUserListTemplate"></ng-template>
</mat-card-content>
</mat-card>
<ng-template #selectedUserListTemplate>
<div class="list-chip">
<mat-chip-list aria-label="User selection">
<mat-chip
*ngFor="let userInfo of selectedUserList"
[selected]="getChipsRemoveYn(userInfo)"
(removed)="onClickDeleteUser(userInfo)"
>
<!-- {{ userInfo | ucapTranslate: 'name' }} -->
{{ userInfo.name }}
<mat-icon matChipRemove *ngIf="getChipsRemoveYn(userInfo)"
>clear</mat-icon
>
</mat-chip>
</mat-chip-list>
</div>
<ng-container
*ngIf="
SelectUserDialogType.NewChat === SelectUserDialogType.NewChat;
then newchatcount;
else defaultcount
"
></ng-container>
<ng-template #newchatcount>
<span [ngClass]="selectedUserList.length >= 300 ? 'text-warn-color' : ''">
{{ selectedUserList.length }} / 300
<!-- {{ environment.productConfig.CommonSetting.maxChatRoomUser - 1 }} -->
<!-- {{ 'common.units.persons' | translate }} -->
</span>
<span
class="text-warn-color"
style="float: right;"
*ngIf="selectedUserList.length >= 300"
>
<!-- ({{
'chat.errors.maxCountOfRoomMemberWith'
| translate
: {
maxCount:
environment.productConfig.CommonSetting.maxChatRoomUser - 1
}
}}) -->
</span>
</ng-template>
<ng-template #defaultcount>
<span>
{{ selectedUserList.length }}
<!-- {{ 'common.units.persons' | translate }} -->
</span>
</ng-template>
</ng-template>

View File

@ -0,0 +1,215 @@
import {
Component,
OnInit,
OnDestroy,
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Inject,
ViewChild,
ComponentFactoryResolver,
ViewContainerRef,
ComponentRef
} from '@angular/core';
import { UserInfo, GroupDetailData } from '@ucap/protocol-sync';
import {
UserInfoSS,
UserInfoF,
UserInfoDN,
DeptInfo
} from '@ucap/protocol-query';
import { Store, select } from '@ngrx/store';
import { Subject, combineLatest } from 'rxjs';
import { AppAuthenticationService } from '@app/services/app-authentication.service';
import { SelectUserDialogType } from '@app/types';
import { RoomInfo, UserInfo as RoomUserInfo } from '@ucap/protocol-room';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { SelectUserSectionComponent } from '../../select-user.section.component';
import { GroupActions } from '@ucap/ng-store-group';
import { UserInfoTypes } from '../profile-list-item.component';
import { GroupInputComponent } from '../group-input.component';
export interface CreateChatDialogData {
type?: SelectUserDialogType;
title: string;
/** CASE :: EditMember */
group?: GroupDetailData;
/** CASE :: EventForward */
ignoreRoom?: RoomInfo[];
/** CASE :: EditChatMember */
curRoomUser?: (
| UserInfo
| UserInfoSS
| UserInfoF
| UserInfoDN
| RoomUserInfo
)[];
}
export interface CreateChatDialogResult {
choice: boolean;
groupName?: string;
oldGroup?: GroupDetailData;
selectedUserList?: (
| UserInfo
| UserInfoSS
| UserInfoF
| UserInfoDN
| RoomUserInfo
)[];
selectedRoom: RoomInfo;
}
@Component({
selector: 'app-create-chat.dialog',
templateUrl: './create-chat.dialog.component.html',
styleUrls: ['./create-chat.dialog.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CreateChatDialogComponent implements OnInit, OnDestroy {
@ViewChild('selectBoxUserComponent', { static: false })
selectBoxUserComponent: SelectUserSectionComponent;
@ViewChild('dialogContainer', { static: true, read: ViewContainerRef })
dialogContainer: ViewContainerRef;
componentRef: ComponentRef<any>;
constructor(
public dialogRef: MatDialogRef<
CreateChatDialogData,
CreateChatDialogResult
>,
@Inject(MAT_DIALOG_DATA) public data: CreateChatDialogData,
private changeDetectorRef: ChangeDetectorRef,
private store: Store<any>,
private appAuthenticationService: AppAuthenticationService,
private cfResolver: ComponentFactoryResolver
) {}
private ngOnDestroySubject = new Subject<boolean>();
selectedUserList: UserInfoTypes[] = [];
SelectUserDialogType = SelectUserDialogType;
selectedRoom: RoomInfo;
groupName: string;
ngOnInit(): void {
this.loadComponent();
}
ngOnDestroy(): void {
if (!!this.ngOnDestroySubject) {
this.ngOnDestroySubject.complete();
}
this.componentRef.destroy();
}
loadComponent() {
switch (this.data.type) {
case SelectUserDialogType.NewGroup:
case SelectUserDialogType.ModifyGroup:
{
this.dialogContainer.clear();
const factory = this.cfResolver.resolveComponentFactory(
GroupInputComponent
);
this.componentRef = this.dialogContainer.createComponent(factory);
const cpInstance = this.componentRef.instance;
cpInstance.dialogType = this.data.type;
cpInstance.groupName =
!!this.data.group && !!this.data.group.name
? this.data.group.name
: '';
cpInstance.inputPlacholder = '그룹';
cpInstance.cancel.subscribe(() => {
this.dialogRef.close();
});
cpInstance.confirm.subscribe(() => {
this.groupName = this.componentRef.instance.getGroupName();
this.doAction();
});
cpInstance.completeConfirm.subscribe(() => {
this.groupName = this.componentRef.instance.getGroupName();
this.showSelectUserComponent();
});
}
break;
case SelectUserDialogType.NewChat:
{
// 새로운 대화 유형 & 대화방 이름 섹션 컴포넌트
// 유저 선택 컴포넌트
}
break;
case SelectUserDialogType.EditChatMember:
{
// 유저 선택 컴포넌트
}
break;
case SelectUserDialogType.EditMember:
{
// 그룹 멤버 관리 컴포넌트
// 유저 선택 컴포넌트
}
break;
case SelectUserDialogType.MessageForward:
{
// 유저 선택 컴포넌트
}
break;
}
}
onClickChoice(choice: boolean) {
if (!choice) {
this.dialogRef.close();
return;
}
}
getBtnValid() {}
getChipsRemoveYn(userInfo: UserInfo) {}
onClickDeleteUser(userInfo: UserInfo) {}
onChangeSelectedUserList(userList: UserInfoTypes[]) {
this.selectedUserList = userList;
this.changeDetectorRef.markForCheck();
}
doAction() {
this.dialogRef.close({
choice: true,
selectedUserList: this.selectedUserList,
selectedRoom: this.selectedRoom,
groupName: this.groupName,
oldGroup: undefined
});
}
private showSelectUserComponent() {
this.dialogContainer.clear();
const factory = this.cfResolver.resolveComponentFactory(
SelectUserSectionComponent
);
this.componentRef = this.dialogContainer.createComponent(factory);
this.componentRef.instance.cancel.subscribe(() => {
if (
this.data.type === SelectUserDialogType.NewGroup ||
this.data.type === SelectUserDialogType.ModifyGroup
) {
this.loadComponent();
}
});
this.componentRef.instance.confirm.subscribe(() => {
this.doAction();
});
this.componentRef.instance.changeUserList.subscribe((list) => {
this.selectedUserList = list;
});
}
}

View File

@ -0,0 +1,211 @@
<div class="mainProfile">
<!--Profile -->
<div class="profile-card-box">
<!-- + 내프로필 -->
<ng-container *ngIf="isMe; then isMine; else other"></ng-container>
<ng-template #isMine>
<div class="user-profile-info">
<!--[[ 대화상대 프로필-->
<!-- 모바일이 온라인일 경우 + mobile-ing -->
<!--
<div class="user-profile-thumb mobile-ing">
<span class="presence">온라인</span>
<div class="profileImage">
<img
src="https://material.angular.io/assets/img/examples/shiba2.jpg"
style="width: 122px; height: 122px;"
/>
</div>
</div>-->
<!--]]-->
<!--[[ 내프로필-->
<div class="user-profile-thumb">
<span class="presence">온라인</span>
<div class="profileImage">
<img
src="../../../assets/images/ico/img_nophoto.svg"
style="width: 122px; height: 122px;"
/>
</div>
<div class="btn-profile-ctrl">
<button mat-mini-fab color="primary" class="mat-mini36-fab">
<mat-icon class="material-icons-outlined">camera_alt</mat-icon>
</button>
</div>
</div>
<!--]]-->
<div class="userInfo">
<div class="user-n-g">
<div class="name">{{ userInfo?.name }}</div>
<div class="grade">{{ userInfo?.grade }}</div>
</div>
<div class="deptName">({{ userInfo?.nameEn }})</div>
</div>
<div class="btn-profile-add">
<button
mat-icon-button
class="btn-star-add"
aria-label="Example icon-button with a heart icon"
*ngIf="!isFavorite"
>
<img
src="../../../assets/images/ico/btn_favorite_w24_s.svg"
alt=""
/>
</button>
<button
mat-icon-button
class="btn-star-add"
aria-label="Example icon-button with a heart icon"
*ngIf="!isBuddy"
>
<img
src="../../../assets/images/ico/btn_group_add_w24.svg"
alt=""
/>
</button>
</div>
</div>
<div class="my-input inputtype">
<mat-form-field
class="example-full-width my-in-input"
appearance="none"
>
<mat-label></mat-label>
<input matInput placeholder="" value="마곡 사이언스 파크 E14동 9층" />
</mat-form-field>
<button mat-icon-button aria-label="icon create" class="color-white">
<mat-icon>create</mat-icon>
</button>
</div>
</ng-template>
<!-- + 대회상대 프로필-->
<ng-template #other>
<div class="user-profile-info">
<!--[[ 대화상대 프로필-->
<!-- 모바일이 온라인일 경우 + mobile-ing -->
<!--
<div class="user-profile-thumb mobile-ing">
<span class="presence">온라인</span>
<div class="profileImage">
<img
src="https://material.angular.io/assets/img/examples/shiba2.jpg"
style="width: 122px; height: 122px;"
/>
</div>
</div>-->
<!--]]-->
<!--[[ 내프로필-->
<div class="user-profile-thumb">
<span class="presence">온라인</span>
<div class="profileImage">
<img
src="../../../assets/images/ico/img_nophoto.svg"
style="width: 122px; height: 122px;"
/>
</div>
</div>
<!--]]-->
<div class="userInfo">
<div class="user-n-g">
<div class="name">{{ userInfo?.name }}</div>
<div class="grade">{{ userInfo?.grade }}</div>
</div>
<div class="deptName">({{ userInfo?.nameEn }})</div>
<!-- + 대화상대 프로필 추가 -->
<!-- -->
<div class="nickName">
<div class="nickName-info">닉네임 미설정</div>
<button
mat-icon-button
aria-label="icon create"
class="color-white"
>
<mat-icon>create</mat-icon>
</button>
</div>
<div class="address-txt">
마곡 사이언스 파크 E14동 9층
</div>
</div>
<div class="btn-profile-add">
<button
mat-icon-button
class="btn-star-add"
aria-label="Example icon-button with a heart icon"
*ngIf="!isFavorite"
>
<img
src="../../../assets/images/ico/btn_favorite_w24_s.svg"
alt=""
/>
</button>
<button
mat-icon-button
class="btn-star-add"
aria-label="Example icon-button with a heart icon"
*ngIf="!isBuddy"
>
<img
src="../../../assets/images/ico/btn_group_add_w24.svg"
alt=""
/>
</button>
</div>
</div>
<div class="btn-partner-set">
<button mat-icon-button aria-label="chat">
<img src="../../../assets/images/ico/btn_lise_chat_a24.svg" alt="" />
</button>
<button mat-icon-button aria-label="message">
<img
src="../../../assets/images/ico/btn_list_message_a24.svg"
alt=""
/>
</button>
<button mat-icon-button aria-label="mobile">
<img
src="../../../assets/images/ico/btn_list_mobile_a24.svg"
alt=""
/>
</button>
<button mat-icon-button aria-label="call">
<img src="../../../assets/images/ico/btn_list_call_a24.svg" alt="" />
</button>
<button mat-icon-button aria-label="vc">
<img src="../../../assets/images/ico/btn_list_vc-a24.svg" alt="" />
</button>
</div>
</ng-template>
<div class="user-profile-info-list">
<ul>
<li>
<span>{{ 'profile.labels.company' | ucapI18n }}</span>
{{ userInfo?.companyName }}
</li>
<li>
<span>{{ 'profile.labels.department' | ucapI18n }}</span>
{{ userInfo?.deptName }}
</li>
<li>
<span>{{ 'profile.labels.email' | ucapI18n }}</span>
{{ userInfo?.email }}
</li>
<li>
<span>{{ 'profile.labels.linePhoneNumber' | ucapI18n }}</span>
{{ userInfo?.lineNumber }}
</li>
<li>
<span>{{ 'profile.labels.mobilePhoneNumber' | ucapI18n }}</span>
{{ userInfo?.hpNumber }}
</li>
</ul>
</div>
</div>
<!-- //Profile-->
</div>

View File

@ -0,0 +1,222 @@
@charset 'UTF-8';
@import '../../../../../assets/scss/components.scss';
.mainProfile {
height: calc(100% - 30px);
min-width: 450px;
margin: {
left: 30px;
bottom: 30px;
}
@include screen(mid) {
height: auto;
}
//margin: 30px;
background-image: url(/assets/images/bg/bg_profile1.svg),
url(/assets/images/bg/bg_profile2.svg),
url(/assets/images/bg/bg_profile3.svg),
url(/assets/images/bg/bg_profile4.svg),
url(/assets/images/bg/bg_profile5.svg), $bg-linear-gradient;
background-repeat: no-repeat;
background-position: -213px -223px, 433px 95px, 489px 72px, 433px 517px,
335px 634px, 0 0;
.profile-card-box {
display: flex;
flex-direction: column;
padding: 60px 8.7%;
width: 100%;
position: relative;
.user-profile-info {
display: inline-flex;
flex-direction: row;
align-items: center;
// Profile thumb//////////////////
.user-profile-thumb {
@include profile-avatar-default(
10px 0 0,
18.6,
$green,
30px
); //오른 아래 공간, 모바일 온라인 아이콘 크기, 모바일 아이콘 , 모바일 아이콘 bg크기
padding: 10px 0 0;
margin-left: -14px;
align-self: start;
.presence {
//PC 상태
@include presence-state(14px); //원크기
margin-top: -10px;
}
.profileImage {
@include avatar-img(128px, 0); //아바타 크기, 왼쪽공간
border: 3px solid $white;
}
.btn-profile-ctrl {
position: absolute;
bottom: 0;
right: 0;
}
}
//////////////////Profile thumb //
.userInfo {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding-left: 38px;
.user-n-g {
display: flex;
flex-flow: row-reverse nowrap;
align-items: flex-end;
height: 44px;
.name {
font: {
size: 26px;
weight: 600;
}
color: $gray-re20;
order: 1;
-ms-flex-order: 1;
}
.grade {
font: {
size: 18px;
}
color: #f1f1f1;
margin-left: 6px;
order: 0;
-ms-flex-order: 0;
}
& + .deptName {
margin-top: 9px;
}
}
.deptName {
font-size: 22px;
color: $white;
line-height: 25px;
font-weight: 600;
}
.nickName {
display: flex;
flex-direction: row;
margin-top: 18px;
align-items: center;
.nickName-info {
padding: 0 16px;
height: 30px;
line-height: 30px;
border-radius: 15px;
border: solid 1px #fc5182;
background-color: rgba(255, 255, 255, 0.95);
color: $gray-re9;
font-size: 14px;
}
button {
}
}
.address-txt {
font-size: 16px;
line-height: 21px;
color: $gray-re3;
margin-top: 20px;
}
}
.btn-profile-add {
position: absolute;
z-index: 5;
top: 40px;
right: 40px;
button {
margin: 0 2px;
&.btn-star-add {
line-height: 24px !important;
}
}
}
}
.btn-partner-set {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 25px;
border-top: 1px solid rgba(255, 255, 255, 0.8);
border-bottom: 1px solid rgba(255, 255, 255, 0.8);
height: 70px;
margin-top: 30px;
img {
vertical-align: top;
}
}
.my-input {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
margin: 0;
width: 100%;
border-bottom: 1px solid $white;
margin-top: 78px;
.my-in-input {
font-size: 16px;
color: $gray-re3;
flex-grow: 1;
height: 24px;
line-height: 24px;
margin-top: 8px;
}
button {
margin-bottom: 5px;
}
}
.user-profile-info-list {
margin-top: 60px;
ul {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 250px;
li {
font-size: 16px;
font-weight: 600;
color: $brown;
span {
width: 100px;
height: 34px;
border-radius: 18px;
border: solid 1px #f8f9fd;
background-color: #aaa0a5;
font-size: 14px;
font-weight: 600;
display: inline-flex;
align-items: center;
justify-content: center;
color: $white;
margin-right: 40px;
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////// 제거
.profile-card {
//mat-card
width: 100%;
background-color: transparent;
box-shadow: none;
.profileImage {
width: 126px;
height: 126px;
border-radius: 50%;
border: 3px solid $white;
box-sizing: border-box;
overflow: hidden;
display: flex;
img {
display: flex;
align-items: center;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////
}

View File

@ -0,0 +1,288 @@
import {
Component,
OnInit,
OnDestroy,
ChangeDetectionStrategy,
ChangeDetectorRef,
Input,
Output,
EventEmitter,
ViewChild,
ElementRef
} from '@angular/core';
import { AppKey } from '@app/types/app-key.type';
import { LoginSession } from '@app/models/login-session';
import { Subject } from 'rxjs';
import { UserInfoSS, AuthResponse } from '@ucap/protocol-query';
import { OpenProfileOptions } from '@ucap/protocol-buddy';
import { FileUploadItem } from '@ucap/api';
import { FormControl } from '@angular/forms';
import { WorkStatusType } from '@ucap/protocol';
import { I18nService } from '@ucap/ng-i18n';
@Component({
selector: 'app-group-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProfileComponent implements OnInit, OnDestroy {
@Input()
set userInfo(u: UserInfoSS) {
this._userInfo = u;
}
get userInfo(): UserInfoSS {
return this._userInfo;
}
_userInfo: UserInfoSS;
@Input()
isMe: boolean;
@Input()
isBuddy: boolean;
@Input()
isFavorite: boolean;
@Input()
myMadn?: string;
@Input()
canVideoConfernece: boolean;
@Output()
toggleFavorite = new EventEmitter<{
userInfo: UserInfoSS;
isFavorite: boolean;
}>();
@Output()
toggleBuddy = new EventEmitter<{
userInfo: UserInfoSS;
isBuddy: boolean;
}>();
@Output()
openChat = new EventEmitter<UserInfoSS>();
@Output()
sendCall = new EventEmitter<string>();
@Output()
sendSms = new EventEmitter<string>();
@Output()
createConference = new EventEmitter<number>();
@Output()
sendMessage = new EventEmitter<UserInfoSS>();
///////////////////////////////////////////////
@Input()
profileImageRoot: string;
@Input()
openProfileOptions?: OpenProfileOptions;
@Input()
useBuddyToggleButton: boolean;
@Input()
authInfo: AuthResponse;
@Output()
profileImageView = new EventEmitter<void>();
@Output()
uploadProfileImage = new EventEmitter<FileUploadItem>();
@Output()
updateIntro = new EventEmitter<string>();
@ViewChild('profileImageFileInput', { static: false })
profileImageFileInput: ElementRef<HTMLInputElement>;
userIntroFormControl = new FormControl('');
profileImageFileUploadItem: FileUploadItem;
private ngOnDestroySubject = new Subject<boolean>();
constructor(private i18nService: I18nService) {}
ngOnInit(): void {
console.log(this.isMe);
}
ngOnDestroy(): void {
if (!!this.ngOnDestroySubject) {
this.ngOnDestroySubject.complete();
}
}
onToggleFavorit() {
this.toggleFavorite.emit({
userInfo: this.userInfo,
isFavorite: !this.isFavorite
});
}
onClickToggleBuddy() {
this.toggleBuddy.emit({
userInfo: this.userInfo,
isBuddy: !this.isBuddy
});
}
onClickActionButton(event: MouseEvent, type: string): void {
event.preventDefault();
event.stopPropagation();
switch (type) {
case 'CHAT':
this.onClickOpenChat();
break;
case 'MESSAGE':
this.onClickMessage();
break;
case 'SMS':
this.onClickSMS();
break;
case 'CALL_MOBILE':
this.onClickCall('MOBILE');
break;
case 'CALL_LINE':
this.onClickCall('LINE');
break;
case 'CONFERENCE':
this.onClickVideoConference();
break;
}
}
onClickOpenChat() {
this.openChat.emit(this.userInfo);
}
onClickCall(type: string) {
let calleeNumber = '';
if (type === 'LINE') {
calleeNumber = this.userInfo.lineNumber;
} else {
calleeNumber = this.userInfo.hpNumber;
}
this.sendCall.emit(calleeNumber);
}
onClickSMS() {
this.sendSms.emit(this.userInfo.hpNumber);
}
onClickVideoConference() {
this.createConference.emit(Number(this.userInfo.seq));
}
onClickMessage() {
this.sendMessage.emit(this.userInfo);
}
isDisabledCallButton(type: string): boolean {
if (!this.myMadn || this.myMadn.trim().length === 0) {
if (type === 'LINE' || type === 'MOBILE') {
return true;
}
}
if (type === 'LINE') {
if (
!!this.userInfo &&
!!this.userInfo.lineNumber &&
this.userInfo.lineNumber.trim().length > 0
) {
return false;
} else {
return true;
}
} else if (type === 'MOBILE') {
if (
!!this.userInfo &&
!!this.userInfo.hpNumber &&
this.userInfo.hpNumber.trim().length > 0
) {
return false;
} else {
return true;
}
} else if (type === 'SMS') {
// const smsUtils = new SmsUtils(
// this.sessionStorageService,
// this.nativeService
// );
// return !smsUtils.getAuthSms();
}
return true;
}
///////////////////////////////////////////////
onClickProfileImageView() {
this.profileImageView.emit();
}
onApplyIntroMessage(intro: string) {
if (intro.trim().length < 1) {
this.updateIntro.emit(' ');
} else {
this.updateIntro.emit(intro);
}
}
onChangeFileInput() {
this.profileImageFileUploadItem = FileUploadItem.fromFiles(
this.profileImageFileInput.nativeElement.files
)[0];
this.uploadProfileImage.emit(this.profileImageFileUploadItem);
this.profileImageFileInput.nativeElement.value = '';
}
getWorkstatus(userInfo: UserInfoSS): string {
let workstatus = '';
if (!!userInfo && !!userInfo.workstatus) {
switch (userInfo.workstatus) {
case WorkStatusType.VacationAM:
workstatus = '오전';
break;
case WorkStatusType.VacationPM:
workstatus = '오후';
break;
case WorkStatusType.VacationAll:
workstatus = '휴가';
break;
case WorkStatusType.LeaveOfAbsence:
workstatus = '휴직';
break;
case WorkStatusType.LongtermRefresh:
workstatus = '장기';
break;
}
}
return workstatus;
}
getWorkstatusStyle(userInfo: UserInfoSS): string {
// morning-off: 오전 afternoon-off: 오후 day-off: 휴가 long-time: 장기 leave-of-absence: 휴직
let style = '';
if (!!userInfo && !!userInfo.workstatus) {
switch (userInfo.workstatus) {
case WorkStatusType.VacationAM:
style = 'morning-off';
break;
case WorkStatusType.VacationPM:
style = 'afternoon-off';
break;
case WorkStatusType.VacationAll:
style = 'day-off';
break;
case WorkStatusType.LeaveOfAbsence:
style = 'leave-of-absence';
break;
case WorkStatusType.LongtermRefresh:
style = 'long-time';
break;
}
}
return style;
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.