diff --git a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.html b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.html
index 407640fb..42541ded 100644
--- a/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.html
+++ b/projects/ucap-webmessenger-app/src/app/layouts/messenger/components/main-contents/organization.component.html
@@ -31,9 +31,113 @@
-
+
+ {{ 'search.fieldCompany' | translate }}
+
+
+ {{ fcCompany.value ? fcCompany.value[0] : '' }}
+ 1"
+ class="example-additional-selection"
+ >
+ (+{{ fcCompany.value.length - 1 }}
+ {{ fcCompany.value?.length === 2 ? 'other' : 'others' }})
+
+
+ {{ option }}
+
+
+
+ {{ 'search.fieldGrade' | translate }}
+
+
+ {{ fcGrade.value ? fcGrade.value[0] : '' }}
+ 1"
+ class="example-additional-selection"
+ >
+ (+{{ fcGrade.value.length - 1 }}
+ {{ fcGrade.value?.length === 2 ? 'other' : 'others' }})
+
+
+ {{ option }}
+
+
+
+ {{ 'search.fieldWorkPlace' | translate }}
+
+
+ {{ fcWorkPlace.value ? fcWorkPlace.value[0] : '' }}
+ 1"
+ class="example-additional-selection"
+ >
+ (+{{ fcWorkPlace.value.length - 1 }}
+ {{ fcWorkPlace.value?.length === 2 ? 'other' : 'others' }})
+
+
+ {{ option }}
+
+
+
+ {{ 'presence.label' | translate }}
+
+
+ {{ setFilterOptionSelectedTextPresence() }}
+ 1"
+ class="example-additional-selection"
+ >
+ (+{{ fcPresence.value.length - 1 }}
+ {{ fcPresence.value?.length === 2 ? 'other' : 'others' }})
+
+
+ {{
+ 'presence.online' | translate
+ }}
+ {{
+ 'presence.away' | translate
+ }}
+ {{
+ 'presence.statusMessage1' | translate
+ }}
+ {{
+ 'presence.offline' | translate
+ }}
+
+
@@ -50,7 +154,7 @@
();
+ @ViewChild('filterCompany', { static: false })
+ filterCompany: MatSelect;
+ filterCompanyOption: string[] = [];
+ fcCompany = new FormControl();
+ @ViewChild('filterGrade', { static: false })
+ filterGrade: MatSelect;
+ filterGradeOption: string[] = [];
+ filterGradeOptionSet: {
+ value: string[];
+ valueEn: string[];
+ valueCn: string[];
+ } = {
+ value: [],
+ valueEn: [],
+ valueCn: []
+ };
+ fcGrade = new FormControl();
+ @ViewChild('filterWorkPlace', { static: false })
+ filterWorkPlace: MatSelect;
+ filterWorkPlaceOption: string[] = [];
+ fcWorkPlace = new FormControl();
+ @ViewChild('filterPresence', { static: false })
+ filterPresence: MatSelect;
+ fcPresence = new FormControl();
+
loginRes: LoginResponse;
loginResSubscription: Subscription;
sessionVerinfo: VersionInfo2Response;
authInfo: AuthResponse;
+ ucapLangChangeSubscription: Subscription;
+ ucapCurrentLocale: string;
isSearch: boolean;
isSearchSubscription: Subscription;
@@ -62,25 +94,32 @@ export class OrganizationComponent implements OnInit, OnDestroy {
searchDepartmentUserInfoListSubscription: Subscription;
departmentUserInfoList: UserInfoSS[] = [];
+ originDepartmentUserInfoList: UserInfoSS[] = [];
selectedUserList: UserInfoSS[] = []; // selected user in departmentUserList detail
profileImageRoot: string;
- presence$: Observable;
+ presenceSubscription: Subscription;
+ presenceSubject = new BehaviorSubject(undefined);
PresenceType = PresenceType;
+ StatusCode = StatusCode;
constructor(
private store: Store,
private sessionStorageService: SessionStorageService,
private dialogService: DialogService,
private translateService: TranslateService,
+ private ucapTranslateService: UCapTranslateService,
private changeDetectorRef: ChangeDetectorRef,
private logger: NGXLogger
) {
this.sessionVerinfo = this.sessionStorageService.get(
KEY_VER_INFO
);
+
this.authInfo = this.sessionStorageService.get(KEY_AUTH_INFO);
+
+ this.ucapCurrentLocale = this.ucapTranslateService.currentLang;
}
ngOnInit() {
@@ -93,6 +132,13 @@ export class OrganizationComponent implements OnInit, OnDestroy {
)
.subscribe();
+ this.ucapLangChangeSubscription = this.ucapTranslateService.changedLang.subscribe(
+ (event: LangChangeEvent) => {
+ this.ucapCurrentLocale = event.lang;
+ this.setFilterOptionsLang();
+ }
+ );
+
this.isSearchSubscription = this.store
.pipe(select(AppStore.MessengerSelector.QuerySelector.isSearch))
.subscribe(isSearch => {
@@ -116,6 +162,12 @@ export class OrganizationComponent implements OnInit, OnDestroy {
.subscribe(list => {
if (!this.isSearch) {
this.departmentUserInfoList = list;
+ this.originDepartmentUserInfoList = list;
+
+ // filter option add
+ if (!!list && list.length > 0) {
+ this.setFilterOptions(list);
+ }
}
});
@@ -128,12 +180,24 @@ export class OrganizationComponent implements OnInit, OnDestroy {
.subscribe(list => {
if (!!this.isSearch) {
this.departmentUserInfoList = list;
+ this.originDepartmentUserInfoList = list;
+
+ // filter option add
+ if (!!list && list.length > 0) {
+ this.setFilterOptions(list);
+ }
}
});
- this.presence$ = this.store.pipe(
- select(AppStore.MessengerSelector.StatusSelector.selectAllStatusBulkInfo)
- );
+ this.presenceSubscription = this.store
+ .pipe(
+ select(
+ AppStore.MessengerSelector.StatusSelector.selectAllStatusBulkInfo
+ )
+ )
+ .subscribe(presence => {
+ this.presenceSubject.next(presence);
+ });
this.profileImageRoot = this.sessionVerinfo.profileRoot;
}
@@ -142,6 +206,9 @@ export class OrganizationComponent implements OnInit, OnDestroy {
if (!!this.loginResSubscription) {
this.loginResSubscription.unsubscribe();
}
+ if (!!this.ucapLangChangeSubscription) {
+ this.ucapLangChangeSubscription.unsubscribe();
+ }
if (!!this.isSearchSubscription) {
this.isSearchSubscription.unsubscribe();
}
@@ -151,6 +218,9 @@ export class OrganizationComponent implements OnInit, OnDestroy {
if (!!this.searchDepartmentUserInfoListSubscription) {
this.searchDepartmentUserInfoListSubscription.unsubscribe();
}
+ if (!!this.presenceSubscription) {
+ this.presenceSubscription.unsubscribe();
+ }
}
/** Selected User Handling */
@@ -251,8 +321,249 @@ export class OrganizationComponent implements OnInit, OnDestroy {
const targetUserSeqs = this.selectedUserList.map(userInfo => userInfo.seq);
this.createConference.emit(targetUserSeqs);
}
-
onClickOpenProfile(userSeq: number) {
this.openProfile.emit(userSeq);
}
+
+ /** Handling Filters */
+ setFilterOptions(list: UserInfoSS[]) {
+ // option set
+ this.filterCompanyOption = [];
+ this.filterGradeOption = [];
+ this.filterGradeOptionSet = {
+ value: [],
+ valueEn: [],
+ valueCn: []
+ };
+ this.filterWorkPlaceOption = [];
+
+ list.forEach(info => {
+ if (!!info.companyName) {
+ this.filterCompanyOption.push(info.companyName);
+ }
+
+ if (!!info.grade) {
+ this.filterGradeOptionSet.value.push(info.grade);
+ }
+ if (!!info.gradeEn) {
+ this.filterGradeOptionSet.valueEn.push(info.gradeEn);
+ }
+ if (!!info.gradeCn) {
+ this.filterGradeOptionSet.valueCn.push(info.gradeCn);
+ }
+ if (!!info.workplace) {
+ this.filterWorkPlaceOption.push(info.workplace);
+ }
+ });
+ // remove duplication.
+ if (!!this.filterCompanyOption && this.filterCompanyOption.length > 0) {
+ this.filterCompanyOption = this.filterCompanyOption.reduce(
+ (unique, item) => (unique.includes(item) ? unique : [...unique, item]),
+ []
+ );
+ }
+ if (
+ !!this.filterGradeOptionSet &&
+ this.filterGradeOptionSet.value &&
+ this.filterGradeOptionSet.value.length > 0
+ ) {
+ this.filterGradeOptionSet.value = this.filterGradeOptionSet.value.reduce(
+ (unique, item) => (unique.includes(item) ? unique : [...unique, item]),
+ []
+ );
+ }
+ if (
+ !!this.filterGradeOptionSet &&
+ this.filterGradeOptionSet.valueEn &&
+ this.filterGradeOptionSet.valueEn.length > 0
+ ) {
+ this.filterGradeOptionSet.valueEn = this.filterGradeOptionSet.valueEn.reduce(
+ (unique, item) => (unique.includes(item) ? unique : [...unique, item]),
+ []
+ );
+ }
+ if (
+ !!this.filterGradeOptionSet &&
+ this.filterGradeOptionSet.valueCn &&
+ this.filterGradeOptionSet.valueCn.length > 0
+ ) {
+ this.filterGradeOptionSet.valueCn = this.filterGradeOptionSet.valueCn.reduce(
+ (unique, item) => (unique.includes(item) ? unique : [...unique, item]),
+ []
+ );
+ }
+ if (!!this.filterWorkPlaceOption && this.filterWorkPlaceOption.length > 0) {
+ this.filterWorkPlaceOption = this.filterWorkPlaceOption.reduce(
+ (unique, item) => (unique.includes(item) ? unique : [...unique, item]),
+ []
+ );
+ }
+
+ this.setFilterOptionsLang();
+ }
+ setFilterOptionsLang() {
+ const ucapLang = this.ucapCurrentLocale;
+ switch (ucapLang) {
+ case 'en':
+ this.filterGradeOption =
+ !!this.filterGradeOptionSet.valueEn &&
+ this.filterGradeOptionSet.valueEn.length > 0
+ ? this.filterGradeOptionSet.valueEn.slice()
+ : [];
+ break;
+ case 'cn':
+ this.filterGradeOption =
+ !!this.filterGradeOptionSet.valueCn &&
+ this.filterGradeOptionSet.valueCn.length > 0
+ ? this.filterGradeOptionSet.valueCn.slice()
+ : [];
+ break;
+ default:
+ // ko
+ this.filterGradeOption =
+ !!this.filterGradeOptionSet.value &&
+ this.filterGradeOptionSet.value.length > 0
+ ? this.filterGradeOptionSet.value.slice()
+ : [];
+ this.filterGradeOption = this.filterGradeOptionSet.value.slice();
+ }
+ }
+ setFilterOptionSelectedTextPresence() {
+ let firstPresence = '';
+ if (!this.filterPresence) {
+ return firstPresence;
+ }
+ const presences = this.filterPresence.selected as MatOption[];
+ if (!!presences && presences.length > 0) {
+ firstPresence = presences[0].value;
+ }
+
+ switch (firstPresence) {
+ case StatusCode.OnLine:
+ firstPresence = this.translateService.instant('presence.online');
+ break;
+ case StatusCode.Away:
+ firstPresence = this.translateService.instant('presence.away');
+ break;
+ case StatusCode.Busy:
+ firstPresence = this.translateService.instant(
+ 'presence.statusMessage1'
+ );
+ break;
+ case StatusCode.Offline:
+ firstPresence = this.translateService.instant('presence.offline');
+ break;
+ }
+ return firstPresence;
+ }
+ onOpenedChange(isOpened: boolean) {
+ // only close action.
+ if (!isOpened) {
+ this.filteredDeptUserList();
+ }
+ }
+ filteredDeptUserList() {
+ const companies = this.filterCompany.selected as MatOption[];
+ const grades = this.filterGrade.selected as MatOption[];
+ const workplaces = this.filterWorkPlace.selected as MatOption[];
+ const presences = this.filterPresence.selected as MatOption[];
+
+ let isMulti = false;
+ if (!!companies && companies.length > 0) {
+ isMulti = true;
+ const data = !!isMulti
+ ? this.originDepartmentUserInfoList
+ : this.departmentUserInfoList;
+
+ this.departmentUserInfoList = data.filter(userInfo => {
+ if (
+ companies
+ .map(option => option.value)
+ .some(opt => opt === userInfo.companyName)
+ ) {
+ return true;
+ }
+ return false;
+ });
+ }
+ if (!!grades && grades.length > 0) {
+ isMulti = true;
+ const data = !!isMulti
+ ? this.originDepartmentUserInfoList
+ : this.departmentUserInfoList;
+
+ this.departmentUserInfoList = data.filter(userInfo => {
+ if (
+ grades
+ .map(option => option.value)
+ .some(opt => {
+ let trgtGrade = userInfo.grade;
+
+ if (this.ucapCurrentLocale === 'en') {
+ trgtGrade = userInfo.gradeEn;
+ } else if (this.ucapCurrentLocale === 'cn') {
+ trgtGrade = userInfo.gradeCn;
+ }
+
+ return opt === trgtGrade;
+ })
+ ) {
+ return true;
+ }
+ return false;
+ });
+ }
+ if (!!workplaces && workplaces.length > 0) {
+ isMulti = true;
+ const data = !!isMulti
+ ? this.originDepartmentUserInfoList
+ : this.departmentUserInfoList;
+
+ this.departmentUserInfoList = data.filter(userInfo => {
+ if (
+ workplaces
+ .map(option => option.value)
+ .some(opt => opt === userInfo.workplace)
+ ) {
+ return true;
+ }
+ return false;
+ });
+ }
+ if (!!presences && presences.length > 0) {
+ isMulti = true;
+ const data = !!isMulti
+ ? this.originDepartmentUserInfoList
+ : this.departmentUserInfoList;
+
+ this.departmentUserInfoList = data.filter(userInfo => {
+ const userPresences = this.presenceSubject.value.filter(
+ presence => presence.userSeq === userInfo.seq
+ );
+ let userPresence = StatusCode.Offline;
+
+ if (!!userPresences && userPresences.length > 0) {
+ userPresence = userPresences[0].pcStatus;
+ }
+
+ if (
+ presences
+ .map(option => option.value)
+ .some(opt => {
+ return opt === userPresence;
+ })
+ ) {
+ return true;
+ }
+ return false;
+ });
+ }
+
+ if (!isMulti) {
+ this.departmentUserInfoList = this.originDepartmentUserInfoList.slice();
+ }
+
+ // // reset filterOption by data filtered.
+ // this.setFilterOptions(this.departmentUserInfoList);
+ }
}
diff --git a/projects/ucap-webmessenger-app/src/app/store/messenger/room/reducers.ts b/projects/ucap-webmessenger-app/src/app/store/messenger/room/reducers.ts
index bba3bec5..b9d15f7c 100644
--- a/projects/ucap-webmessenger-app/src/app/store/messenger/room/reducers.ts
+++ b/projects/ucap-webmessenger-app/src/app/store/messenger/room/reducers.ts
@@ -72,6 +72,10 @@ export const reducer = createReducer(
on(updateSuccess, (state, action) => {
const curRoomInfo = state.roomInfo;
+ if (!curRoomInfo) {
+ return { ...state };
+ }
+
let roomName = curRoomInfo.roomName;
let receiveAlarm = curRoomInfo.receiveAlarm;
diff --git a/projects/ucap-webmessenger-app/src/assets/i18n/en.json b/projects/ucap-webmessenger-app/src/assets/i18n/en.json
index 54728b02..f7169da3 100644
--- a/projects/ucap-webmessenger-app/src/assets/i18n/en.json
+++ b/projects/ucap-webmessenger-app/src/assets/i18n/en.json
@@ -142,6 +142,7 @@
}
},
"presence": {
+ "label": "Status",
"settingOfAwayTime": "Setting of away time",
"offline": "Offline",
"online": "Online",
diff --git a/projects/ucap-webmessenger-app/src/assets/i18n/ko.json b/projects/ucap-webmessenger-app/src/assets/i18n/ko.json
index 44f1bff8..8d660134 100644
--- a/projects/ucap-webmessenger-app/src/assets/i18n/ko.json
+++ b/projects/ucap-webmessenger-app/src/assets/i18n/ko.json
@@ -142,6 +142,7 @@
}
},
"presence": {
+ "label": "상태",
"settingOfAwayTime": "부재 중 시간 설정",
"offline": "오프라인",
"online": "온라인",
@@ -364,16 +365,16 @@
}
},
"conference": {
- "detailView": "상세 보기",
- "videoConferenceTypeNow": "[화상회의] 개설",
- "videoConferenceTypeNew": "[화상회의] 예약",
- "videoConferenceTypeUpdate": "[화상회의] 수정",
- "videoConferenceTypeDelete": "[화상회의] 삭제",
- "videoConferenceRegister": "개설자",
- "videoConferenceAttendee": "참여자",
- "videoConferenceDate": "날짜",
- "videoConferenceRoom": "회의실",
- "videoConferenceEnjoy": "참석하기"
+ "detailView": "상세 보기",
+ "videoConferenceTypeNow": "[화상회의] 개설",
+ "videoConferenceTypeNew": "[화상회의] 예약",
+ "videoConferenceTypeUpdate": "[화상회의] 수정",
+ "videoConferenceTypeDelete": "[화상회의] 삭제",
+ "videoConferenceRegister": "개설자",
+ "videoConferenceAttendee": "참여자",
+ "videoConferenceDate": "날짜",
+ "videoConferenceRoom": "회의실",
+ "videoConferenceEnjoy": "참석하기"
},
"update": {
"label": "업데이트"
diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.html b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.html
index 1bd36d22..e5771efe 100644
--- a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.html
+++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.html
@@ -60,14 +60,14 @@
{{ getWorkstatusInfo(element, 'text') }}
- {{ element.name }}
+ {{ element | ucapTranslate: 'name' }}
- {{ element.grade }}
+ {{ element | ucapTranslate: 'grade' }}
- {{ element.deptName }}
+ {{ element | ucapTranslate: 'deptName' }}
diff --git a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.ts b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.ts
index 1b2a248d..2b101df2 100644
--- a/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.ts
+++ b/projects/ucap-webmessenger-ui-organization/src/lib/components/detail-table.component.ts
@@ -4,7 +4,8 @@ import {
Input,
Output,
EventEmitter,
- ChangeDetectorRef
+ ChangeDetectorRef,
+ OnDestroy
} from '@angular/core';
import { NGXLogger } from 'ngx-logger';
import { UserInfoSS } from '@ucap-webmessenger/protocol-query';
@@ -15,13 +16,14 @@ import {
} from '@ucap-webmessenger/protocol-status';
import { Sort } from '@angular/material/sort';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
+import { Observable, Subscription } from 'rxjs';
@Component({
selector: 'ucap-organization-detail-table',
templateUrl: './detail-table.component.html',
styleUrls: ['./detail-table.component.scss']
})
-export class DetailTableComponent implements OnInit {
+export class DetailTableComponent implements OnInit, OnDestroy {
@Input('departmentUserInfoList')
set userInfoListIn(userInfo: UserInfoSS[]) {
this.departmentUserInfoList = userInfo;
@@ -30,7 +32,7 @@ export class DetailTableComponent implements OnInit {
@Input()
loginRes: LoginResponse;
@Input()
- presence: StatusBulkInfo[];
+ presence$: Observable
;
@Input()
profileImageRoot: string;
@Input()
@@ -46,6 +48,9 @@ export class DetailTableComponent implements OnInit {
@Output()
toggleUser = new EventEmitter();
+ presenceSubscription: Subscription;
+ presence: StatusBulkInfo[];
+
departmentUserInfoList: UserInfoSS[];
sortedData: UserInfoSS[] = [];
@@ -64,7 +69,17 @@ export class DetailTableComponent implements OnInit {
private logger: NGXLogger
) {}
- ngOnInit() {}
+ ngOnInit() {
+ this.presenceSubscription = this.presence$.subscribe(presence => {
+ this.presence = presence;
+ });
+ }
+
+ ngOnDestroy(): void {
+ if (!!this.presenceSubscription) {
+ this.presenceSubscription.unsubscribe();
+ }
+ }
getPresence(userInfo: UserInfoSS, type: PresenceType): string {
const presences = this.presence.filter(p => p.userSeq === userInfo.seq);