This commit is contained in:
병준 박 2019-10-17 16:57:46 +09:00
commit a6450fba84
10 changed files with 151 additions and 37 deletions

View File

@ -14,13 +14,8 @@
</mat-tab> </mat-tab>
<mat-tab> <mat-tab>
<ng-template mat-tab-label> <ng-template mat-tab-label>
<mat-icon <mat-icon [matBadgeHidden]="((badgeChatUnReadCount$ | async) <= 0)" [matBadge]="badgeChatUnReadCount$ | async"
matBadge="22" matBadgeDescription="확인하지 않은 메시지가 있습니다." matBadgeColor="accent" matBadgePosition="above after">chat</mat-icon>
matBadgeDescription="확인하지 않은 메시지가 있습니다."
matBadgeColor="accent"
matBadgePosition="above after"
>chat</mat-icon
>
</ng-template> </ng-template>
<app-layout-chat-left-sidenav-chat></app-layout-chat-left-sidenav-chat> <app-layout-chat-left-sidenav-chat></app-layout-chat-left-sidenav-chat>
</mat-tab> </mat-tab>

View File

@ -6,6 +6,10 @@ import {
CreateChatDialogData, CreateChatDialogData,
CreateChatDialogResult CreateChatDialogResult
} from '@app/layouts/messenger/dialogs/chat/create-chat.dialog.component'; } from '@app/layouts/messenger/dialogs/chat/create-chat.dialog.component';
import { Observable } from 'rxjs';
import { Store, select } from '@ngrx/store';
import * as AppStore from '@app/store';
@Component({ @Component({
selector: 'app-layout-messenger-left-side', selector: 'app-layout-messenger-left-side',
@ -14,12 +18,19 @@ import {
animations: ucapAnimations animations: ucapAnimations
}) })
export class LeftSideComponent implements OnInit { export class LeftSideComponent implements OnInit {
badgeChatUnReadCount$: Observable<number>;
constructor( constructor(
private store: Store<any>,
private dialogService: DialogService, private dialogService: DialogService,
private logger: NGXLogger private logger: NGXLogger
) {} ) {}
ngOnInit() {} ngOnInit() {
this.badgeChatUnReadCount$ = this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.selectChatUnreadCount)
);
}
async onClickNewChat() { async onClickNewChat() {
const result = await this.dialogService.open< const result = await this.dialogService.open<

View File

@ -9,39 +9,38 @@
<ng-template mat-tab-label> <ng-template mat-tab-label>
<mat-icon>group</mat-icon> <mat-icon>group</mat-icon>
</ng-template> </ng-template>
<ng-template matTabContent>
<ucap-organization-tenant-search [companyList]="companyList$ | async" [companyCode]="companyCode" <ucap-organization-tenant-search [companyList]="companyList$ | async" [companyCode]="companyCode"
(keyDownEnter)="onKeyDownEnterOrganizationTenantSearch($event)"></ucap-organization-tenant-search> (keyDownEnter)="onKeyDownEnterOrganizationTenantSearch($event)"></ucap-organization-tenant-search>
<ucap-group-expansion-panel #groupExpansionPanel [groupBuddyList]="groupBuddyList$ | async" <ucap-group-expansion-panel #groupExpansionPanel [groupBuddyList]="groupBuddyList$ | async"
[favoritBuddyList]="favoritBuddyList$ | async" [checkable]="true"> [favoritBuddyList]="favoritBuddyList$ | async" [checkable]="true" (checkGroup)="onCheckGroup($event)">
<ucap-profile-user-list-item *ucapGroupExpansionPanelItem="let userInfo" [userInfo]="userInfo" <ucap-profile-user-list-item *ucapGroupExpansionPanelItem="let userInfo" [userInfo]="userInfo"
[sessionVerinfo]="sessionVerinfo" [checkable]="true"> [sessionVerinfo]="sessionVerinfo" (checkUser)="onCheckUser($event)" [checkable]="true">
</ucap-profile-user-list-item> </ucap-profile-user-list-item>
</ucap-group-expansion-panel> </ucap-group-expansion-panel>
</ng-template>
</mat-tab> </mat-tab>
<mat-tab> <mat-tab>
<ng-template mat-tab-label> <ng-template mat-tab-label>
<mat-icon>device_hub</mat-icon> <mat-icon>device_hub</mat-icon>
</ng-template> </ng-template>
<ng-template matTabContent>
<app-layout-chat-left-sidenav-organization></app-layout-chat-left-sidenav-organization> <app-layout-chat-left-sidenav-organization></app-layout-chat-left-sidenav-organization>
</ng-template>
</mat-tab> </mat-tab>
<mat-tab> <mat-tab>
<ng-template mat-tab-label> <ng-template mat-tab-label>
<mat-icon>chat</mat-icon> <mat-icon>chat</mat-icon>
</ng-template> </ng-template>
<ng-template matTabContent>
<ucap-room-list-item *ngFor="let room of roomList" [loginRes]="loginRes" [roomInfo]="room" <ucap-room-list-item *ngFor="let room of roomList" [loginRes]="loginRes" [roomInfo]="room"
[roomUserInfo]="getRoomUserList(room)" [sessionVerinfo]="sessionVerinfo"> [roomUserInfo]="getRoomUserList(room)" [sessionVerinfo]="sessionVerinfo">
</ucap-room-list-item> </ucap-room-list-item>
</ng-template>
</mat-tab> </mat-tab>
</mat-tab-group> </mat-tab-group>
</div> </div>
<div fxFlex="100px"> <div fxFlex="100px">
choiced users <ul>
<li *ngFor="let userInfo of selectedUserList">
{{ userInfo.name }}
</li>
</ul>
</div> </div>
</mat-card-content> </mat-card-content>
<mat-card-actions class="button-farm flex-row"> <mat-card-actions class="button-farm flex-row">

View File

@ -20,7 +20,12 @@ import {
RoomUserDetailData, RoomUserDetailData,
RoomUserData RoomUserData
} from '@ucap-webmessenger/protocol-sync'; } from '@ucap-webmessenger/protocol-sync';
import { DeptSearchType } from '@ucap-webmessenger/protocol-query'; import {
DeptSearchType,
UserInfoSS,
UserInfoF,
UserInfoDN
} from '@ucap-webmessenger/protocol-query';
import { import {
RoomInfo, RoomInfo,
UserInfoShort, UserInfoShort,
@ -70,6 +75,9 @@ export class CreateChatDialogComponent implements OnInit, OnDestroy {
roomUserShortList: RoomUserData[]; roomUserShortList: RoomUserData[];
roomSubscription: Subscription; roomSubscription: Subscription;
// 수집 데이터
selectedUserList: (UserInfo | UserInfoSS | UserInfoF | UserInfoDN)[] = [];
ngOnInit() { ngOnInit() {
const loginInfo = this.sessionStorageService.get<LoginInfo>(KEY_LOGIN_INFO); const loginInfo = this.sessionStorageService.get<LoginInfo>(KEY_LOGIN_INFO);
this.companyCode = loginInfo.companyCode; this.companyCode = loginInfo.companyCode;
@ -189,9 +197,49 @@ export class CreateChatDialogComponent implements OnInit, OnDestroy {
); );
} }
onClickChoice(choice: boolean): void { onCheckGroup(params: {
this.dialogRef.close({ isChecked: boolean;
choice groupBuddyList: { group: GroupDetailData; buddyList: UserInfo[] };
}) {
if (params.isChecked) {
params.groupBuddyList.buddyList.forEach(item => {
if (
this.selectedUserList.filter(user => user.seq === item.seq).length ===
0
) {
this.selectedUserList.push(item);
}
}); });
} else {
this.selectedUserList = this.selectedUserList.filter(
item =>
params.groupBuddyList.buddyList.filter(del => del.seq === item.seq)
.length === 0
);
}
}
onCheckUser(params: {
isChecked: boolean;
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
}) {
if (params.isChecked) {
if (
this.selectedUserList.filter(user => user.seq === params.userInfo.seq)
.length === 0
) {
this.selectedUserList.push(params.userInfo);
}
} else {
this.selectedUserList = this.selectedUserList.filter(
item => item.seq !== params.userInfo.seq
);
}
}
onClickChoice(choice: boolean): void {
// this.dialogRef.close({
// choice
// });
} }
} }

View File

@ -68,6 +68,9 @@ export const reducer = createReducer(
} }
} }
let unReadCount = 0;
action.roomList.map(item => (unReadCount += item.noReadCnt));
return { return {
...state, ...state,
room: adapterRoom.upsertMany(action.roomList, { room: adapterRoom.upsertMany(action.roomList, {
@ -79,7 +82,8 @@ export const reducer = createReducer(
}), }),
roomUserShort: adapterRoomUserShort.upsertMany(roomUserShortList, { roomUserShort: adapterRoomUserShort.upsertMany(roomUserShortList, {
...state.roomUserShort ...state.roomUserShort
}) }),
chatUnreadCount: unReadCount
}; };
}), }),
@ -152,12 +156,26 @@ export const reducer = createReducer(
noReadCnt: action.noReadCnt noReadCnt: action.noReadCnt
}; };
let unReadCount = 0;
if (action.noReadCnt === 0) {
// tslint:disable-next-line: forin
for (const key in state.room.entities) {
if (key !== action.roomSeq) {
const value = state.room.entities[key];
unReadCount += value.noReadCnt;
}
}
} else {
unReadCount = state.chatUnreadCount + 1;
}
return { return {
...state, ...state,
room: adapterRoom.updateOne( room: adapterRoom.updateOne(
{ id: action.roomSeq, changes: roomInfo }, { id: action.roomSeq, changes: roomInfo },
{ ...state.room } { ...state.room }
) ),
chatUnreadCount: unReadCount
}; };
}), }),

View File

@ -34,6 +34,7 @@ export interface State {
room: RoomState; room: RoomState;
roomUser: RoomUserState; roomUser: RoomUserState;
roomUserShort: RoomUserShortState; roomUserShort: RoomUserShortState;
chatUnreadCount: number;
} }
export const adapterBuddy2 = createEntityAdapter<UserInfo>({ export const adapterBuddy2 = createEntityAdapter<UserInfo>({
@ -93,7 +94,8 @@ export const initialState: State = {
group2: group2InitialState, group2: group2InitialState,
room: roomInitialState, room: roomInitialState,
roomUser: roomUserInitialState, roomUser: roomUserInitialState,
roomUserShort: roomUserShortInitialState roomUserShort: roomUserShortInitialState,
chatUnreadCount: 0
}; };
const { const {
@ -189,6 +191,10 @@ export function selectors<S>(selector: Selector<any, State>) {
selectAllRoomUserShort: createSelector( selectAllRoomUserShort: createSelector(
selectRoomUserShort, selectRoomUserShort,
ngeSelectAllRoomUserShort ngeSelectAllRoomUserShort
),
selectChatUnreadCount: createSelector(
selector,
(state: State) => state.chatUnreadCount
) )
}; };
} }

View File

@ -28,7 +28,8 @@
(click)="onClickMore($event, groupBuddy.group)"> (click)="onClickMore($event, groupBuddy.group)">
<mat-icon>more_vert</mat-icon> <mat-icon>more_vert</mat-icon>
</button> </button>
<mat-checkbox *ngIf="checkable"></mat-checkbox> <mat-checkbox *ngIf="checkable" #checkbox (change)="onChangeCheck(checkbox.checked, groupBuddy)"
(click)="$event.stopPropagation()"></mat-checkbox>
</mat-panel-description> </mat-panel-description>
</mat-expansion-panel-header> </mat-expansion-panel-header>

View File

@ -37,6 +37,12 @@ export class ExpansionPanelComponent implements OnInit {
group: GroupDetailData; group: GroupDetailData;
}>(); }>();
@Output()
checkGroup = new EventEmitter<{
isChecked: boolean;
groupBuddyList: { group: GroupDetailData; buddyList: UserInfo[] };
}>();
@ContentChild(ExpansionPanelItemDirective, { @ContentChild(ExpansionPanelItemDirective, {
read: TemplateRef, read: TemplateRef,
static: true static: true
@ -60,4 +66,14 @@ export class ExpansionPanelComponent implements OnInit {
onClickMore(event: MouseEvent, group: GroupDetailData) { onClickMore(event: MouseEvent, group: GroupDetailData) {
this.more.emit({ event, group }); this.more.emit({ event, group });
} }
onChangeCheck(
value: boolean,
groupBuddyList: { group: GroupDetailData; buddyList: UserInfo[] }
) {
this.checkGroup.emit({
isChecked: value,
groupBuddyList
});
}
} }

View File

@ -40,5 +40,7 @@
</div> </div>
</dd> </dd>
</dl> </dl>
<mat-checkbox *ngIf="checkable"></mat-checkbox> <mat-checkbox *ngIf="checkable" #checkbox [checked]="isChecked" (change)="onChangeCheck(checkbox.checked, userInfo)"
(click)="$event.stopPropagation()">
</mat-checkbox>
</div> </div>

View File

@ -23,6 +23,7 @@ import { StatusCode } from '@ucap-webmessenger/core';
import { PresenceType } from '../types/presence-type.type'; import { PresenceType } from '../types/presence-type.type';
import { VersionInfo2Response } from '@ucap-webmessenger/api-public'; import { VersionInfo2Response } from '@ucap-webmessenger/api-public';
import { MatCheckboxChange, MatPseudoCheckbox } from '@angular/material';
@Component({ @Component({
selector: 'ucap-profile-user-list-item', selector: 'ucap-profile-user-list-item',
@ -41,12 +42,19 @@ export class UserListItemComponent implements OnInit, OnDestroy {
@Input() @Input()
checkable = false; checkable = false;
@Input() @Input()
isChecked = false;
@Input()
compactable = false; compactable = false;
@Input() @Input()
sessionVerinfo: VersionInfo2Response; sessionVerinfo: VersionInfo2Response;
userPresence: StatusBulkInfo | StatusInfo; @Output()
checkUser = new EventEmitter<{
isChecked: boolean;
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN;
}>();
userPresence: StatusBulkInfo | StatusInfo;
PresenceType = PresenceType; PresenceType = PresenceType;
// private profileImageRootSubscription: Subscription; // private profileImageRootSubscription: Subscription;
@ -105,4 +113,14 @@ export class UserListItemComponent implements OnInit, OnDestroy {
return rtnClass; return rtnClass;
} }
onChangeCheck(
value: boolean,
userInfo: UserInfo | UserInfoSS | UserInfoF | UserInfoDN
) {
this.checkUser.emit({
isChecked: value,
userInfo
});
}
} }