조직도 detail > 그룹에 추가, 대화, 화상회의 연결.
This commit is contained in:
parent
e7356b3ad3
commit
bf351bf690
|
@ -15,6 +15,7 @@
|
|||
|
||||
<app-layout-messenger-organization
|
||||
(openProfile)="onClickOpenProfile($event)"
|
||||
(createConference)="onClickConferenceCreate($event)"
|
||||
[style.display]="
|
||||
MainMenu.Organization === (this.gnbMenuIndex$ | async) ? 'block' : 'none'
|
||||
"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { OpenProfileOptions } from '@ucap-webmessenger/protocol-buddy';
|
||||
|
||||
import * as AppStore from '@app/store';
|
||||
import { select, Store } from '@ngrx/store';
|
||||
|
@ -24,6 +23,9 @@ export class MainContentsComponent implements OnInit {
|
|||
@Output()
|
||||
closeRightDrawer = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
createConference = new EventEmitter<number[]>();
|
||||
|
||||
MainMenu = MainMenu;
|
||||
gnbMenuIndex$: Observable<string>;
|
||||
|
||||
|
@ -42,4 +44,8 @@ export class MainContentsComponent implements OnInit {
|
|||
onCloseRightDrawer() {
|
||||
this.closeRightDrawer.emit();
|
||||
}
|
||||
|
||||
onClickConferenceCreate(userSeqs: number[]) {
|
||||
this.createConference.emit(userSeqs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<ng-container *ngIf="!!(isSearch | async)">
|
||||
{{ 'common.searchResult' | translate
|
||||
}}<span class="text-accent-color"
|
||||
>({{ selectedDepartmentUserInfoList.length }}
|
||||
>({{ departmentUserInfoList.length }}
|
||||
{{ 'common.units.persons' | translate }})</span
|
||||
>
|
||||
</ng-container>
|
||||
|
@ -49,10 +49,14 @@
|
|||
<div fxFlex="auto" class="organization-content">
|
||||
<div fxFlex="0 0 auto" class="table-box">
|
||||
<ucap-organization-detail-table
|
||||
[loginRes]="loginRes"
|
||||
[presence]="presence$ | async"
|
||||
[selectedDepartmentUserInfoList]="selectedDepartmentUserInfoList"
|
||||
[departmentUserInfoList]="departmentUserInfoList"
|
||||
[profileImageRoot]="profileImageRoot"
|
||||
[selectedUserList]="selectedUserList"
|
||||
(openProfile)="onClickOpenProfile($event)"
|
||||
(toggleAllUser)="onToggleAllUser($event)"
|
||||
(toggleUser)="onToggleUser($event)"
|
||||
class="detail-table"
|
||||
></ucap-organization-detail-table>
|
||||
</div>
|
||||
|
@ -63,22 +67,60 @@
|
|||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Personal data
|
||||
{{ 'organization.selectedUser' | translate }}
|
||||
<span *ngIf="selectedUserList.length > 0">
|
||||
({{ selectedUserList.length }})
|
||||
{{ 'common.units.persons' | translate }}
|
||||
</span>
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Type your name and age
|
||||
</mat-panel-description>
|
||||
<mat-panel-description> </mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>First name</mat-label>
|
||||
<input matInput />
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Age</mat-label>
|
||||
<input matInput type="number" min="1" />
|
||||
</mat-form-field>
|
||||
<div class="list-chip">
|
||||
<mat-chip-list aria-label="User selection">
|
||||
<mat-chip
|
||||
*ngFor="let userInfo of selectedUserList"
|
||||
(removed)="onClickDeleteUser(userInfo)"
|
||||
>
|
||||
{{ userInfo.name }}
|
||||
<mat-icon matChipRemove>clear</mat-icon>
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
</div>
|
||||
<div class="btn-box">
|
||||
<ul>
|
||||
<li>
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="selectedUserList.length > 0 ? 'false' : 'true'"
|
||||
(click)="onClickAddGroup()"
|
||||
class="mat-primary"
|
||||
>
|
||||
{{ 'organization.addToGroup' | translate }}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="selectedUserList.length > 0 ? 'false' : 'true'"
|
||||
(click)="onClickChatOpen()"
|
||||
class="mat-primary"
|
||||
>
|
||||
{{ 'organization.startChat' | translate }}
|
||||
</button>
|
||||
</li>
|
||||
<li *ngIf="!!authInfo && authInfo.canVideoConference">
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="selectedUserList.length > 0 ? 'false' : 'true'"
|
||||
(click)="onClickConference()"
|
||||
class="mat-primary"
|
||||
>
|
||||
{{ 'organization.startVideoConference' | translate }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</div>
|
||||
|
|
|
@ -103,3 +103,36 @@
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
padding: 10px;
|
||||
button {
|
||||
width: 100%;
|
||||
@include ellipsis(1);
|
||||
span {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-content: space-between;
|
||||
margin-top: 4px;
|
||||
li {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
width: 33%;
|
||||
margin-right: 4px;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
button {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,11 @@ import {
|
|||
Output,
|
||||
EventEmitter
|
||||
} from '@angular/core';
|
||||
import { SelectedDept, UserInfoSS } from '@ucap-webmessenger/protocol-query';
|
||||
import {
|
||||
SelectedDept,
|
||||
UserInfoSS,
|
||||
AuthResponse
|
||||
} from '@ucap-webmessenger/protocol-query';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { DialogService } from '@ucap-webmessenger/ui';
|
||||
|
@ -25,8 +29,16 @@ import {
|
|||
WorkStatusType
|
||||
} from '@ucap-webmessenger/protocol-status';
|
||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
||||
import { KEY_VER_INFO } from '@app/types';
|
||||
import { KEY_VER_INFO, KEY_AUTH_INFO } from '@app/types';
|
||||
import { Sort } from '@angular/material/sort';
|
||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import {
|
||||
SelectGroupDialogComponent,
|
||||
SelectGroupDialogData,
|
||||
SelectGroupDialogResult
|
||||
} from '../../dialogs/group/select-group.dialog.component';
|
||||
import { GroupDetailData } from '@ucap-webmessenger/protocol-sync';
|
||||
|
||||
@Component({
|
||||
selector: 'app-layout-messenger-organization',
|
||||
|
@ -36,8 +48,13 @@ import { Sort } from '@angular/material/sort';
|
|||
export class OrganizationComponent implements OnInit, OnDestroy {
|
||||
@Output()
|
||||
openProfile = new EventEmitter<number>();
|
||||
@Output()
|
||||
createConference = new EventEmitter<number[]>();
|
||||
|
||||
loginRes: LoginResponse;
|
||||
loginResSubscription: Subscription;
|
||||
sessionVerinfo: VersionInfo2Response;
|
||||
authInfo: AuthResponse;
|
||||
|
||||
isSearch: boolean;
|
||||
isSearchSubscription: Subscription;
|
||||
|
@ -47,7 +64,9 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
departmentUserInfoListSubscription: Subscription;
|
||||
searchDepartmentUserInfoListSubscription: Subscription;
|
||||
|
||||
selectedDepartmentUserInfoList: UserInfoSS[] = [];
|
||||
departmentUserInfoList: UserInfoSS[] = [];
|
||||
|
||||
selectedUserList: UserInfoSS[] = []; // selected user in departmentUserList detail
|
||||
|
||||
profileImageRoot: string;
|
||||
presence$: Observable<StatusBulkInfo[]>;
|
||||
|
@ -64,9 +83,19 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
|
||||
KEY_VER_INFO
|
||||
);
|
||||
this.authInfo = this.sessionStorageService.get<AuthResponse>(KEY_AUTH_INFO);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.loginResSubscription = this.store
|
||||
.pipe(
|
||||
select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
|
||||
tap(loginRes => {
|
||||
this.loginRes = loginRes;
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
|
||||
this.isSearchSubscription = this.store
|
||||
.pipe(select(AppStore.MessengerSelector.QuerySelector.isSearch))
|
||||
.subscribe(isSearch => {
|
||||
|
@ -89,7 +118,7 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
)
|
||||
.subscribe(list => {
|
||||
if (!this.isSearch) {
|
||||
this.selectedDepartmentUserInfoList = list;
|
||||
this.departmentUserInfoList = list;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -101,7 +130,7 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
)
|
||||
.subscribe(list => {
|
||||
if (!!this.isSearch) {
|
||||
this.selectedDepartmentUserInfoList = list;
|
||||
this.departmentUserInfoList = list;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -113,6 +142,9 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (!!this.loginResSubscription) {
|
||||
this.loginResSubscription.unsubscribe();
|
||||
}
|
||||
if (!!this.isSearchSubscription) {
|
||||
this.isSearchSubscription.unsubscribe();
|
||||
}
|
||||
|
@ -124,6 +156,97 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
/** Selected User Handling */
|
||||
onToggleAllUser(params: { isChecked: boolean; userInfos: UserInfoSS[] }) {
|
||||
params.userInfos.forEach(userInfo => {
|
||||
if (params.isChecked) {
|
||||
if (
|
||||
this.selectedUserList.filter(user => user.seq === userInfo.seq)
|
||||
.length === 0
|
||||
) {
|
||||
this.selectedUserList = [...this.selectedUserList, userInfo];
|
||||
}
|
||||
} else {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
user => user.seq !== userInfo.seq
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
onToggleUser(userInfo: UserInfoSS) {
|
||||
if (userInfo.seq === this.loginRes.userSeq) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
this.selectedUserList.filter(user => user.seq === userInfo.seq).length ===
|
||||
0
|
||||
) {
|
||||
this.selectedUserList = [...this.selectedUserList, userInfo];
|
||||
} else {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
item => item.seq !== userInfo.seq
|
||||
);
|
||||
}
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
/** Handling chipset for selectedUserList */
|
||||
/** 선택된 사용자 취소 */
|
||||
onClickDeleteUser(userInfo: UserInfoSS) {
|
||||
this.selectedUserList = this.selectedUserList.filter(
|
||||
item => item.seq !== userInfo.seq
|
||||
);
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
|
||||
/** Handling Button */
|
||||
async onClickAddGroup() {
|
||||
this.logger.debug('onClickAddGroup', this.selectedUserList);
|
||||
|
||||
const result = await this.dialogService.open<
|
||||
SelectGroupDialogComponent,
|
||||
SelectGroupDialogData,
|
||||
SelectGroupDialogResult
|
||||
>(SelectGroupDialogComponent, {
|
||||
width: '600px',
|
||||
data: {
|
||||
title: this.translateService.instant('group.selectTargetGroup')
|
||||
}
|
||||
});
|
||||
|
||||
if (!!result && !!result.choice && result.choice) {
|
||||
if (!!result.group) {
|
||||
const oldGroup: GroupDetailData = result.group;
|
||||
const trgtUserSeq: number[] = [];
|
||||
result.group.userSeqs.map(seq => trgtUserSeq.push(seq));
|
||||
this.selectedUserList
|
||||
.filter(v => result.group.userSeqs.indexOf(v.seq) < 0)
|
||||
.forEach(user => {
|
||||
trgtUserSeq.push(user.seq);
|
||||
});
|
||||
|
||||
this.store.dispatch(
|
||||
SyncStore.updateGroupMember({
|
||||
oldGroup,
|
||||
trgtUserSeq
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
onClickChatOpen() {
|
||||
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
|
||||
const seq: number[] = [];
|
||||
this.selectedUserList.map(user => seq.push(user.seq));
|
||||
this.store.dispatch(ChatStore.openRoom({ userSeqList: seq }));
|
||||
}
|
||||
}
|
||||
onClickConference() {
|
||||
const targetUserSeqs = this.selectedUserList.map(userInfo => userInfo.seq);
|
||||
this.createConference.emit(targetUserSeqs);
|
||||
}
|
||||
|
||||
onClickOpenProfile(userSeq: number) {
|
||||
this.openProfile.emit(userSeq);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
[selectedChat]="this.selectedChat$ | async"
|
||||
(openProfile)="onClickOpenProfile($event)"
|
||||
(closeRightDrawer)="onCloseRightDrawer()"
|
||||
(createConference)="conferenceCreate($event)"
|
||||
>
|
||||
</app-layout-messenger-main-contents>
|
||||
<button
|
||||
|
|
|
@ -138,8 +138,9 @@
|
|||
<td mat-cell *matCellDef="let element">
|
||||
<mat-checkbox
|
||||
#checkbox
|
||||
[checked]="getCheckedAllUser()"
|
||||
(change)="onCheckAllUser(checkbox.checked)"
|
||||
*ngIf="loginRes.userSeq !== element.seq"
|
||||
[checked]="getCheckedUser(element)"
|
||||
(change)="onToggleUser(checkbox.checked, element)"
|
||||
(click)="$event.stopPropagation()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
import {
|
||||
Component,
|
||||
OnInit,
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter,
|
||||
ChangeDetectorRef
|
||||
} from '@angular/core';
|
||||
import { NGXLogger } from 'ngx-logger';
|
||||
import { UserInfoSS } from '@ucap-webmessenger/protocol-query';
|
||||
import { PresenceType, StatusCode } from '@ucap-webmessenger/core';
|
||||
|
@ -7,6 +14,7 @@ import {
|
|||
StatusBulkInfo
|
||||
} from '@ucap-webmessenger/protocol-status';
|
||||
import { Sort } from '@angular/material/sort';
|
||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||
|
||||
@Component({
|
||||
selector: 'ucap-organization-detail-table',
|
||||
|
@ -14,12 +22,13 @@ import { Sort } from '@angular/material/sort';
|
|||
styleUrls: ['./detail-table.component.scss']
|
||||
})
|
||||
export class DetailTableComponent implements OnInit {
|
||||
@Input('selectedDepartmentUserInfoList')
|
||||
@Input('departmentUserInfoList')
|
||||
set userInfoListIn(userInfo: UserInfoSS[]) {
|
||||
this.selectedDepartmentUserInfoList = userInfo;
|
||||
this.departmentUserInfoList = userInfo;
|
||||
this.sortedData = userInfo;
|
||||
}
|
||||
|
||||
@Input()
|
||||
loginRes: LoginResponse;
|
||||
@Input()
|
||||
presence: StatusBulkInfo[];
|
||||
@Input()
|
||||
|
@ -30,19 +39,14 @@ export class DetailTableComponent implements OnInit {
|
|||
@Output()
|
||||
openProfile = new EventEmitter<number>();
|
||||
@Output()
|
||||
checkUser = new EventEmitter<{
|
||||
isChecked: boolean;
|
||||
userInfo: UserInfoSS;
|
||||
}>();
|
||||
@Output()
|
||||
toggleUser = new EventEmitter<UserInfoSS>();
|
||||
@Output()
|
||||
checkAllUser = new EventEmitter<{
|
||||
toggleAllUser = new EventEmitter<{
|
||||
isChecked: boolean;
|
||||
userInfos: UserInfoSS[];
|
||||
}>();
|
||||
@Output()
|
||||
toggleUser = new EventEmitter<UserInfoSS>();
|
||||
|
||||
selectedDepartmentUserInfoList: UserInfoSS[];
|
||||
departmentUserInfoList: UserInfoSS[];
|
||||
sortedData: UserInfoSS[] = [];
|
||||
|
||||
PresenceType = PresenceType;
|
||||
|
@ -55,7 +59,10 @@ export class DetailTableComponent implements OnInit {
|
|||
'checkable'
|
||||
];
|
||||
|
||||
constructor(private logger: NGXLogger) {}
|
||||
constructor(
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private logger: NGXLogger
|
||||
) {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
|
@ -158,7 +165,7 @@ export class DetailTableComponent implements OnInit {
|
|||
}
|
||||
|
||||
sortData(sort: Sort) {
|
||||
const data = this.selectedDepartmentUserInfoList.slice();
|
||||
const data = this.departmentUserInfoList.slice();
|
||||
if (!sort.active || sort.direction === '') {
|
||||
this.sortedData = data;
|
||||
return;
|
||||
|
@ -196,43 +203,61 @@ export class DetailTableComponent implements OnInit {
|
|||
|
||||
/** 전체 체크여부 */
|
||||
getCheckedAllUser() {
|
||||
// if (!this.loginRes) {
|
||||
// return false;
|
||||
// }
|
||||
// const compareList: UserInfoSS[] = this.isShowSearch
|
||||
// ? this.searchUserInfos
|
||||
// : this.selectedDepartmentUserInfoList;
|
||||
// if (
|
||||
// !compareList ||
|
||||
// compareList.length === 0 ||
|
||||
// compareList
|
||||
// .filter(item => item.seq !== this.loginRes.userSeq)
|
||||
// .filter(
|
||||
// item =>
|
||||
// !(
|
||||
// this.selectedUserList.filter(user => user.seq === item.seq)
|
||||
// .length > 0
|
||||
// )
|
||||
// ).length > 0
|
||||
// ) {
|
||||
// return false;
|
||||
// } else {
|
||||
// return true;
|
||||
// }
|
||||
if (!this.loginRes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const compareList: UserInfoSS[] = this.departmentUserInfoList;
|
||||
if (
|
||||
!compareList ||
|
||||
compareList.length === 0 ||
|
||||
compareList
|
||||
.filter(item => item.seq !== this.loginRes.userSeq)
|
||||
.filter(
|
||||
item =>
|
||||
!(
|
||||
this.selectedUserList.filter(user => user.seq === item.seq)
|
||||
.length > 0
|
||||
)
|
||||
).length > 0
|
||||
) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/** 전체선택 이벤트 */
|
||||
onCheckAllUser(value: boolean) {
|
||||
// if (!this.loginRes) {
|
||||
// return false;
|
||||
// }
|
||||
// this.checkAllUser.emit({
|
||||
// isChecked: value,
|
||||
// userInfos: (this.isShowSearch
|
||||
// ? this.searchUserInfos
|
||||
// : this.selectedDepartmentUserInfoList
|
||||
// ).filter(user => user.seq !== this.loginRes.userSeq)
|
||||
// });
|
||||
// this.changeDetectorRef.detectChanges();
|
||||
if (!this.loginRes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.toggleAllUser.emit({
|
||||
isChecked: value,
|
||||
userInfos: this.departmentUserInfoList.filter(
|
||||
user => user.seq !== this.loginRes.userSeq
|
||||
)
|
||||
});
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
/** 개별 체크여부 */
|
||||
getCheckedUser(userInfo: UserInfoSS) {
|
||||
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
|
||||
return (
|
||||
this.selectedUserList.filter(item => item.seq === userInfo.seq).length >
|
||||
0
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/** 개별선택(토글) 이벤트 */
|
||||
onToggleUser(isChecked: boolean, userInfo: UserInfoSS) {
|
||||
console.log(isChecked, userInfo);
|
||||
|
||||
if (!this.loginRes || userInfo.seq === this.loginRes.userSeq) {
|
||||
return;
|
||||
}
|
||||
this.toggleUser.emit(userInfo);
|
||||
}
|
||||
|
||||
onClickOpenProfile(event: MouseEvent, userSeq: number) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user