This commit is contained in:
Richard Park 2020-01-06 17:06:41 +09:00
commit 1d7cfbb9e5
11 changed files with 276 additions and 8 deletions

View File

@ -50,7 +50,7 @@ export class AppAutoLoginGuard implements CanActivate {
if ( if (
!!appUserInfo && !!appUserInfo &&
appUserInfo.settings.general.autoLogin && appUserInfo.settings.general.autoLogin &&
!personLogout.personLogout !(!!personLogout && !!personLogout.personLogout)
) { ) {
this.store.dispatch( this.store.dispatch(
AuthenticationStore.webLogin({ AuthenticationStore.webLogin({

View File

@ -186,6 +186,7 @@
(sendCall)="onClickSendClickToCall($event)" (sendCall)="onClickSendClickToCall($event)"
(sendSms)="onClickSendSms($event)" (sendSms)="onClickSendSms($event)"
(toggleUser)="onToggleUser($event)" (toggleUser)="onToggleUser($event)"
(resetSelectedUserList)="onResetSelectedUserList($event)"
class="organization-side" class="organization-side"
></app-layout-chat-left-sidenav-organization> ></app-layout-chat-left-sidenav-organization>
</div> </div>

View File

@ -403,6 +403,11 @@ export class LeftSideComponent implements OnInit, OnDestroy {
); );
} }
} }
onResetSelectedUserList(
selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]
) {
this.selectedUserList = selectedUserList;
}
/** FAB */ /** FAB */
onClickFab(params: { btn: any }) { onClickFab(params: { btn: any }) {

View File

@ -41,22 +41,27 @@ import {
} from '@app/types'; } from '@app/types';
import { take, map, tap, delay, catchError } from 'rxjs/operators'; import { take, map, tap, delay, catchError } from 'rxjs/operators';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import {
SelectGroupDialogComponent,
SelectGroupDialogData,
SelectGroupDialogResult
} from '../../dialogs/group/select-group.dialog.component';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication'; import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { Company } from '@ucap-webmessenger/api-external'; import { Company } from '@ucap-webmessenger/api-external';
import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar'; import { PerfectScrollbarDirective } from 'ngx-perfect-scrollbar';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { MatMenuTrigger } from '@angular/material'; import { MatMenuTrigger } from '@angular/material';
import { TranslateService } from '@ngx-translate/core';
import { import {
MessageWriteDialogComponent, MessageWriteDialogComponent,
MessageWriteDialogResult, MessageWriteDialogResult,
MessageWriteDialogData MessageWriteDialogData
} from '../../dialogs/message/message-write.dialog.component'; } from '../../dialogs/message/message-write.dialog.component';
import { TranslateService } from '@ngx-translate/core'; import {
SelectGroupDialogComponent,
SelectGroupDialogResult,
SelectGroupDialogData
} from '../../dialogs/group/select-group.dialog.component';
import {
SelectedUserListDialogComponent,
SelectedUserListDialogResult,
SelectedUserListDialogData
} from '../../dialogs/organization/selected-user-list.dialog.component';
@Component({ @Component({
selector: 'app-layout-chat-left-sidenav-organization', selector: 'app-layout-chat-left-sidenav-organization',
@ -99,6 +104,10 @@ export class OrganizationComponent
userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]; userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[];
}>(); }>();
@Output() @Output()
resetSelectedUserList = new EventEmitter<
(UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[]
>();
@Output()
openProfile = new EventEmitter<{ userSeq: number }>(); openProfile = new EventEmitter<{ userSeq: number }>();
@Output() @Output()
sendCall = new EventEmitter<string>(); sendCall = new EventEmitter<string>();
@ -411,8 +420,25 @@ export class OrganizationComponent
this.sendCall.emit(calleeNumber); this.sendCall.emit(calleeNumber);
} }
onClickShowSelectedUserList() { async onClickShowSelectedUserList() {
this.logger.debug('onClickShowSelectedUserList', this.selectedUserList); this.logger.debug('onClickShowSelectedUserList', this.selectedUserList);
const result = await this.dialogService.open<
SelectedUserListDialogComponent,
SelectedUserListDialogData,
SelectedUserListDialogResult
>(SelectedUserListDialogComponent, {
data: {
title: '선택된 유저',
selectedUserList: this.selectedUserList
}
});
if (!!result && !!result.choice && result.choice) {
if (!!result.selectedUserList) {
this.resetSelectedUserList.emit(result.selectedUserList);
}
}
} }
async onClickAddGroup() { async onClickAddGroup() {

View File

@ -3,6 +3,7 @@ import { DIALOGS as CHAT_DIALOGS } from './chat';
import { DIALOGS as GROUP_DIALOGS } from './group'; import { DIALOGS as GROUP_DIALOGS } from './group';
import { DIALOGS as MESSAGE_DIALOGS } from './message'; import { DIALOGS as MESSAGE_DIALOGS } from './message';
import { DIALOGS as NOTICE_DIALOGS } from './notice'; import { DIALOGS as NOTICE_DIALOGS } from './notice';
import { DIALOGS as ORGANIZATION_DIALOGS } from './organization';
import { DIALOGS as PROFILE_DIALOGS } from './profile'; import { DIALOGS as PROFILE_DIALOGS } from './profile';
import { DIALOGS as SETTINGS_DIALOGS } from './settings'; import { DIALOGS as SETTINGS_DIALOGS } from './settings';
@ -12,6 +13,7 @@ export const DIALOGS = [
...GROUP_DIALOGS, ...GROUP_DIALOGS,
...MESSAGE_DIALOGS, ...MESSAGE_DIALOGS,
...NOTICE_DIALOGS, ...NOTICE_DIALOGS,
...ORGANIZATION_DIALOGS,
...PROFILE_DIALOGS, ...PROFILE_DIALOGS,
...SETTINGS_DIALOGS ...SETTINGS_DIALOGS
]; ];

View File

@ -0,0 +1,3 @@
import { SelectedUserListDialogComponent } from './selected-user-list.dialog.component';
export const DIALOGS = [SelectedUserListDialogComponent];

View File

@ -0,0 +1,66 @@
<mat-card class="confirm-card mat-elevation-z">
<mat-card-header>
<mat-card-title>
{{ data.title }}
<span class="count">
{{ selectedUserList.length }} / {{ data.selectedUserList.length }}
</span>
<mat-checkbox
#checkbox
labelPosition="before"
[checked]="
selectedUserList.length === data.selectedUserList.length &&
data.selectedUserList.length > 0
"
(change)="onCheckAllUser(checkbox.checked)"
(click)="$event.stopPropagation()"
>
전체선택
</mat-checkbox>
</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="item-list">
<cdk-virtual-scroll-viewport
itemSize="80"
#cvsvDeptUser
perfectScrollbar
fxFlexFill
>
<ucap-profile-user-list-item
*cdkVirtualFor="let userInfo of data.selectedUserList"
[userInfo]="userInfo"
[sessionVerinfo]="sessionVerinfo"
[selectedUserList]="selectedUserList"
[checkable]="userInfo.seq !== loginRes.userSeq"
[checkDisabled]="false"
[isChecked]="getCheckedUser(userInfo)"
(checkUser)="onCheckUser($event)"
(click)="onToggleUser(userInfo)"
(openProfile)="onClickOpenProfile($event)"
[matTooltip]="
userInfo.companyName +
' / ' +
userInfo.lineNumber +
' / ' +
userInfo.hpNumber
"
matTooltipPosition="after"
>
</ucap-profile-user-list-item>
</cdk-virtual-scroll-viewport>
</div>
</mat-card-content>
<mat-card-actions class="button-farm flex-row">
<button
mat-stroked-button
(click)="onClickChoice(false)"
class="mat-primary"
>
취소
</button>
<button mat-flat-button (click)="onClickChoice(true)" class="mat-primary">
적용
</button>
</mat-card-actions>
</mat-card>

View File

@ -0,0 +1,18 @@
::ng-deep .mat-card-header-tex {
margin: 0;
}
.confirm-card {
min-width: 500px;
.mat-card-content {
.item-list {
height: 450px;
}
}
.button-farm {
text-align: right;
.mat-primary {
margin-left: 4px;
}
}
}

View File

@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SelectedUserListDialogComponent } from './selected-user-list.dialog.component';
describe('app::layouts::messenger::SelectedUserListDialogComponent', () => {
let component: SelectedUserListDialogComponent;
let fixture: ComponentFixture<SelectedUserListDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SelectedUserListDialogComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SelectedUserListDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,120 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
import {
UserInfoSS,
UserInfoF,
UserInfoDN
} from '@ucap-webmessenger/protocol-query';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { KEY_VER_INFO, KEY_LOGIN_RES_INFO } from '@app/types';
export interface SelectedUserListDialogData {
title: string;
/** 선택된 사용자의 리스트 */
selectedUserList?: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[];
}
export interface SelectedUserListDialogResult {
choice: boolean;
selectedUserList?: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[];
}
@Component({
selector: 'app-layout-messenger-selected-user-list',
templateUrl: './selected-user-list.dialog.component.html',
styleUrls: ['./selected-user-list.dialog.component.scss']
})
export class SelectedUserListDialogComponent implements OnInit {
selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];
loginRes: LoginResponse;
sessionVerinfo: VersionInfo2Response;
constructor(
public dialogRef: MatDialogRef<
SelectedUserListDialogData,
SelectedUserListDialogResult
>,
@Inject(MAT_DIALOG_DATA) public data: SelectedUserListDialogData,
private sessionStorageService: SessionStorageService
) {
this.loginRes = this.sessionStorageService.get<LoginResponse>(
KEY_LOGIN_RES_INFO
);
this.sessionVerinfo = this.sessionStorageService.get<VersionInfo2Response>(
KEY_VER_INFO
);
}
ngOnInit(): void {
this.selectedUserList = this.data.selectedUserList;
}
/** 전체선택 이벤트 */
onCheckAllUser(value: boolean) {
if (!!value) {
this.selectedUserList = this.data.selectedUserList;
} else {
this.selectedUserList = [];
}
}
/** 리스트 checkable 할 경우 checkbox 의 isChecked 를 관장하며 리스트의 전체선택 여부를 판단한다. */
getCheckedUser(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
if (!!this.selectedUserList && this.selectedUserList.length > 0) {
return (
this.selectedUserList.filter(item => item.seq === userInfo.seq).length >
0
);
}
return false;
}
/** 리스트가 checkable 할 경우 checkbox 의 change 이벤트를 상위 컴포넌트로 전달한다. */
onCheckUser(params: {
isChecked: boolean;
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
}) {
if (params.isChecked) {
if (
params.userInfo &&
this.selectedUserList.filter(user => user.seq === params.userInfo.seq)
.length === 0
) {
this.selectedUserList = [...this.selectedUserList, params.userInfo];
}
} else {
this.selectedUserList = this.selectedUserList.filter(
user => user.seq !== params.userInfo.seq
);
}
}
onToggleUser(userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN) {
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
);
}
}
onClickOpenProfile(userSeq: number) {}
onClickChoice(choice: boolean): void {
this.dialogRef.close({
choice,
selectedUserList: this.selectedUserList
});
}
}

View File

@ -351,6 +351,9 @@
확대 확대
</button> </button>
</div> --> </div> -->
<div class="setting">
<button mat-menu-item (click)="onClickNotice()">공지사항</button>
</div>
<div class="setting"> <div class="setting">
<button mat-menu-item (click)="onClickSettings()">설정</button> <button mat-menu-item (click)="onClickSettings()">설정</button>
</div> </div>