This commit is contained in:
Park Byung Eun 2020-05-27 18:53:37 +09:00
parent 7906aeaf7b
commit 915d871217
12 changed files with 1071 additions and 0 deletions

View File

@ -0,0 +1,323 @@
const rect = target.getBoundingClientRect();
const clickEventY = this.groupMenuEvent.clientY;
const tartgetY = Math.floor((clickEventY - 150) * 0.1) * 10;
const dialogRef = this.dialog.open(EditInlineInputDialogComponent, {
width: rect.width,
height: rect.height,
panelClass: 'ucap-edit-group-name-dialog',
data: {
curValue: group.name,
placeholder: '그룹명을 입력하세요.',
left: rect.left,
top: clickEventY - 100 + rect.height
}
});
"TypeError: Cannot read property 'height' of undefined
at ExpansionComponent.onSelectGroupMenu (http://localhost:4200/pages-group-group-page-module.980e746b5ae98aad2c91.hot-update.js:985:47)
at ExpansionComponent_ng_template_11_button_6_Template_button_click_0_listener (http://localhost:4200/pages-group-group-page-module.980e746b5ae98aad2c91.hot-update.js:581:416)
at executeListenerWithErrorHandling (http://localhost:4200/vendor.js:53654:16)
at wrapListenerIn_markDirtyAndPreventDefault (http://localhost:4200/vendor.js:53703:22)
at HTMLButtonElement.<anonymous> (http://localhost:4200/vendor.js:123295:38)
at ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:443:35)
at Object.onInvokeTask (http://localhost:4200/vendor.js:70743:33)
at ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:442:40)
at Zone.runTask (http://localhost:4200/polyfills.js:211:51)
at ZoneTask.invokeTask [as invoke] (http://localhost:4200/polyfills.js:524:38)"
switch (menuType) {
case 'VIEW_PROFILE':
this.onClickUser(event, userInfo as UserInfo);
break;
case 'REGISTER_FAVORITE':
this.store.dispatch(
BuddyActions.update({
req: {
seq: Number(userInfo.seq),
isFavorit: !userInfo.isFavorit
}
})
);
break;
case 'NICKNAME':
{
this.editNickname(event, userInfo, rect);
}
break;
case 'COPY_BUDDY':
this.eidtUserDialog('COPY_BUDDY', group, userInfo);
break;
case 'MOVE_BUDDY':
this.eidtUserDialog('MOVE_BUDDY', group, userInfo);
break;
case 'REMOVE_BUDDY':
{
this.removeBuddy(userInfo, group);
}
break;
}
private eidtUserDialog(
type: string,
group: GroupDetailData,
userInfo: UserInfoTypes
) {
let title = '';
let dialogType: GroupUserDialaogType;
if (type === 'COPY_BUDDY') {
title = '멤버 복사';
dialogType = GroupUserDialaogType.Copy;
} else {
title = '멤버 이동';
dialogType = GroupUserDialaogType.Move;
}
const dialogRef = this.dialog.open<
EditUserDialogComponent,
EditUserDialogData,
EditUserDialogResult
>(EditUserDialogComponent, {
width: '100%',
height: '100%',
data: {
title,
type: dialogType,
group,
userInfo
}
});
dialogRef
.afterClosed()
.pipe(
take(1),
map((result: EditUserDialogResult) => {
let targetGroup: GroupDetailData;
let targetUserSeqs: string[];
if (result.type === GroupUserDialaogType.Add) {
targetGroup = result.group;
targetUserSeqs = [];
result.selelctUserList.forEach((u) => {
targetUserSeqs.push(u.seq + '');
});
this.store.dispatch(
GroupActions.updateMember({ targetGroup, targetUserSeqs })
);
} else if (result.type === GroupUserDialaogType.Copy) {
if (!!result.selectGroupList && result.selectGroupList.length > 0) {
result.selectGroupList.forEach((g) => {
targetGroup = g;
targetUserSeqs = [];
g.userSeqs.map((seq) => {
targetUserSeqs.push(seq);
});
if (targetUserSeqs.length === 0) {
result.selelctUserList.forEach((user) => {
targetUserSeqs.push(user.seq as any);
});
} else {
result.selelctUserList.forEach((user) => {
const find = targetUserSeqs.indexOf(user.seq as any);
if (find < 0) {
targetUserSeqs.push(user.seq as any);
}
});
}
this.store.dispatch(
GroupActions.updateMember({ targetGroup, targetUserSeqs })
);
});
}
} else if (result.type === GroupUserDialaogType.Move) {
const fromGroup = result.group;
let toGroup: GroupDetailData;
targetUserSeqs = [];
if (!!result.selectGroupList && result.selectGroupList.length > 0) {
result.selectGroupList.forEach((g) => {
toGroup = g;
targetUserSeqs = [];
result.selelctUserList.forEach((user) => {
targetUserSeqs.push(user.seq as any);
});
this.store.dispatch(
GroupActions.moveMember({
fromGroup,
toGroup,
targetUserSeq: targetUserSeqs
})
);
});
}
} else if (result.type === GroupUserDialaogType.Create) {
targetUserSeqs = [];
result.selelctUserList.forEach((u) => {
targetUserSeqs.push(u.seq + '');
});
this.store.dispatch(
GroupActions.create({
groupName: result.groupName,
targetUserSeqs
})
);
}
}),
catchError((err) => {
return of(err);
})
)
.subscribe();
}
private removeBuddy(userInfo: UserInfoF, group: GroupDetailData) {
const dialogRef = this.dialog.open<
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
>(ConfirmDialogComponent, {
data: {
title: '',
html: this.i18nService.t('label.confirmRemoveBuddy')
}
});
dialogRef
.afterClosed()
.pipe(
take(1),
map((result) => {
if (!!result && result.choice) {
const trgtUserSeq = group.userSeqs.filter(
(user) => user + '' !== userInfo.seq + ''
);
this.store.dispatch(
GroupActions.updateMember({
targetGroup: group,
targetUserSeqs: trgtUserSeq
})
);
}
}),
catchError((err) => {
return of(err);
})
)
.subscribe();
}
private editNickname(event: MouseEvent, userInfo: UserInfoF, rect: any) {
const clickEventY = event.clientY;
// const dialogRef = this.dialog.open(EditInlineInputDialogComponent, {
// width: rect.width - 30 + '',
// height: rect.height,
// panelClass: 'ucap-edit-group-name-dialog',
// data: {
// curValue: userInfo.nickName,
// placeholder: '닉네임을 설정하세요.',
// left: rect.left + 70,
// top: rect.top
// }
// });
// dialogRef
// .afterClosed()
// .pipe(
// take(1),
// map((result) => {
// if (
// !!result &&
// result.choice &&
// result.curValue.localeCompare(userInfo.nickName) !== 0
// ) {
// this.store.dispatch(
// BuddyActions.nickname({
// req: {
// userSeq: Number(userInfo.seq),
// nickname: result.curValue
// }
// })
// );
// }
// }),
// catchError((err) => {
// return of(err);
// })
// )
// .subscribe();
}
리팩토링
셀렉트 이용
이벤트가 다른 컴포넌트 시리즈 분리
컴포넌트 후보
사용자 선택 (chips)
검색 결과
프로필 리스트
그룹 다이얼로그
생성,
출력
그룹명, 그룹 유저 리스트, 조직도, 검색, 검색 결과
기능
그룹명 유효성 검사
그룹 유저 리스트
사용자 체크에 대한 처리, 그룹 체크에 대한 처리, 체크박스
한줄 수정,
출력
한줄 입력창, 적용 버튼, 취소 버튼
기능
한줄 입력에 대한 유효성 검사
절대 위치에 출력할 수 있게 포지션 계산
유저 변경(이동, 복사, 생성, 삭제),
유저 변경(이동, 복사)
그룹 메뉴
출력
메뉴
이름 바꾸기
그룹 삭제
기능
그룹 대화, 쪽지 => 이벤트 호출
그룹 이름 => position 계산, 적용, 취소에 대한 처리, 액션 처리
그룹 삭제 => 사용자 확인 다이얼로그 출력 및 액션에 대한 처리
익스팬션
프로필 리스트 아이템
출력
프로필 메뉴, 프레젠스, 프로핊 이미지, 이름, 직함, 부서, 인트로, 닉네임
기능
프로필 보기
즐겨 찾기 설정
닉네임 설정
대화 상대 복사, 이동
삭제
마우스오버&리브 이벤트에 대한 버튼 출력
모어 메뉴 출력 포지션 계산
검색
출력
입력창, 검색 버튼, 입력 삭제 버튼, 회사 리스트
기능
입력 이벤트
검색 액션 처리
삭제 버튼 액션 처리
회사 리스트 조회
셀렉트 그룹
검색
그룹명 입력
기존 그룹 리스트
체크박스
셀렉트 유저
익스팬션
프로필 리스트 아이템
프레젠스, 프로필 이미지, 이름, 부서, 직함, 체크박스
그룹용 프로필 리스트 아이템
마우스오버 -> 버튼 컴포넌트
다이얼로그 프로필 리스트 아이템
체크박스

View File

@ -0,0 +1,58 @@
todo
다국어 적용
프로필 컴포넌트 정리
org 프로필 컴포넌트 적용
마우스오버 이벤트
히든 버튼 적용
체크박스 이벤트
익스팬션 컴포넌트 정리
그룹 메뉴
그룹별 메뉴 히든 처리
프로필 메뉴
프로필 메뉴 히든 처리
온/오프 리스트
접속동료 리스트
다이얼로그 컴포넌트 정리
관리
삭제, 추가, 이동, 복사, 검색
그룹이름 유효성 검사
선택 컴포넌트 적용
생성
그룹이름 유효성 검사
선택 컴포넌트 적용
한줄 편집
수정
셀렉트 유저 컴포넌트
셀렉트 컴포넌트 적용
셀렉트 그룹 컴포넌트
검색 결과 컴포넌트
그룹명 컴포넌트
// if (params.isChecked) {
// params.groupBuddyList.buddyList.forEach((item) => {
// if (
// this.selectedUserList.filter((user) => user.seq === item.seq)
// .length === 0
// ) {
// this.selectedUserList = [...this.selectedUserList, item];
// }
// });
// } else {
// this.selectedUserList = this.selectedUserList.filter(
// (item) =>
// params.groupBuddyList.buddyList.filter((del) => del.seq === item.seq)
// .length === 0
// );
// }
// this.changeDetectorRef.markForCheck();
// this.changeUserList.emit(this.selectedUserList);

View File

@ -0,0 +1,85 @@
<div
class="ucap-group-profile-list-item-02-container"
(mouseover)="onMouseover($event)"
(mouseleave)="onMouseleave($event)"
>
<div class="user-profile-info">
<div class="profile-image">
<ucap-organization-profile-image-01
ucapGroupProfileListItem02="profileImage"
[userInfo]="userInfo"
[profileImageRoot]="versionInfo2Res?.profileRoot"
defaultProfileImage="assets/images/ico/img_nophoto.svg"
>
</ucap-organization-profile-image-01>
</div>
<div class="user-info">
<div class="user-n-g">
<div class="user-name">
{{ userInfo | ucapOrganizationTranslate: 'name' }}
</div>
<div class="user-grade">
{{ userInfo | ucapOrganizationTranslate: 'grade' }}
</div>
</div>
<div class="dept-name">
{{ userInfo | ucapOrganizationTranslate: 'deptName' }}
</div>
</div>
</div>
<div class="user-info">
<div class="intro">{{ userInfo.intro }}</div>
<div class="nickname">{{ userInfo.nickName }}</div>
</div>
<div *ngIf="isShow || isClickMore">
<ng-template [ngTemplateOutlet]="profileMoreContextTemplate"></ng-template>
</div>
</div>
<ng-template #profileMoreContextTemplate>
<button
mat-icon-button
aria-label="chat"
(click)="onClickProfileContextMenu($event, 'CHAT')"
>
<img src="../../../assets/images/ico/btn_lise_chat_a24.svg" alt="" />
</button>
<button
mat-icon-button
aria-label="message"
(click)="
$event.stopPropagation(); onClickProfileContextMenu($event, 'CHAT')
"
>
<img src="../../../assets/images/ico/btn_list_message_a24.svg" alt="" />
</button>
<button
mat-icon-button
aria-label="mobile"
(click)="onClickProfileContextMenu($event, 'CHAT')"
>
<img src="../../../assets/images/ico/btn_list_mobile_a24.svg" alt="" />
</button>
<button
mat-icon-button
aria-label="call"
(click)="onClickProfileContextMenu($event, 'CHAT')"
>
<img src="../../../assets/images/ico/btn_list_call_a24.svg" alt="" />
</button>
<button
mat-icon-button
aria-label="vc"
(click)="onClickProfileContextMenu($event, 'CHAT')"
>
<img src="../../../assets/images/ico/btn_list_vc-a24.svg" alt="" />
</button>
<button
mat-icon-button
aria-label="more"
*ngIf="true"
(click)="onClickMore($event)"
>
<mat-icon>more_horiz</mat-icon>
</button>
</ng-template>

View File

@ -0,0 +1,101 @@
<div
class="user-list line-top"
*ngIf="userInfo"
(mouseover)="onMouseover($event)"
(mouseleave)="onMouseleave($event)"
>
<div class="user-profile-info">
<div
class="user-profile-thumb"
[ngClass]="
getPresence(PresenceType.MOBILE) === 'online' ? 'mobile-ing' : ''
"
>
<!-- 모바일이 온라인일 경우 + mobile-ing -->
<span
class="presence"
[ngClass]="getPresence(PresenceType.PC)"
[matTooltip]="getPresenceMsg()"
matTooltipPosition="after"
>
</span>
<!-- 기본값:온라인, +offline:오프라인, +absence:부재중, +other-business:다른용무 -->
<!-- <span class="ucap-organization-profile-list-item-presence">bullet</span> -->
<div class="profile-image">
<img
class="thumbnail"
ucapImage
[base]="profileImageRoot"
[path]="userInfo.profileImageFile"
[default]="defaultProfileImage"
(click)="onClickProfileImage($event, userInfo)"
/>
</div>
</div>
<div class="user-info">
<div>
<div class="user-name">
{{ userInfo | ucapOrganizationTranslate: 'name' }}
</div>
<div class="user-grade">
{{ userInfo | ucapOrganizationTranslate: 'grade' }}
</div>
</div>
<div class="dept-name">
{{ userInfo | ucapOrganizationTranslate: 'deptName' }}
</div>
</div>
</div>
<div *ngIf="!isShowMenu && userInfo.nickName === ''" class="intro">
{{ userInfo.intro }}
</div>
<div *ngIf="!isShowMenu && userInfo.nickName !== ''" class="intro">
{{ userInfo.nickName }}
</div>
<div
*ngIf="!checkable && (isShowMenu || isClickMore)"
class="btn-partner-set"
>
<button
mat-icon-button
aria-label="chat"
(click)="onClickProfileContextMenu($event, 'CHAT')"
>
<img src="../../../assets/images/ico/btn_lise_chat_a24.svg" alt="" />
</button>
<button
mat-icon-button
aria-label="message"
(click)="
$event.stopPropagation(); onClickProfileContextMenu($event, 'CHAT')
"
>
<img src="../../../assets/images/ico/btn_list_message_a24.svg" alt="" />
</button>
<!-- <button mat-icon-button aria-label="mobile" *ngIf="getDisabledBtn('MOBILE')" (click)="onClickProfileContextMenu('CHAT')">
<img src="../../../assets/images/ico/btn_list_mobile_a24.svg" alt="" />
</button>
<button mat-icon-button aria-label="call" *ngIf="getDisabledBtn('LINE')" (click)="onClickProfileContextMenu('CHAT')">
<img src="../../../assets/images/ico/btn_list_call_a24.svg" alt="" />
</button>
<button mat-icon-button aria-label="vc" *ngIf="getDisabledBtn('VC')"(click)="onClickProfileContextMenu('CHAT')">
<img src="../../../assets/images/ico/btn_list_vc-a24.svg" alt="" />
</button> -->
<button
mat-icon-button
aria-label="more"
*ngIf="true"
(click)="onClickMore($event)"
>
<mat-icon>more_horiz</mat-icon>
</button>
</div>
<div *ngIf="checkable">
<mat-checkbox
#checkbox
[checked]="isChecked"
(change)="onChangeCheck(checkbox.checked, userInfo)"
></mat-checkbox>
</div>
</div>

View File

@ -0,0 +1,136 @@
@import '~@ucap/lg-scss/mixins';
.user-list {
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
padding: 0 16px;
height: 70px;
align-items: center;
&.line-top {
border-top: 1px solid $gray-rec;
}
.user-profile-info {
display: inline-flex;
flex-direction: row;
flex-grow: 2.3;
.user-profile-thumb {
@include profile-avatar-default(
0 5px 5px 0,
8,
$green,
18px
); //오른 아래 공간, 모바일 온라인 아이콘 크기, 모바일 아이콘 , 모바일 아이콘 bg크기
.presence {
//PC 상태
@include presence-state(8px); //원크기
}
.profile-image {
@include avatar-img(36px, 2px); //아바타 크기, 왼쪽공간
}
}
.user-info {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
padding-left: 16px;
.user-n-g {
display: flex;
flex-flow: row-reverse nowrap;
align-items: flex-end;
height: 22px;
.user-name {
@include ellipsis-column(1);
height: 22px;
font: {
size: 16px;
weight: 600;
}
color: $gray-re21;
order: 1;
-ms-flex-order: 1;
}
.user-grade {
@include ellipsis(1);
align-self: stretch;
font: {
size: 13px;
}
color: $gray-re70;
margin-left: 4px;
order: 0;
-ms-flex-order: 0;
}
}
.dept-name {
@include ellipsis(1);
font-size: 12px;
color: $gray-re6;
line-height: 16px;
}
}
}
.intro {
display: inline-flex;
flex-flow: row nowrap;
flex-basis: 35%;
flex-grow: 0;
align-items: baseline;
p {
font-size: 11px;
line-height: 1.4;
@include ellipsis(2);
height: 30px;
}
&:before {
content: 'chat';
@include font-family-ico($font-ico-default, 12, center, $lipstick);
flex-direction: row;
align-items: flex-start;
width: 12px;
height: 12px;
line-height: 12px;
margin-right: 4.8px;
position: relative;
top: 2px;
}
}
.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: 20px;
margin-top: 20px;
img {
vertical-align: top;
}
}
.intro-name {
display: inline-flex;
flex-flow: row nowrap;
flex-basis: 35%;
align-items: center;
justify-content: center;
overflow: hidden;
span {
display: inline-block;
text-align: center;
width: 100%;
height: 20px;
line-height: 20px;
color: $gray-re70;
font-size: 11px;
padding: 0 10px;
border-radius: 30px;
border: solid 1px $warm-pink;
background-color: #ffffff;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}

View File

@ -0,0 +1,26 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { ProfileListItemComponent } from './profile-list-item.component';
describe('ucap::ucap::organization::ProfileListItemComponent', () => {
let component: ProfileListItemComponent;
let fixture: ComponentFixture<ProfileListItemComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ProfileListItemComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ProfileListItemComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,214 @@
import {
Component,
OnInit,
OnDestroy,
ChangeDetectionStrategy,
ChangeDetectorRef,
Input,
EventEmitter,
Output,
ElementRef,
Self
} from '@angular/core';
import { UserInfo, GroupDetailData } from '@ucap/protocol-sync';
import { UserInfoSS, UserInfoF, UserInfoDN } from '@ucap/protocol-query';
import { UserInfo as RoomUserInfo } from '@ucap/protocol-room';
import { StatusBulkInfo, StatusInfo } from '@ucap/protocol-status';
import { PresenceType, StatusCode } from '@ucap/core';
import { I18nService } from '@ucap/ng-i18n';
import { ucapAnimations } from '@ucap/ng-ui';
export type UserInfoTypes =
| UserInfo
| UserInfoSS
| UserInfoF
| UserInfoDN
| RoomUserInfo;
@Component({
selector: 'app-group-profile-list-item',
templateUrl: './profile-list-item.component.html',
styleUrls: ['./profile-list-item.component.scss'],
animations: ucapAnimations,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProfileListItemComponent implements OnInit, OnDestroy {
@Input()
userInfo: UserInfoF;
@Input()
group: GroupDetailData;
@Input()
isSearchData = false;
@Input()
defaultProfileImage: string;
@Input()
profileImageRoot: string;
@Input()
set presence(info: StatusBulkInfo | StatusInfo) {
this._presence = info;
}
get presence(): StatusBulkInfo | StatusInfo {
return this._presence;
}
_presence: StatusBulkInfo | StatusInfo;
@Input()
showMenu = true;
@Input()
checkable = false;
@Input()
set isChecked(checked: boolean) {
this._isChecked = checked;
}
get isChecked(): boolean {
return this._isChecked;
}
_isChecked = false;
@Output()
checked = new EventEmitter<{
isChecked: boolean;
userInfo: UserInfoTypes;
}>();
@Output()
moreMenu: EventEmitter<{
event: MouseEvent;
userInfo: UserInfoTypes;
group: GroupDetailData;
rect: any;
}> = new EventEmitter();
isClicked = false;
isShowMenu = false;
@Input()
isMe = false;
PresenceType = PresenceType;
isClickMore = false;
constructor(
private changeDetectorRef: ChangeDetectorRef,
private i18nService: I18nService,
@Self() private elementRef: ElementRef
) {
this.i18nService.setDefaultNamespace('organization');
}
ngOnInit(): void {}
ngOnDestroy(): void {}
onClickProfileImage(event: Event, userInfo: UserInfoTypes): void {}
onChangeCheck(value: boolean, userInfo: UserInfoTypes) {
this.checked.emit({
isChecked: value,
userInfo
});
}
getPresence(type: PresenceType): string {
let status: string;
let rtnClass = '';
switch (type) {
case PresenceType.PC:
status = !!this.presence ? this.presence.pcStatus : undefined;
break;
case PresenceType.MOBILE:
status = !!this.presence ? this.presence.mobileStatus : undefined;
break;
}
switch (status) {
case StatusCode.OnLine:
rtnClass = 'online';
break;
case StatusCode.Away:
rtnClass = 'absence';
break;
case StatusCode.Busy:
rtnClass = 'other-business';
break;
default:
rtnClass = 'offline';
break;
}
return rtnClass;
}
getPresenceMsg(): string {
let presenceMsg = this.i18nService.t('presence.offline');
if (!!this.presence) {
switch (this.presence.pcStatus) {
case StatusCode.OnLine:
presenceMsg = this.i18nService.t('presence.online');
break;
case StatusCode.Away:
presenceMsg = this.i18nService.t('presence.away');
break;
case StatusCode.Busy:
if (
!!this.presence.statusMessage &&
this.presence.statusMessage !== '.'
) {
presenceMsg = this.presence.statusMessage;
} else {
presenceMsg = this.i18nService.t('presence.statusMessage1');
}
break;
}
}
return presenceMsg;
}
onClickMore(event: MouseEvent) {
this.isClickMore = true;
const rect = this.elementRef.nativeElement.getBoundingClientRect();
this.moreMenu.emit({
event,
userInfo: this.userInfo,
group: this.group,
rect
});
}
onClickProfileContextMenu(event: MouseEvent, type: string) {}
onClickProfile(event: MouseEvent) {
event.preventDefault();
event.stopPropagation();
if (this.showMenu && !this.isMe) {
this.isShowMenu = true;
}
}
onMouseover(event: MouseEvent): void {
if (this.showMenu && !this.isMe) {
this.isShowMenu = true;
if (this.isClickMore) {
this.isClickMore = false;
}
}
event.preventDefault();
event.stopPropagation();
}
onMouseleave(event: MouseEvent): void {
if (this.showMenu && !this.isMe) {
this.isShowMenu = false;
}
event.preventDefault();
event.stopPropagation();
}
}

View File

@ -0,0 +1,128 @@
<!-- select user section -->
<div *ngIf="isSelectionOff">
<ng-template [ngTemplateOutlet]="selectedUserListTemplate"></ng-template>
</div>
<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>
<!-- select user section -->
<!--
<perfect-scrollbar fxFlex="1 1 auto">
<app-group-profile-list-item
*ngFor="let userInfo of searchUserInfos"
[userInfo]="userInfo"
[checkable]="checkable"
[isChecked]="getCheckedUser(userInfo)"
defaultProfileImage="assets/images/img_nophoto_50.png"
(checked)="onCheckUser($event)"
>
</app-group-profile-list-item>
</perfect-scrollbar>
-->
<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>
manage.dialog.component 버그 (동료 리스트와 선택유저 리스트 동기화)

Binary file not shown.