import { Subject, of } from 'rxjs'; import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, Inject, ComponentFactoryResolver, ViewChild, ViewContainerRef, ComponentRef } from '@angular/core'; import { Store } from '@ngrx/store'; import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog'; import { UserInfo, GroupDetailData } from '@ucap/protocol-sync'; import { UserInfoSS, UserInfoF, UserInfoDN } from '@ucap/protocol-query'; import { UserInfo as RoomUserInfo } from '@ucap/protocol-room'; import { MatStepper } from '@angular/material/stepper'; import { I18nService } from '@ucap/ng-i18n'; import { GroupActions } from '@ucap/ng-store-group'; import { AlertDialogComponent, AlertDialogData, AlertDialogResult, ConfirmDialogComponent, ConfirmDialogResult, ConfirmDialogData } from '@ucap/ng-ui'; import { SelectUserSectionComponent } from '../components/select-user.section.component'; import { take, map, catchError } from 'rxjs/operators'; import { SelectGroupSectionComponent } from '../components/select-group.section.component'; import { SelectUserDialogType, GroupUserDialaogType } from '@app/types'; export type UserInfoTypes = | UserInfo | UserInfoSS | UserInfoF | UserInfoDN | RoomUserInfo; export enum ManageContentType { Add = 'ADD_COMPONENT', Copy = 'COPY_COMPONENT', Move = 'MOVE_COMPONENT', Delete = 'DELETE_COMPONENT', None = 'NONE_COMPONENT' } export interface ManageDialogData { title: string; groupBuddyList?: { group: GroupDetailData; buddyList: UserInfo[] }; } export interface ManageDialogResult { type: GroupUserDialaogType; groupName: string; group?: GroupDetailData; selelctUserList?: UserInfoTypes[]; selectGroupList?: GroupDetailData[]; } @Component({ selector: 'app-dialog-group-manage', templateUrl: './manage.dialog.component.html', styleUrls: ['./manage.dialog.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class ManageDialogComponent implements OnInit, OnDestroy { constructor( public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: ManageDialogData, private changeDetectorRef: ChangeDetectorRef, private store: Store, private i18nService: I18nService, public dialog: MatDialog, private cfResolver: ComponentFactoryResolver ) {} @ViewChild('dialogContainer', { static: true, read: ViewContainerRef }) dialogContainer: ViewContainerRef; componentRef: ComponentRef; private ngOnDestroySubject: Subject; currentType: GroupUserDialaogType; SelectUserDialogType = SelectUserDialogType; GroupUserDialaogType = GroupUserDialaogType; currentStep = 0; groupName = ''; ManageContentType = ManageContentType; selectedUserList: UserInfoTypes[]; selectedGroupList: GroupDetailData[]; selectContentType: ManageContentType; ngOnInit(): void { this.ngOnDestroySubject = new Subject(); this.selectedUserList = []; this.selectContentType = ManageContentType.None; } ngOnDestroy(): void { if (!!this.ngOnDestroySubject) { this.ngOnDestroySubject.next(); this.ngOnDestroySubject.complete(); } } onClosed(event: MouseEvent): void { this.dialogRef.close(); } onDelete(stepper: MatStepper) { if ( !!this.selectedUserList && this.selectedUserList.length > 0 && this.currentStep === 0 ) { let titleStr = ''; this.selectedUserList.forEach((user, idx) => { let userTitle = user.name + ' ' + user.grade; if (idx < this.selectedUserList.length) { userTitle = userTitle + ', '; } titleStr = titleStr.concat('', userTitle); }); const dialogRef = this.dialog.open< ConfirmDialogComponent, ConfirmDialogData, ConfirmDialogResult >(ConfirmDialogComponent, { panelClass: 'min-create-dialog', data: { title: '동료 삭제', html: titleStr + '을 삭제하시겠습니까?' } }); dialogRef .afterClosed() .pipe( take(1), map((result) => { if (!!result && result.choice) { const trgtUserSeq: string[] = []; this.selectedUserList.forEach((userIfno) => { const tempSeqs = this.data.groupBuddyList.group.userSeqs.filter( (seq) => seq !== userIfno.seq ); tempSeqs.map((seq) => trgtUserSeq.push(seq)); }); console.log(trgtUserSeq); this.store.dispatch( GroupActions.updateMember({ targetGroup: this.data.groupBuddyList.group, targetUserSeqs: trgtUserSeq }) ); this.dialogRef.close(); } }), catchError((err) => { return of(err); }) ) .subscribe(); } } onUpdateMember(stepper: MatStepper, type: GroupUserDialaogType) { this.dialogContainer.clear(); this.currentType = type; this.selectedGroupList = []; const isMemberMove = type === GroupUserDialaogType.Copy ? false : true; const factory = this.cfResolver.resolveComponentFactory( SelectGroupSectionComponent ); this.componentRef = this.dialogContainer.createComponent(factory); const cpInstance = this.componentRef.instance; // cpInstance.title = title; cpInstance.isMemberMove = isMemberMove; cpInstance.isDialog = true; cpInstance.checkable = true; cpInstance.curGroup = this.data.groupBuddyList.group; cpInstance.selectedGroupList = this.selectedGroupList; cpInstance.selectedUserList = this.selectedUserList; cpInstance.changeUserList.subscribe( (datas: { checked: boolean; userInfo: UserInfoSS }[]) => { this.changeSelectedUserList(datas); cpInstance.selectedUserList = this.selectedUserList; } ); cpInstance.changeGroupList.subscribe((data: { group: GroupDetailData }) => { if ( this.selectedGroupList.filter((g) => g.seq === data.group.seq) .length === 0 ) { this.selectedGroupList = [...this.selectedGroupList, data.group]; } else { this.selectedGroupList = this.selectedGroupList.filter( (g) => g.seq !== data.group.seq ); } cpInstance.selectedGroupList = this.selectedGroupList; }); cpInstance.changeGroupName.subscribe((groupName) => { this.groupName = groupName; }); this.currentStep++; stepper.next(); } onAdd(stepper: MatStepper) { this.dialogContainer.clear(); this.currentType = GroupUserDialaogType.Add; const factory = this.cfResolver.resolveComponentFactory( SelectUserSectionComponent ); this.componentRef = this.dialogContainer.createComponent(factory); const cpInstance = this.componentRef.instance; cpInstance.isDialog = true; cpInstance.checkable = true; cpInstance.selectedUserList = this.data.groupBuddyList.buddyList; // const cpElement: HTMLElement = this.componentRef.location.nativeElement; // cpElement.style.height = '400px'; cpInstance.toggleCheckUser.subscribe( (datas: { checked: boolean; userInfo: UserInfoSS }[]) => { this.changeSelectedUserList(datas); cpInstance.selectedUserList = this.selectedUserList; } ); this.currentStep++; stepper.next(); } onChangeUserList(datas: { checked: boolean; userInfo: UserInfoSS }[]) { this.changeSelectedUserList(datas); } private changeSelectedUserList( datas: { checked: boolean; userInfo: UserInfoSS; }[] ) { if (!datas || 0 === datas.length) { return; } const pushs: UserInfoSS[] = []; const pops: UserInfoSS[] = []; datas.forEach((d) => { const i = this.selectedUserList.findIndex( (u) => u.seq === d.userInfo.seq ); if (d.checked) { if (-1 === i) { pushs.push(d.userInfo); } } else { if (-1 < i) { pops.push(d.userInfo); } } }); if (0 < pushs.length) { this.selectedUserList = [...this.selectedUserList, ...pushs]; } if (0 < pops.length) { this.selectedUserList = this.selectedUserList.filter( (u) => -1 === pops.findIndex((p) => p.seq === u.seq) ); } } onCnacel(stepper: MatStepper) { if (!!this.selectedUserList && this.selectedUserList.length > 0) { this.selectedUserList = []; } this.currentStep--; stepper.previous(); } onConfirm(stepper: MatStepper) { switch (this.currentType) { case GroupUserDialaogType.Add: { if (!!this.selectedUserList && this.selectedUserList.length > 0) { this.doAction(); } } break; case GroupUserDialaogType.Copy: case GroupUserDialaogType.Move: { if ( !!this.selectedUserList && this.selectedUserList.length === 0 && this.groupName === '' ) { this.dialog.open< AlertDialogComponent, AlertDialogData, AlertDialogResult >(AlertDialogComponent, { panelClass: 'min-create-dialog', data: { title: 'Error', html: '선택된 유저가 없습니다.' } }); return; } this.doAction(); } break; } } doAction() { this.dialogContainer.clear(); if (!!this.groupName && this.groupName.trim().localeCompare('') !== 0) { this.currentType = GroupUserDialaogType.Create; } else { this.groupName = undefined; } this.dialogRef.close({ type: this.currentType, groupName: this.groupName, group: this.data.groupBuddyList.group, selelctUserList: this.selectedUserList, selectGroupList: this.selectedGroupList }); } /** 개별 체크여부 */ getCheckedUser(userInfo: UserInfoSS) { if (!!this.selectedUserList && this.selectedUserList.length > 0) { return ( this.selectedUserList.filter( (item) => (item.seq as any) === (userInfo.seq as any) ).length > 0 ); } return false; } onToggleCheck(data: { checked: boolean; userInfo: UserInfoSS }) { this.changeSelectedUserList([data]); } onRemovedProfileSelection(userInfo: UserInfo) { const i = this.selectedUserList.findIndex( (u) => (u.seq as any) === (userInfo.seq as any) ); if (-1 < i) { this.selectedUserList = this.selectedUserList.filter( (u) => (u.seq as any) !== (userInfo.seq as any) ); } } removableForSelection = (userInfo: UserInfo) => { return true; }; colorForSelection = (userInfo: UserInfo) => { return 'accent'; }; }