조직도 타이틀, 검색 기능 구현.
This commit is contained in:
parent
d28b6cc171
commit
8fec0e15f2
|
@ -1,37 +1,50 @@
|
|||
<div
|
||||
class="oraganization-tab"
|
||||
*ngIf="departmentInfoList$ | async"
|
||||
>
|
||||
<div class="oraganization-tab-tree" >
|
||||
<div>
|
||||
<div class="current-head">
|
||||
<h3>조직도</h3>
|
||||
</div>
|
||||
<ucap-organization-tenant-search
|
||||
[companyList]="companyList$ | async"
|
||||
[companyCode]="companyCode"
|
||||
(keyDownEnter)="onKeyDownEnterOrganizationTenantSearch($event)"
|
||||
(cancel)="onClickCancel($event)"
|
||||
>
|
||||
</ucap-organization-tenant-search>
|
||||
</div>
|
||||
<div class="oraganization-tab" *ngIf="departmentInfoList$ | async">
|
||||
<div class="oraganization-tab-tree">
|
||||
<ucap-organization-tree
|
||||
[oraganizationList]="departmentInfoList$ | async"
|
||||
[loginRes]="loginRes"
|
||||
(selected)="onSelectedOrganization($event)"
|
||||
></ucap-organization-tree>
|
||||
</div>
|
||||
<div class="select-list ">
|
||||
<dl class="select-dept text-accent-color">
|
||||
<dt>
|
||||
<div class="select-list">
|
||||
<dl class="select-dept text-accent-color">
|
||||
<dt>
|
||||
<ng-container *ngIf="!isShowSearch">
|
||||
{{ getSelectedDepartmentName() }}
|
||||
</dt>
|
||||
<dd>
|
||||
<mat-checkbox
|
||||
#checkbox
|
||||
[checked]="getCheckedAllUser()"
|
||||
(change)="onCheckAllUser(checkbox.checked)"
|
||||
(click)="$event.stopPropagation()"
|
||||
</ng-container>
|
||||
<ng-container *ngIf="isShowSearch">
|
||||
검색결과<span class="text-accent-color"
|
||||
>({{ searchUserInfos.length }}명)</span
|
||||
>
|
||||
</mat-checkbox>
|
||||
</dd>
|
||||
</dl>
|
||||
</ng-container>
|
||||
</dt>
|
||||
<dd>
|
||||
<mat-checkbox
|
||||
#checkbox
|
||||
[checked]="getCheckedAllUser()"
|
||||
(change)="onCheckAllUser(checkbox.checked)"
|
||||
(click)="$event.stopPropagation()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</dd>
|
||||
</dl>
|
||||
<div *ngIf="selectedDepartmentProcessing">
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</div>
|
||||
<div class="search-list">
|
||||
<cdk-virtual-scroll-viewport
|
||||
itemSize="20"
|
||||
style="height: 100%;"
|
||||
>
|
||||
<div *ngIf="!isShowSearch" class="search-list">
|
||||
<cdk-virtual-scroll-viewport itemSize="20" style="height: 100%;">
|
||||
<ucap-profile-user-list-item
|
||||
*cdkVirtualFor="let userInfo of selectedDepartmentUserInfoList"
|
||||
[userInfo]="userInfo"
|
||||
|
@ -55,11 +68,25 @@
|
|||
>
|
||||
</ucap-profile-user-list-item> -->
|
||||
</div>
|
||||
<div *ngIf="isShowSearch" class="search-result">
|
||||
<cdk-virtual-scroll-viewport itemSize="20" style="height: 100%;">
|
||||
<ucap-profile-user-list-item
|
||||
*cdkVirtualFor="let userInfo of searchUserInfos"
|
||||
[userInfo]="userInfo"
|
||||
[checkable]="true"
|
||||
[sessionVerinfo]="sessionVerinfo"
|
||||
[selectedUserList]="selectedUserList"
|
||||
[isChecked]="getCheckedUser(userInfo)"
|
||||
(checkUser)="onCheckUser($event)"
|
||||
>
|
||||
</ucap-profile-user-list-item>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="!isUserSelect" class="btn-box">
|
||||
<!--선택된 후에는 disabled="true" 빼주세요. -->
|
||||
<button
|
||||
mat-stroked-button
|
||||
[disabled]="selectedUserList.length > 0 ? 'false' : 'true'"
|
||||
class="mat-primary"
|
||||
(click)="onClickShowSelectedUserList()"
|
||||
>
|
||||
|
@ -69,18 +96,29 @@
|
|||
</button>
|
||||
<ul>
|
||||
<li>
|
||||
<button mat-flat-button (click)="onClickAddGroup()" class="mat-primary">
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="selectedUserList.length > 0 ? 'false' : 'true'"
|
||||
(click)="onClickAddGroup()"
|
||||
class="mat-primary"
|
||||
>
|
||||
그룹에 추가
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button mat-flat-button (click)="onClickChatOpen()" class="mat-primary">
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="selectedUserList.length > 0 ? 'false' : 'true'"
|
||||
(click)="onClickChatOpen()"
|
||||
class="mat-primary"
|
||||
>
|
||||
대화
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
mat-flat-button
|
||||
[disabled]="selectedUserList.length > 0 ? 'false' : 'true'"
|
||||
(click)="onClickConference()"
|
||||
class="mat-primary"
|
||||
>
|
||||
|
|
|
@ -11,98 +11,134 @@
|
|||
display: -webkit-box;
|
||||
-webkit-line-clamp: $row;
|
||||
-webkit-box-orient: vertical;
|
||||
word-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
.current-head {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
height: 70px;
|
||||
background-color: #eeeeee;
|
||||
background: #f15f79;
|
||||
background: -webkit-linear-gradient(to right, #352a37, #f15f79);
|
||||
background: linear-gradient(to right, #352a37, #ef4c73);
|
||||
color: #ffffff;
|
||||
h3 {
|
||||
display: inline-flex;
|
||||
padding-left: 10px;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
.btn-box {
|
||||
height: 100%;
|
||||
margin-left: auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
svg {
|
||||
stroke: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
.search-result {
|
||||
height: calc(100% - 40px);
|
||||
overflow: auto;
|
||||
.result-num {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.oraganization-tab {
|
||||
height: 100%;
|
||||
height: calc(100% - 130px);
|
||||
flex-direction: inherit;
|
||||
display: flex;
|
||||
.oraganization-tab-tree {
|
||||
height:40%;
|
||||
height: 40%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
//팝업에 있는 조직도
|
||||
.mat-card-content{
|
||||
.mat-tab-body-content{
|
||||
.oraganization-box{
|
||||
.mat-card-content {
|
||||
.mat-tab-body-content {
|
||||
.oraganization-box {
|
||||
.oraganization-tab {
|
||||
height: 80%;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-list{
|
||||
height:60%;
|
||||
border-top:1px solid #dddddd;
|
||||
.select-dept{
|
||||
padding:0 20px;
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
display:flex;
|
||||
background-color: #f9f9f9;
|
||||
dt{
|
||||
|
||||
}
|
||||
dd{
|
||||
margin-left:auto;
|
||||
}
|
||||
}
|
||||
.search-list{
|
||||
height: calc(100% - 40px);
|
||||
overflow: auto;
|
||||
.list-item{
|
||||
height:70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn-box{
|
||||
padding:10px;
|
||||
button{
|
||||
width:100%;
|
||||
@include ellipsis(1);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-list {
|
||||
height: 60%;
|
||||
border-top: 1px solid #dddddd;
|
||||
.select-dept {
|
||||
padding: 0 20px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
display: flex;
|
||||
background-color: #f9f9f9;
|
||||
dt {
|
||||
}
|
||||
dd {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
.search-list {
|
||||
height: calc(100% - 40px);
|
||||
overflow: auto;
|
||||
.list-item {
|
||||
height: 70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dialog-org {
|
||||
.oraganization-tab {
|
||||
width: 100%;
|
||||
height:380px;
|
||||
height: 380px;
|
||||
border-bottom: 1px solid #dddddd;
|
||||
position: relative;
|
||||
.oraganization-tab-tree {
|
||||
display: inline-flex;
|
||||
width: 50%;
|
||||
height:100%;
|
||||
height: 100%;
|
||||
border-right: 1px solid #dddddd;
|
||||
overflow: auto;
|
||||
}
|
||||
|
@ -110,11 +146,11 @@
|
|||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
height:100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
.search-list {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@ import {
|
|||
OnDestroy,
|
||||
Output,
|
||||
EventEmitter,
|
||||
Input
|
||||
Input,
|
||||
} from '@angular/core';
|
||||
import { ucapAnimations, DialogService } from '@ucap-webmessenger/ui';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { Observable, Subscription, of } from 'rxjs';
|
||||
import {
|
||||
DeptInfo,
|
||||
QueryProtocolService,
|
||||
|
@ -15,7 +15,10 @@ import {
|
|||
UserInfoSS,
|
||||
DeptUserResponse,
|
||||
UserInfoF,
|
||||
UserInfoDN
|
||||
UserInfoDN,
|
||||
SSVC_TYPE_QUERY_DEPT_USER_DATA,
|
||||
SSVC_TYPE_QUERY_DEPT_USER_RES,
|
||||
DeptUserData,
|
||||
} from '@ucap-webmessenger/protocol-query';
|
||||
import { UserInfo, GroupDetailData } from '@ucap-webmessenger/protocol-sync';
|
||||
import { Store, select } from '@ngrx/store';
|
||||
|
@ -25,23 +28,25 @@ import * as AppStore from '@app/store';
|
|||
import * as QueryStore from '@app/store/messenger/query';
|
||||
import * as SyncStore from '@app/store/messenger/sync';
|
||||
import * as ChatStore from '@app/store/messenger/chat';
|
||||
import * as StatusStore from '@app/store/messenger/status';
|
||||
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
|
||||
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
|
||||
import { take, map, tap, delay } from 'rxjs/operators';
|
||||
import { take, map, tap, delay, catchError } from 'rxjs/operators';
|
||||
import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
|
||||
import { KEY_VER_INFO } from '@app/types/ver-info.type';
|
||||
import {
|
||||
SelectGroupDialogComponent,
|
||||
SelectGroupDialogData,
|
||||
SelectGroupDialogResult
|
||||
SelectGroupDialogResult,
|
||||
} from '../../dialogs/group/select-group.dialog.component';
|
||||
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
|
||||
import { Company } from '@ucap-webmessenger/api-external';
|
||||
|
||||
@Component({
|
||||
selector: 'app-layout-chat-left-sidenav-organization',
|
||||
templateUrl: './organization.component.html',
|
||||
styleUrls: ['./organization.component.scss'],
|
||||
animations: ucapAnimations
|
||||
animations: ucapAnimations,
|
||||
})
|
||||
export class OrganizationComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
|
@ -62,6 +67,9 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
userInfos: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[];
|
||||
}>();
|
||||
|
||||
companyList$: Observable<Company[]>;
|
||||
companyCode: string;
|
||||
|
||||
departmentInfoList$: Observable<DeptInfo[]>;
|
||||
selectedDepartmentUserInfoList$: Observable<UserInfoSS[]>;
|
||||
selectedDepartmentUserInfoList: UserInfoSS[] = [];
|
||||
|
@ -75,9 +83,13 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
loginRes: LoginResponse;
|
||||
sessionVerinfo: VersionInfo2Response;
|
||||
|
||||
isShowSearch = false;
|
||||
searchUserInfos: UserInfoSS[] = [];
|
||||
|
||||
constructor(
|
||||
private store: Store<any>,
|
||||
private sessionStorageService: SessionStorageService,
|
||||
private queryProtocolService: QueryProtocolService,
|
||||
private dialogService: DialogService,
|
||||
private logger: NGXLogger
|
||||
) {
|
||||
|
@ -88,6 +100,11 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.companyCode = this.loginInfo.companyCode;
|
||||
this.companyList$ = this.store.pipe(
|
||||
select(AppStore.SettingSelector.CompanySelector.companyList)
|
||||
);
|
||||
|
||||
this.departmentInfoList$ = this.store.pipe(
|
||||
select(AppStore.MessengerSelector.QuerySelector.departmentInfoList)
|
||||
);
|
||||
|
@ -133,7 +150,7 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
search: '',
|
||||
searchRange: DeptSearchType.All,
|
||||
senderCompanyCode: this.loginInfo.companyCode,
|
||||
senderEmployeeType: loginRes.userInfo.employeeType
|
||||
senderEmployeeType: loginRes.userInfo.employeeType,
|
||||
})
|
||||
);
|
||||
return loginRes;
|
||||
|
@ -155,7 +172,67 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
/** 유저검색 */
|
||||
onKeyDownEnterOrganizationTenantSearch(params: {
|
||||
companyCode: string;
|
||||
searchWord: string;
|
||||
}) {
|
||||
if (params.searchWord.trim().length > 1) {
|
||||
this.isShowSearch = true;
|
||||
this.selectedDepartmentProcessing = true;
|
||||
const searchUserInfos: UserInfoSS[] = [];
|
||||
this.queryProtocolService
|
||||
.deptUser({
|
||||
divCd: 'GRP',
|
||||
companyCode: params.companyCode,
|
||||
searchRange: DeptSearchType.All,
|
||||
search: params.searchWord,
|
||||
senderCompanyCode: params.companyCode,
|
||||
senderEmployeeType: this.loginRes.userInfo.employeeType,
|
||||
})
|
||||
.pipe(
|
||||
map(res => {
|
||||
switch (res.SSVC_TYPE) {
|
||||
case SSVC_TYPE_QUERY_DEPT_USER_DATA:
|
||||
searchUserInfos.push(...(res as DeptUserData).userInfos);
|
||||
break;
|
||||
case SSVC_TYPE_QUERY_DEPT_USER_RES:
|
||||
{
|
||||
// 검색 결과 처리.
|
||||
this.searchUserInfos = searchUserInfos;
|
||||
this.selectedDepartmentProcessing = false;
|
||||
// 검색 결과에 따른 프레즌스 조회.
|
||||
const userSeqList: number[] = [];
|
||||
this.searchUserInfos.map(user => userSeqList.push(user.seq));
|
||||
if (userSeqList.length > 0) {
|
||||
this.store.dispatch(
|
||||
StatusStore.bulkInfo({
|
||||
divCd: 'orgSrch',
|
||||
userSeqs: userSeqList,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}),
|
||||
catchError(error => {
|
||||
this.selectedDepartmentProcessing = false;
|
||||
return of(this.logger.error(error));
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
/** 검색 취소 */
|
||||
onClickCancel() {
|
||||
this.isShowSearch = false;
|
||||
this.searchUserInfos = [];
|
||||
}
|
||||
|
||||
onSelectedOrganization(deptInfo: DeptInfo) {
|
||||
this.onClickCancel();
|
||||
|
||||
this.store
|
||||
.pipe(
|
||||
take(1),
|
||||
|
@ -169,7 +246,7 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
search: '',
|
||||
searchRange: DeptSearchType.All,
|
||||
senderCompanyCode: this.loginInfo.companyCode,
|
||||
senderEmployeeType: loginRes.userInfo.employeeType
|
||||
senderEmployeeType: loginRes.userInfo.employeeType,
|
||||
})
|
||||
);
|
||||
}),
|
||||
|
@ -182,7 +259,7 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
|
||||
getSelectedDepartmentName() {
|
||||
if (!!this.selectedDepartmentProcessing) {
|
||||
return '부서조회중..';
|
||||
return '조회중..';
|
||||
}
|
||||
|
||||
if (!!this.selectedDepartmentName) {
|
||||
|
@ -194,10 +271,14 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
|
||||
/** 전체 체크여부 */
|
||||
getCheckedAllUser() {
|
||||
const compareList: UserInfoSS[] = this.isShowSearch
|
||||
? this.searchUserInfos
|
||||
: this.selectedDepartmentUserInfoList;
|
||||
|
||||
if (
|
||||
!this.selectedDepartmentUserInfoList ||
|
||||
this.selectedDepartmentUserInfoList.length === 0 ||
|
||||
this.selectedDepartmentUserInfoList.filter(
|
||||
!compareList ||
|
||||
compareList.length === 0 ||
|
||||
compareList.filter(
|
||||
item =>
|
||||
!(
|
||||
this.selectedUserList.filter(user => user.seq === item.seq).length >
|
||||
|
@ -225,7 +306,9 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
onCheckAllUser(value: boolean) {
|
||||
this.checkAllUser.emit({
|
||||
isChecked: value,
|
||||
userInfos: this.selectedDepartmentUserInfoList
|
||||
userInfos: this.isShowSearch
|
||||
? this.searchUserInfos
|
||||
: this.selectedDepartmentUserInfoList,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -251,8 +334,8 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
>(SelectGroupDialogComponent, {
|
||||
width: '600px',
|
||||
data: {
|
||||
title: 'Group Select'
|
||||
}
|
||||
title: 'Group Select',
|
||||
},
|
||||
});
|
||||
|
||||
if (!!result && !!result.choice && result.choice) {
|
||||
|
@ -269,7 +352,7 @@ export class OrganizationComponent implements OnInit, OnDestroy {
|
|||
this.store.dispatch(
|
||||
SyncStore.updateGroupMember({
|
||||
oldGroup,
|
||||
trgtUserSeq
|
||||
trgtUserSeq,
|
||||
})
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user