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. (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 계산, 적용, 취소에 대한 처리, 액션 처리 그룹 삭제 => 사용자 확인 다이얼로그 출력 및 액션에 대한 처리 익스팬션 프로필 리스트 아이템 출력 프로필 메뉴, 프레젠스, 프로핊 이미지, 이름, 직함, 부서, 인트로, 닉네임 기능 프로필 보기 즐겨 찾기 설정 닉네임 설정 대화 상대 복사, 이동 삭제 마우스오버&리브 이벤트에 대한 버튼 출력 모어 메뉴 출력 포지션 계산 검색 출력 입력창, 검색 버튼, 입력 삭제 버튼, 회사 리스트 기능 입력 이벤트 검색 액션 처리 삭제 버튼 액션 처리 회사 리스트 조회 셀렉트 그룹 검색 그룹명 입력 기존 그룹 리스트 체크박스 셀렉트 유저 익스팬션 프로필 리스트 아이템 프레젠스, 프로필 이미지, 이름, 부서, 직함, 체크박스 그룹용 프로필 리스트 아이템 마우스오버 -> 버튼 컴포넌트 다이얼로그 프로필 리스트 아이템 체크박스