그룹 > 동료리스트 context menu > 이 그룹에서 삭제, 대화 상대, 대화 상대 이동 :: 기능 구현.
This commit is contained in:
parent
7cd159efba
commit
b3c649c393
|
@ -33,13 +33,13 @@
|
||||||
(more)="onMoreGroup($event)"
|
(more)="onMoreGroup($event)"
|
||||||
>
|
>
|
||||||
<ucap-profile-user-list-item
|
<ucap-profile-user-list-item
|
||||||
*ucapGroupExpansionPanelItem="let userInfo"
|
*ucapGroupExpansionPanelItem="let userInfo; let group = group"
|
||||||
[userInfo]="userInfo"
|
[userInfo]="userInfo"
|
||||||
[presence]="getStatusBulkInfo(userInfo) | async"
|
[presence]="getStatusBulkInfo(userInfo) | async"
|
||||||
[sessionVerinfo]="sessionVerinfo"
|
[sessionVerinfo]="sessionVerinfo"
|
||||||
(click)="onSelectBuddy(userInfo)"
|
(click)="onSelectBuddy(userInfo)"
|
||||||
(openProfile)="onClickOpenProfile($event)"
|
(openProfile)="onClickOpenProfile($event)"
|
||||||
(contextmenu)="onContextMenuProfile($event, userInfo)"
|
(contextmenu)="onContextMenuProfile($event, userInfo, group)"
|
||||||
class="list-item-frame"
|
class="list-item-frame"
|
||||||
>
|
>
|
||||||
</ucap-profile-user-list-item>
|
</ucap-profile-user-list-item>
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
[hasBackdrop]="false"
|
[hasBackdrop]="false"
|
||||||
(ucapClickOutside)="profileContextMenuTrigger.closeMenu()"
|
(ucapClickOutside)="profileContextMenuTrigger.closeMenu()"
|
||||||
>
|
>
|
||||||
<ng-template matMenuContent let-userInfo="userInfo">
|
<ng-template matMenuContent let-userInfo="userInfo" let-group="group">
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
(click)="onClickProfileContextMenu('VIEW_PROFILE', userInfo)"
|
(click)="onClickProfileContextMenu('VIEW_PROFILE', userInfo)"
|
||||||
|
@ -130,7 +130,7 @@
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*ngIf="getShowContextMenu(userInfo)"
|
*ngIf="getShowContextMenu('REGISTER_FAVORITE', userInfo, group)"
|
||||||
(click)="onClickProfileContextMenu('REGISTER_FAVORITE', userInfo)"
|
(click)="onClickProfileContextMenu('REGISTER_FAVORITE', userInfo)"
|
||||||
>
|
>
|
||||||
즐겨찾기 {{ userInfo.isFavorit ? '해제' : '등록' }}
|
즐겨찾기 {{ userInfo.isFavorit ? '해제' : '등록' }}
|
||||||
|
@ -140,39 +140,39 @@
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*ngIf="getShowContextMenu(userInfo)"
|
*ngIf="getShowContextMenu('REMOVE_FROM_GROUP', userInfo, group)"
|
||||||
(click)="onClickProfileContextMenu('REMOVE_FROM_GROUP', userInfo)"
|
(click)="onClickProfileContextMenu('REMOVE_FROM_GROUP', userInfo, group)"
|
||||||
>
|
>
|
||||||
이 그룹에서 삭제
|
이 그룹에서 삭제
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*ngIf="getShowContextMenu(userInfo)"
|
*ngIf="getShowContextMenu('COPY_BUDDY', userInfo, group)"
|
||||||
(click)="onClickProfileContextMenu('COPY_BUDDY', userInfo)"
|
(click)="onClickProfileContextMenu('COPY_BUDDY', userInfo)"
|
||||||
>
|
>
|
||||||
대화 상대 복사
|
대화 상대 복사
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*ngIf="getShowContextMenu(userInfo)"
|
*ngIf="getShowContextMenu('MOVE_BUDDY', userInfo, group)"
|
||||||
(click)="onClickProfileContextMenu('MOVE_BUDDY', userInfo)"
|
(click)="onClickProfileContextMenu('MOVE_BUDDY', userInfo, group)"
|
||||||
>
|
>
|
||||||
대화 상대 이동
|
대화 상대 이동
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*ngIf="getShowContextMenu(userInfo)"
|
*ngIf="getShowContextMenu('SEND_NOTE', userInfo, group)"
|
||||||
(click)="onClickProfileContextMenu('SEND_NOTE', userInfo)"
|
(click)="onClickProfileContextMenu('SEND_NOTE', userInfo)"
|
||||||
>
|
>
|
||||||
쪽지 보내기
|
쪽지 보내기
|
||||||
</button>
|
</button>
|
||||||
<button
|
<!-- <button
|
||||||
mat-menu-item
|
mat-menu-item
|
||||||
*ngIf="getShowContextMenu(userInfo)"
|
*ngIf="getShowContextMenu('REGISTER_NICKNAME', userInfo, group)"
|
||||||
(click)="onClickProfileContextMenu('REGISTER_NICKNAME', userInfo)"
|
(click)="onClickProfileContextMenu('REGISTER_NICKNAME', userInfo)"
|
||||||
>
|
>
|
||||||
닉네임 설정
|
닉네임 설정
|
||||||
</button>
|
</button> -->
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,11 @@ import {
|
||||||
EditGroupDialogData,
|
EditGroupDialogData,
|
||||||
EditGroupDialogResult
|
EditGroupDialogResult
|
||||||
} from '@app/layouts/messenger/dialogs/group/edit-group.dialog.component';
|
} from '@app/layouts/messenger/dialogs/group/edit-group.dialog.component';
|
||||||
|
import {
|
||||||
|
SelectGroupDialogComponent,
|
||||||
|
SelectGroupDialogResult,
|
||||||
|
SelectGroupDialogData
|
||||||
|
} from '../../dialogs/group/select-group.dialog.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-layout-chat-left-sidenav-group',
|
selector: 'app-layout-chat-left-sidenav-group',
|
||||||
|
@ -281,20 +286,42 @@ export class GroupComponent implements OnInit, OnDestroy {
|
||||||
this.searchUserInfos = [];
|
this.searchUserInfos = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
getShowContextMenu(userInfo: UserInfo | UserInfoF) {
|
getShowContextMenu(
|
||||||
|
menuType: string,
|
||||||
|
userInfo: UserInfo | UserInfoF,
|
||||||
|
group?: GroupDetailData
|
||||||
|
) {
|
||||||
if (userInfo.seq === this.loginRes.userSeq) {
|
if (userInfo.seq === this.loginRes.userSeq) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!group || group === undefined) {
|
||||||
|
if (
|
||||||
|
menuType === 'REGISTER_FAVORITE' ||
|
||||||
|
menuType === 'SEND_NOTE' ||
|
||||||
|
menuType === 'REGISTER_NICKNAME'
|
||||||
|
) {
|
||||||
|
// continue;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
onClickProfileContextMenu(menuType: string, userInfo: UserInfo | UserInfoF) {
|
async onClickProfileContextMenu(
|
||||||
|
menuType: string,
|
||||||
|
userInfo: UserInfo | UserInfoF,
|
||||||
|
group?: GroupDetailData
|
||||||
|
) {
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
'onClickProfileContextMenu',
|
'onClickProfileContextMenu',
|
||||||
'menuType',
|
'menuType',
|
||||||
menuType,
|
menuType,
|
||||||
'userInfo',
|
'userInfo',
|
||||||
userInfo
|
userInfo,
|
||||||
|
'group',
|
||||||
|
group
|
||||||
);
|
);
|
||||||
switch (menuType) {
|
switch (menuType) {
|
||||||
case 'VIEW_PROFILE':
|
case 'VIEW_PROFILE':
|
||||||
|
@ -303,6 +330,98 @@ export class GroupComponent implements OnInit, OnDestroy {
|
||||||
case 'CHAT':
|
case 'CHAT':
|
||||||
this.onSelectBuddy(userInfo);
|
this.onSelectBuddy(userInfo);
|
||||||
break;
|
break;
|
||||||
|
case 'REMOVE_FROM_GROUP':
|
||||||
|
{
|
||||||
|
const result = await this.dialogService.open<
|
||||||
|
ConfirmDialogComponent,
|
||||||
|
ConfirmDialogData,
|
||||||
|
ConfirmDialogResult
|
||||||
|
>(ConfirmDialogComponent, {
|
||||||
|
width: '360px',
|
||||||
|
data: {
|
||||||
|
title: 'Delete Member in Group',
|
||||||
|
html: `[${userInfo.name} ${userInfo.grade}]를 [${group.name}]그룹에서 삭제하시겠습니까?`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!!result && !!result.choice && result.choice) {
|
||||||
|
const trgtUserSeq = group.userSeqs.filter(
|
||||||
|
user => user !== userInfo.seq
|
||||||
|
);
|
||||||
|
this.store.dispatch(
|
||||||
|
SyncStore.updateGroupMember({
|
||||||
|
oldGroup: group,
|
||||||
|
trgtUserSeq
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'COPY_BUDDY':
|
||||||
|
{
|
||||||
|
const result = await this.dialogService.open<
|
||||||
|
SelectGroupDialogComponent,
|
||||||
|
SelectGroupDialogData,
|
||||||
|
SelectGroupDialogResult
|
||||||
|
>(SelectGroupDialogComponent, {
|
||||||
|
width: '600px',
|
||||||
|
data: {
|
||||||
|
title: 'Group Select'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!!result && !!result.choice && result.choice) {
|
||||||
|
if (!!result.group) {
|
||||||
|
const oldGroup: GroupDetailData = result.group;
|
||||||
|
const trgtUserSeq: number[] = [];
|
||||||
|
let exist = false;
|
||||||
|
result.group.userSeqs.map(seq => {
|
||||||
|
trgtUserSeq.push(seq);
|
||||||
|
if (seq === userInfo.seq) {
|
||||||
|
exist = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!exist) {
|
||||||
|
trgtUserSeq.push(userInfo.seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.store.dispatch(
|
||||||
|
SyncStore.updateGroupMember({
|
||||||
|
oldGroup,
|
||||||
|
trgtUserSeq
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'MOVE_BUDDY':
|
||||||
|
{
|
||||||
|
const result = await this.dialogService.open<
|
||||||
|
SelectGroupDialogComponent,
|
||||||
|
SelectGroupDialogData,
|
||||||
|
SelectGroupDialogResult
|
||||||
|
>(SelectGroupDialogComponent, {
|
||||||
|
width: '600px',
|
||||||
|
data: {
|
||||||
|
title: 'Group Select'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!!result && !!result.choice && result.choice) {
|
||||||
|
if (!!result.group) {
|
||||||
|
this.store.dispatch(
|
||||||
|
SyncStore.moveGroupMember({
|
||||||
|
fromGroup: group,
|
||||||
|
toGroup: result.group,
|
||||||
|
trgtUserSeq: [userInfo.seq]
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'REGISTER_FAVORITE':
|
case 'REGISTER_FAVORITE':
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
SyncStore.updateBuddy({
|
SyncStore.updateBuddy({
|
||||||
|
@ -320,7 +439,8 @@ export class GroupComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
onContextMenuProfile(
|
onContextMenuProfile(
|
||||||
event: MouseEvent,
|
event: MouseEvent,
|
||||||
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN
|
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN,
|
||||||
|
group: GroupDetailData
|
||||||
) {
|
) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
@ -328,7 +448,7 @@ export class GroupComponent implements OnInit, OnDestroy {
|
||||||
this.profileContextMenuPosition.x = event.clientX + 'px';
|
this.profileContextMenuPosition.x = event.clientX + 'px';
|
||||||
this.profileContextMenuPosition.y = event.clientY + 'px';
|
this.profileContextMenuPosition.y = event.clientY + 'px';
|
||||||
this.profileContextMenuTrigger.menu.focusFirstItem('mouse');
|
this.profileContextMenuTrigger.menu.focusFirstItem('mouse');
|
||||||
this.profileContextMenuTrigger.menuData = { userInfo };
|
this.profileContextMenuTrigger.menuData = { userInfo, group };
|
||||||
this.profileContextMenuTrigger.openMenu();
|
this.profileContextMenuTrigger.openMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,23 @@ export const updateGroupMemberFailure = createAction(
|
||||||
'[Messenger::Sync] Update Group Member Failure',
|
'[Messenger::Sync] Update Group Member Failure',
|
||||||
props<{ error: any }>()
|
props<{ error: any }>()
|
||||||
);
|
);
|
||||||
|
/** 그룹원 이동 */
|
||||||
|
export const moveGroupMember = createAction(
|
||||||
|
'[Messenger::Sync] Move Group Member',
|
||||||
|
props<{
|
||||||
|
fromGroup: GroupDetailData;
|
||||||
|
toGroup: GroupDetailData;
|
||||||
|
trgtUserSeq: number[];
|
||||||
|
}>()
|
||||||
|
);
|
||||||
|
export const moveGroupToFailure = createAction(
|
||||||
|
'[Messenger::Sync] Move Group Member / To',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
export const moveGroupFromFailure = createAction(
|
||||||
|
'[Messenger::Sync] Move Group Member / From',
|
||||||
|
props<{ error: any }>()
|
||||||
|
);
|
||||||
|
|
||||||
/** 동료 추가 */
|
/** 동료 추가 */
|
||||||
export const addBuddy = createAction(
|
export const addBuddy = createAction(
|
||||||
|
|
|
@ -48,7 +48,10 @@ import {
|
||||||
delGroup,
|
delGroup,
|
||||||
delGroupFailure,
|
delGroupFailure,
|
||||||
delGroupSuccess,
|
delGroupSuccess,
|
||||||
delBuddyAndClear
|
delBuddyAndClear,
|
||||||
|
moveGroupMember,
|
||||||
|
moveGroupFromFailure,
|
||||||
|
moveGroupToFailure
|
||||||
} from './actions';
|
} from './actions';
|
||||||
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
||||||
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
|
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
|
||||||
|
@ -623,6 +626,67 @@ export class Effects {
|
||||||
{ dispatch: false }
|
{ dispatch: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
moveGroupMember$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(moveGroupMember),
|
||||||
|
withLatestFrom(
|
||||||
|
this.store.pipe(
|
||||||
|
select(
|
||||||
|
(state: any) =>
|
||||||
|
state.messenger.sync.group2.entities as Dictionary<
|
||||||
|
GroupDetailData
|
||||||
|
>
|
||||||
|
)
|
||||||
|
),
|
||||||
|
this.store.pipe(
|
||||||
|
select((state: any) => state.messenger.sync.group2.syncDate as string)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
exhaustMap(([action, groupList, syncDate]) => {
|
||||||
|
// copy to
|
||||||
|
let toTrgtUserSeqs = groupList[action.toGroup.seq].userSeqs;
|
||||||
|
action.trgtUserSeq.forEach(trgtSeq => {
|
||||||
|
if (toTrgtUserSeqs.indexOf(trgtSeq) > -1) {
|
||||||
|
// ignore
|
||||||
|
} else {
|
||||||
|
toTrgtUserSeqs = toTrgtUserSeqs.concat(trgtSeq);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.groupProtocolService
|
||||||
|
.update2({
|
||||||
|
groupSeq: action.toGroup.seq,
|
||||||
|
groupName: action.toGroup.name,
|
||||||
|
userSeqs: toTrgtUserSeqs
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
exhaustMap((resTo: GroupUpdateResponse) => {
|
||||||
|
// del from
|
||||||
|
const fromTrgtUserSeqs = groupList[action.fromGroup.seq].userSeqs;
|
||||||
|
|
||||||
|
return this.groupProtocolService
|
||||||
|
.update2({
|
||||||
|
groupSeq: action.fromGroup.seq,
|
||||||
|
groupName: action.fromGroup.name,
|
||||||
|
userSeqs: fromTrgtUserSeqs.filter(
|
||||||
|
trgtSeq => action.trgtUserSeq.indexOf(trgtSeq) < 0
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
map((resFrom: GroupUpdateResponse) => {
|
||||||
|
return group2({
|
||||||
|
syncDate
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
catchError(error => of(moveGroupFromFailure({ error })))
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
catchError(error => of(moveGroupToFailure({ error })))
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
delGroup$ = createEffect(() =>
|
delGroup$ = createEffect(() =>
|
||||||
this.actions$.pipe(
|
this.actions$.pipe(
|
||||||
ofType(delGroup),
|
ofType(delGroup),
|
||||||
|
|
|
@ -19,10 +19,12 @@
|
||||||
<div class="mat-tree-node">
|
<div class="mat-tree-node">
|
||||||
<ng-container
|
<ng-container
|
||||||
[ngTemplateOutlet]="expansionPanelItemTemplateRef"
|
[ngTemplateOutlet]="expansionPanelItemTemplateRef"
|
||||||
[ngTemplateOutletContext]="{ $implicit: node?.userInfo }"
|
[ngTemplateOutletContext]="{
|
||||||
|
$implicit: node?.userInfo,
|
||||||
|
group: node?.groupDetail
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<!--{{ node?.userInfo?.name }}-->
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</mat-tree-node>
|
</mat-tree-node>
|
||||||
|
|
|
@ -119,6 +119,7 @@ export class ExpansionPanelComponent
|
||||||
item.buddyList.forEach(userInfo => {
|
item.buddyList.forEach(userInfo => {
|
||||||
groupNode.children.push({
|
groupNode.children.push({
|
||||||
nodeType: NodeType.Buddy,
|
nodeType: NodeType.Buddy,
|
||||||
|
groupDetail: item.group,
|
||||||
userInfo
|
userInfo
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user