# Conflicts:
#	projects/ucap-webmessenger-app/src/app/pages/template/components/template.page.component.html
#	projects/ucap-webmessenger-ui-profile/src/lib/components/user-list-item.component.html
This commit is contained in:
김남중 2019-10-10 10:33:26 +09:00
commit f363d23242
286 changed files with 3899 additions and 1298 deletions

View File

@ -11,59 +11,59 @@ import {
FileProfileSaveResponse,
encodeFileProfileSave,
decodeFileProfileSave
} from '../models/file-profile-save';
} from '../apis/file-profile-save';
import {
FileTalkDownloadRequest,
encodeFileTalkDownload
} from '../models/file-talk-download';
} from '../apis/file-talk-download';
import {
FileTalkSaveRequest,
FileTalkSaveResponse,
encodeFileTalkSave,
decodeFileTalkSave
} from '../models/file-talk-save';
} from '../apis/file-talk-save';
import {
FileTalkShareRequest,
FileTalkShareResponse,
encodeFileTalkShare,
decodeFileTalkShare
} from '../models/file-talk-share';
} from '../apis/file-talk-share';
import {
MassTalkDownloadRequest,
MassTalkDownloadResponse,
encodeMassTalkDownload,
decodeMassTalkDownload
} from '../models/mass-talk-download';
} from '../apis/mass-talk-download';
import {
MassTalkSaveRequest,
MassTalkSaveResponse,
encodeMassTalkSave,
decodeMassTalkSave
} from '../models/mass-talk-save';
} from '../apis/mass-talk-save';
import {
TransMassTalkDownloadRequest,
TransMassTalkDownloadResponse,
encodeTransMassTalkDownload,
decodeTransMassTalkDownload
} from '../models/trans-mass-talk-download';
} from '../apis/trans-mass-talk-download';
import {
TransMassTalkSaveRequest,
TransMassTalkSaveResponse,
encodeTransMassTalkSave,
decodeTransMassTalkSave
} from '../models/trans-mass-talk-save';
} from '../apis/trans-mass-talk-save';
import {
TranslationReqRequest,
TranslationReqResponse,
encodeTranslationReq,
decodeTranslationReq
} from '../models/translation-req';
} from '../apis/translation-req';
import {
TranslationSaveRequest,
TranslationSaveResponse,
encodeTranslationSave,
decodeTranslationSave
} from '../models/translation-save';
} from '../apis/translation-save';
@Injectable({
providedIn: 'root'

View File

@ -4,16 +4,16 @@
export * from './lib/types/module-config';
export * from './lib/models/file-profile-save';
export * from './lib/models/file-talk-download';
export * from './lib/models/file-talk-save';
export * from './lib/models/file-talk-share';
export * from './lib/models/mass-talk-download';
export * from './lib/models/mass-talk-save';
export * from './lib/models/trans-mass-talk-download';
export * from './lib/models/trans-mass-talk-save';
export * from './lib/models/translation-req';
export * from './lib/models/translation-save';
export * from './lib/apis/file-profile-save';
export * from './lib/apis/file-talk-download';
export * from './lib/apis/file-talk-save';
export * from './lib/apis/file-talk-share';
export * from './lib/apis/mass-talk-download';
export * from './lib/apis/mass-talk-save';
export * from './lib/apis/trans-mass-talk-download';
export * from './lib/apis/trans-mass-talk-save';
export * from './lib/apis/translation-req';
export * from './lib/apis/translation-save';
export * from './lib/services/common-api.service';

View File

@ -5,6 +5,7 @@ import {
APIEncoder,
APIDecoder
} from '@ucap-webmessenger/api';
import { Company } from '../models/company';
export interface CompanyListRequest extends APIRequest {
userSeq?: string;
@ -14,15 +15,6 @@ export interface CompanyListRequest extends APIRequest {
companyGroupCode: string;
}
export interface Company {
companyCode?: string;
companyName?: string;
companyDomain?: string;
companyConfAuthYn?: string;
ucapUseYn?: string;
companyTimerChatAuthYn?: string;
}
export interface CompanyListResponse extends APIResponse {
companyList?: Company[];
}

View File

@ -0,0 +1,8 @@
export interface Company {
companyCode?: string;
companyName?: string;
companyDomain?: string;
companyConfAuthYn?: string;
ucapUseYn?: string;
companyTimerChatAuthYn?: string;
}

View File

@ -11,25 +11,25 @@ import {
CheckUserInfoExResponse,
encodeCheckUserInfoEx,
decodeCheckUserInfoEx
} from '../models/check-user-info-ex';
} from '../apis/check-user-info-ex';
import {
CompanyListRequest,
CompanyListResponse,
encodeCompanyList,
decodeCompanyList
} from '../models/company-list';
} from '../apis/company-list';
import {
TokenUpdateRequest,
TokenUpdateResponse,
encodeTokenUpdate,
decodeTokenUpdate
} from '../models/token-update';
} from '../apis/token-update';
import {
UrlInfoResponse,
UrlInfoRequest,
encodeUrlInfo,
decodeUrlInfo
} from '../models/url-info';
} from '../apis/url-info';
@Injectable({
providedIn: 'root'

View File

@ -4,10 +4,12 @@
export * from './lib/types/module-config';
export * from './lib/models/check-user-info-ex';
export * from './lib/models/company-list';
export * from './lib/models/token-update';
export * from './lib/models/url-info';
export * from './lib/models/company';
export * from './lib/apis/check-user-info-ex';
export * from './lib/apis/company-list';
export * from './lib/apis/token-update';
export * from './lib/apis/url-info';
export * from './lib/services/external-api.service';

View File

@ -10,13 +10,13 @@ import {
VersionInfo2Response,
encodeVersionInfo2,
decodeVersionInfo2
} from '../models/version-info2';
} from '../apis/version-info2';
import {
UpdateInfoRequest,
UpdateInfoResponse,
encodeUpdateInfo,
decodeUpdateInfo
} from '../models/update-info';
} from '../apis/update-info';
import { ModuleConfig } from '../types/module-config';
@Injectable({

View File

@ -2,8 +2,8 @@
* Public API Surface of ucap-webmessenger-api-public
*/
export * from './lib/models/update-info';
export * from './lib/models/version-info2';
export * from './lib/apis/update-info';
export * from './lib/apis/version-info2';
export * from './lib/services/public-api.service';

View File

@ -2,7 +2,7 @@
* Public API Surface of ucap-webmessenger-api
*/
export * from './lib/models/api';
export * from './lib/apis/api';
export * from './lib/types/status-code.type';

View File

@ -15,6 +15,7 @@ import { UCapProtocolModule } from '@ucap-webmessenger/protocol';
import { UCapAuthenticationProtocolModule } from '@ucap-webmessenger/protocol-authentication';
import { UCapInnerProtocolModule } from '@ucap-webmessenger/protocol-inner';
import { UCapOptionProtocolModule } from '@ucap-webmessenger/protocol-option';
import { UCapServiceProtocolModule } from '@ucap-webmessenger/protocol-service';
import { UCapSyncProtocolModule } from '@ucap-webmessenger/protocol-sync';
import { UCapUiModule } from '@ucap-webmessenger/ui';
@ -36,6 +37,7 @@ import { AppTranslateModule } from './app-translate.module';
import { AppComponent } from './app.component';
import { GUARDS } from './guards';
import { AppMessengerLayoutModule } from './layouts/messenger/messenger.layout.module';
@NgModule({
imports: [
@ -67,6 +69,7 @@ import { GUARDS } from './guards';
UCapAuthenticationProtocolModule.forRoot(),
UCapInnerProtocolModule.forRoot(),
UCapOptionProtocolModule.forRoot(),
UCapServiceProtocolModule.forRoot(),
UCapSyncProtocolModule.forRoot(),
UCapUiModule.forRoot(),
@ -81,6 +84,8 @@ import { GUARDS } from './guards';
AppStoreModule,
AppTranslateModule,
AppMessengerLayoutModule,
LoggerModule.forRoot({
level: NgxLoggerLevel.DEBUG
})

View File

@ -2,3 +2,16 @@
::ng-deep .mat-tab-label-active {
min-width: 0 !important;
}
::ng-deep .mat-tab-body-wrapper,
::ng-deep .mat-tab-body {
height: 100%;
}
.container {
height: 100%;
mat-tab-group {
height: 100%;
}
}

View File

@ -1 +1,3 @@
Chat
<div *ngFor="let room of roomList$ | async" (click)="onSelectedRoom(room)">
{{ room.finalEventMessage }}
</div>

View File

@ -1,5 +1,11 @@
import { Component, OnInit } from '@angular/core';
import { ucapAnimations } from '@ucap-webmessenger/ui';
import { NGXLogger } from 'ngx-logger';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';
import { RoomInfo } from '@ucap-webmessenger/protocol-room';
import * as AppStore from '@app/store';
import * as ChatStore from '@app/store/messenger/chat';
@Component({
selector: 'app-layout-chat-left-sidenav-chat',
@ -8,7 +14,17 @@ import { ucapAnimations } from '@ucap-webmessenger/ui';
animations: ucapAnimations
})
export class ChatComponent implements OnInit {
constructor() {}
roomList$: Observable<RoomInfo[]>;
ngOnInit() {}
constructor(private store: Store<any>, private logger: NGXLogger) {}
ngOnInit() {
this.roomList$ = this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.roomList)
);
}
onSelectedRoom(roomInfo: RoomInfo) {
this.store.dispatch(ChatStore.selectedRoom({ roomSeq: roomInfo.roomSeq }));
}
}

View File

@ -1,4 +1,46 @@
<ucap-group-expansion-panel
[groupBuddyList]="groupBuddyList$ | async"
(selectBuddy)="onSelectBuddy($event)"
></ucap-group-expansion-panel>
<div>
<div>
<ucap-organization-tenant-search
[companyList]="companyList$ | async"
[companyCode]="companyCode"
(keyDownEnter)="onKeyDownEnterOrganizationTenantSearch($event)"
></ucap-organization-tenant-search>
<button
mat-icon-button
[matMenuTriggerFor]="groupMenu"
aria-label="group menu"
>
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #groupMenu="matMenu" xPosition="after" yPosition="below">
<button mat-menu-item (click)="onClickGroupMenu('GROUP_NEW')">
<mat-icon>group_add</mat-icon>
<span>새 그룹 추가</span>
</button>
<button mat-menu-item (click)="onClickGroupMenu('GROUP_EXPAND_MORE')">
<mat-icon>expand_more</mat-icon>
<span>그룹 전체 열기</span>
</button>
<button mat-menu-item (click)="onClickGroupMenu('GROUP_EXPAND_LESS')">
<mat-icon>expand_less</mat-icon>
<span>그룹 전체 닫기</span>
</button>
<button mat-menu-item (click)="onClickGroupMenu('GROUP_SAVE')">
<mat-icon>save</mat-icon>
<span>그룹 저장하기</span>
</button>
<button mat-menu-item (click)="onClickGroupMenu('GROUP_RESTORE')">
<mat-icon>restore</mat-icon>
<span>그룹 가져오기</span>
</button>
</mat-menu>
</div>
<div>
<ucap-group-expansion-panel
#groupExpansionPanel
[groupBuddyList]="groupBuddyList$ | async"
(selectBuddy)="onSelectBuddy($event)"
>
</ucap-group-expansion-panel>
</div>
</div>

View File

@ -1,16 +1,28 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { Observable, combineLatest, Subscription } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { Store, select } from '@ngrx/store';
import { ucapAnimations } from '@ucap-webmessenger/ui';
import { ucapAnimations, DialogService } from '@ucap-webmessenger/ui';
import { UserInfo, GroupDetailData } from '@ucap-webmessenger/protocol-sync';
import * as AppStore from '@app/store';
import * as ChatStore from '@app/store/messenger/chat';
import * as QueryStore from '@app/store/messenger/query';
import { NGXLogger } from 'ngx-logger';
import { Company } from '@ucap-webmessenger/api-external';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
import { ExpansionPanelComponent as GroupExpansionPanelComponent } from '@ucap-webmessenger/ui-group';
import {
CreateGroupDialogComponent,
CreateGroupDialogData,
CreateGroupDialogResult
} from '@app/layouts/messenger/dialogs/create-group.dialog.component';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { DeptSearchType } from '@ucap-webmessenger/protocol-query';
@Component({
selector: 'app-layout-chat-left-sidenav-group',
@ -19,13 +31,42 @@ import { NGXLogger } from 'ngx-logger';
animations: ucapAnimations
})
export class GroupComponent implements OnInit {
@ViewChild('groupExpansionPanel', { static: true })
groupExpansionPanel: GroupExpansionPanelComponent;
groupBuddyList$: Observable<
{ group: GroupDetailData; buddyList: UserInfo[] }[]
>;
companyList$: Observable<Company[]>;
companyCode: string;
constructor(private store: Store<any>, private logger: NGXLogger) {}
loginRes: LoginResponse;
loginResSubscription: Subscription;
constructor(
private store: Store<any>,
private sessionStorageService: SessionStorageService,
private dialogService: DialogService,
private logger: NGXLogger
) {}
ngOnInit() {
const loginInfo = this.sessionStorageService.get<LoginInfo>(KEY_LOGIN_INFO);
this.companyCode = loginInfo.companyCode;
this.loginResSubscription = this.store
.pipe(
select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
tap(loginRes => {
this.loginRes = loginRes;
})
)
.subscribe();
this.companyList$ = this.store.pipe(
select(AppStore.SettingSelector.CompanySelector.companyList)
);
this.groupBuddyList$ = this.store
.pipe(
select(AppStore.MessengerSelector.SyncSelector.groupListAndBuddyList)
@ -71,7 +112,61 @@ export class GroupComponent implements OnInit {
);
}
async onClickGroupMenu(menuType: string) {
this.logger.debug('menuType', menuType);
switch (menuType) {
case 'GROUP_NEW':
{
const result = await this.dialogService.open<
CreateGroupDialogComponent,
CreateGroupDialogData,
CreateGroupDialogResult
>(CreateGroupDialogComponent, {
width: '220px',
data: {
title: 'Logout',
message: 'Logout ?'
}
});
}
break;
case 'GROUP_EXPAND_MORE':
{
this.groupExpansionPanel.expandMore();
}
break;
case 'GROUP_EXPAND_LESS':
{
this.groupExpansionPanel.expandLess();
}
break;
case 'GROUP_SAVE':
break;
case 'GROUP_RESTORE':
break;
default:
break;
}
}
onSelectBuddy(buddy: UserInfo) {
this.store.dispatch(ChatStore.selectedRoom({ roomSeq: buddy.seq }));
this.store.dispatch(ChatStore.selectedRoom({ roomSeq: String(buddy.seq) }));
}
onKeyDownEnterOrganizationTenantSearch(params: {
companyCode: string;
searchWord: string;
}) {
this.store.dispatch(
QueryStore.deptUser({
divCd: 'GRP',
companyCode: params.companyCode,
searchRange: DeptSearchType.All,
search: params.searchWord,
senderCompanyCode: params.companyCode,
senderEmployeeType: this.loginRes.userInfo.employeeType
})
);
}
}

View File

@ -1 +1,13 @@
<ucap-organization-expansion-panel></ucap-organization-expansion-panel>
<div class="oraganization-tab" fxLayout="column">
<div class="oraganization-tab-tree" fxFlex="50" style="overflow: scroll">
<ucap-organization-tree
[oraganizationList]="departmentInfoList$ | async"
(selected)="onSelectedOrganization($event)"
></ucap-organization-tree>
</div>
<div fxFlex="50" style="overflow: scroll">
<div *ngFor="let userInfo of selectedDepartmentUserInfoList$ | async">
{{ userInfo.name }}
</div>
</div>
</div>

View File

@ -0,0 +1,7 @@
.oraganization-tab {
height: 100%;
.oraganization-tab-tree {
overflow: scroll;
}
}

View File

@ -1,5 +1,21 @@
import { Component, OnInit } from '@angular/core';
import { ucapAnimations } from '@ucap-webmessenger/ui';
import { Observable } from 'rxjs';
import {
DeptInfo,
QueryProtocolService,
DeptSearchType,
UserInfoSS,
DeptUserResponse
} from '@ucap-webmessenger/protocol-query';
import { Store, select } from '@ngrx/store';
import { NGXLogger } from 'ngx-logger';
import * as AppStore from '@app/store';
import * as QueryStore from '@app/store/messenger/query';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
import { take, map, switchMap } from 'rxjs/operators';
@Component({
selector: 'app-layout-chat-left-sidenav-organization',
@ -8,7 +24,52 @@ import { ucapAnimations } from '@ucap-webmessenger/ui';
animations: ucapAnimations
})
export class OrganizationComponent implements OnInit {
constructor() {}
departmentInfoList$: Observable<DeptInfo[]>;
selectedDepartmentUserInfoList$: Observable<UserInfoSS[]>;
selectedDepartmentStatus$: Observable<DeptUserResponse>;
ngOnInit() {}
constructor(
private store: Store<any>,
private queryProtocolService: QueryProtocolService,
private sessionStorageService: SessionStorageService,
private logger: NGXLogger
) {}
ngOnInit() {
this.departmentInfoList$ = this.store.pipe(
select(AppStore.MessengerSelector.QuerySelector.departmentInfoList)
);
this.selectedDepartmentUserInfoList$ = this.store.pipe(
select(
AppStore.MessengerSelector.QuerySelector.selectedDepartmentUserInfoList
)
);
this.selectedDepartmentStatus$ = this.store.pipe(
select(AppStore.MessengerSelector.QuerySelector.selectedDepartmentStatus)
);
}
onSelectedOrganization(deptInfo: DeptInfo) {
const loginInfo = this.sessionStorageService.get<LoginInfo>(KEY_LOGIN_INFO);
this.store
.pipe(
take(1),
select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
map(loginRes => {
this.store.dispatch(
QueryStore.deptUser({
divCd: 'ORG',
companyCode: loginInfo.companyCode,
seq: deptInfo.seq,
search: '',
searchRange: DeptSearchType.All,
senderCompanyCode: loginInfo.companyCode,
senderEmployeeType: loginRes.userInfo.employeeType
})
);
})
)
.subscribe();
}
}

View File

@ -34,11 +34,17 @@
</div>
</mat-toolbar>
<!-- / CHAT TOOLBAR -->
<mat-progress-bar
*ngIf="eventListProcessing$ | async"
mode="indeterminate"
></mat-progress-bar>
<!-- CHAT CONTENT -->
<div fxFlex="1 1 auto" class="chat-content">
<!-- CHAT MESSAGES -->
<ucap-chat-messages></ucap-chat-messages>
<ucap-chat-messages
[messages]="eventList$ | async"
[loginRes]="loginRes"
></ucap-chat-messages>
<!-- CHAT MESSAGES -->
</div>
<!-- / CHAT CONTENT -->
@ -46,7 +52,7 @@
<!-- CHAT FOOTER -->
<div fxFlex="0 0 auto" fxLayout="column">
<!-- REPLY FORM -->
<ucap-chat-form></ucap-chat-form>
<ucap-chat-form (send)="onSendMessage($event)"></ucap-chat-form>
<!-- / REPLY FORM -->
</div>
<!-- / CHAT FOOTER-->

View File

@ -1,5 +1,17 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ucapAnimations } from '@ucap-webmessenger/ui';
import { Store, select } from '@ngrx/store';
import { NGXLogger } from 'ngx-logger';
import { Observable, Subscription } from 'rxjs';
import { Info, EventType } from '@ucap-webmessenger/protocol-event';
import * as AppStore from '@app/store';
import * as EventStore from '@app/store/messenger/event';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
import { RoomInfo } from '@ucap-webmessenger/protocol-room';
import { tap } from 'rxjs/operators';
@Component({
selector: 'app-layout-messenger-messages',
@ -7,10 +19,71 @@ import { ucapAnimations } from '@ucap-webmessenger/ui';
styleUrls: ['./messages.component.scss'],
animations: ucapAnimations
})
export class MessagesComponent implements OnInit {
constructor() {}
export class MessagesComponent implements OnInit, OnDestroy {
loginRes: LoginResponse;
loginResSubscription: Subscription;
eventList$: Observable<Info[]>;
roomInfo: RoomInfo;
roomInfoSubscription: Subscription;
eventListProcessing$: Observable<boolean>;
ngOnInit() {}
constructor(
private store: Store<any>,
private sessionStorageService: SessionStorageService,
private logger: NGXLogger
) {}
ngOnInit() {
const loginInfo = this.sessionStorageService.get<LoginInfo>(KEY_LOGIN_INFO);
this.loginResSubscription = this.store
.pipe(
select(AppStore.AccountSelector.AuthenticationSelector.loginRes),
tap(loginRes => {
this.loginRes = loginRes;
})
)
.subscribe();
this.roomInfoSubscription = this.store
.pipe(
select(AppStore.MessengerSelector.RoomSelector.roomInfo),
tap(roomInfo => {
this.roomInfo = roomInfo;
})
)
.subscribe();
this.eventListProcessing$ = this.store.pipe(
select(AppStore.MessengerSelector.EventSelector.infoListProcessing)
);
this.eventList$ = this.store.pipe(
select(AppStore.MessengerSelector.EventSelector.infoList)
);
}
ngOnDestroy(): void {
if (!!this.loginResSubscription) {
this.loginResSubscription.unsubscribe();
}
if (!!this.roomInfoSubscription) {
this.roomInfoSubscription.unsubscribe();
}
}
selectContact() {}
onSendMessage(message: string) {
this.store.dispatch(
EventStore.send({
senderSeq: this.loginRes.userSeq,
req: {
roomSeq: this.roomInfo.roomSeq,
eventType: EventType.Character,
sentMessage: message
}
})
);
}
}

View File

@ -0,0 +1,18 @@
<mat-card class="confirm-card">
<mat-card-header cdkDrag cdkDragRootElement=".cdk-overlay-pane" cdkDragHandle>
<mat-card-title>새 그룹 추가</mat-card-title>
</mat-card-header>
<mat-card-content> </mat-card-content>
<mat-card-actions class="button-farm flex-row">
<button
mat-stroked-button
(click)="onClickChoice(false)"
class="mat-primary"
>
No
</button>
<button mat-flat-button (click)="onClickChoice(true)" class="mat-primary">
Yes
</button>
</mat-card-actions>
</mat-card>

View File

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

View File

@ -0,0 +1,34 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
export interface CreateGroupDialogData {
title: string;
message?: string;
}
export interface CreateGroupDialogResult {
choice: boolean;
}
@Component({
selector: 'app-layout-messenger-create-group',
templateUrl: './create-group.dialog.component.html',
styleUrls: ['./create-group.dialog.component.scss']
})
export class CreateGroupDialogComponent implements OnInit {
constructor(
public dialogRef: MatDialogRef<
CreateGroupDialogData,
CreateGroupDialogResult
>,
@Inject(MAT_DIALOG_DATA) public data: CreateGroupDialogData
) {}
ngOnInit(): void {}
onClickChoice(choice: boolean): void {
this.dialogRef.close({
choice
});
}
}

View File

@ -0,0 +1,3 @@
import { CreateGroupDialogComponent } from './create-group.dialog.component';
export const DIALOGS = [CreateGroupDialogComponent];

View File

@ -3,31 +3,45 @@ import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { DragDropModule } from '@angular/cdk/drag-drop';
import { UCapUiModule } from '@ucap-webmessenger/ui';
import { UCapUiChatModule } from '@ucap-webmessenger/ui-chat';
import { UCapUiGroupModule } from '@ucap-webmessenger/ui-group';
import { UCapUiOrganizationModule } from '@ucap-webmessenger/ui-organization';
import { COMPONENTS } from './components';
import { DIALOGS } from './dialogs';
@NgModule({
imports: [
CommonModule,
FlexLayoutModule,
DragDropModule,
MatButtonModule,
MatCardModule,
MatDialogModule,
MatIconModule,
MatMenuModule,
MatProgressBarModule,
MatTabsModule,
MatToolbarModule,
UCapUiModule,
UCapUiChatModule,
UCapUiGroupModule,
UCapUiOrganizationModule
],
exports: [...COMPONENTS],
declarations: [...COMPONENTS],
entryComponents: []
exports: [...COMPONENTS, ...DIALOGS],
declarations: [...COMPONENTS, ...DIALOGS],
entryComponents: [...DIALOGS]
})
export class AppMessengerLayoutModule {}

View File

@ -3,6 +3,8 @@ import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { UCapUiAccountModule } from '@ucap-webmessenger/ui-account';
import { AppAccountRoutingPageModule } from './account-routing.page.module';
@ -13,6 +15,7 @@ import { COMPONENTS } from './components';
imports: [
CommonModule,
FlexLayoutModule,
MatButtonModule,
UCapUiAccountModule,
AppAccountRoutingPageModule
],

View File

@ -1,6 +1,19 @@
<div class="login" fxLayout="column">
<div class="login-wrapper" fxLayout="column" fxLayoutAlign="center center">
<ucap-account-login [companyList]="companyList$ | async" (login)="onLogin($event)" (template)="onTemplate($event)">
<ucap-account-login
[companyList]="companyList$ | async"
(login)="onLogin($event)"
>
</ucap-account-login>
</div>
<button
mat-raised-button
color="accent"
class="submit-button"
aria-label="Template"
(click)="onClickTemplate()"
>
Template
</button>
</div>

View File

@ -52,7 +52,7 @@ export class LoginPageComponent implements OnInit {
);
}
onTemplate() {
onClickTemplate() {
this.router.navigate(['/template']);
}
}

View File

@ -2,14 +2,21 @@
<div class="left-side">
<app-layout-messenger-left-side></app-layout-messenger-left-side>
</div>
<div class="contents">
<app-layout-messenger-intro
*ngIf="!(this.selectedChat$ | async)"
></app-layout-messenger-intro>
<app-layout-messenger-messages
*ngIf="!!(this.selectedChat$ | async)"
></app-layout-messenger-messages>
</div>
<mat-drawer-container class="contents" autosize>
<div class="messages">
<app-layout-messenger-intro
(click)="drawer.toggle()"
*ngIf="!(this.selectedChat$ | async)"
></app-layout-messenger-intro>
<app-layout-messenger-messages
*ngIf="!!(this.selectedChat$ | async)"
></app-layout-messenger-messages>
</div>
<mat-drawer #drawer mode="side" position="end">
<p>sidenav</p>
</mat-drawer>
</mat-drawer-container>
<div class="right-side">
<app-layout-messenger-right-side></app-layout-messenger-right-side>
</div>

View File

@ -10,6 +10,11 @@
float: left;
width: calc(100% - 360px);
height: 100%;
.messages {
width: 100%;
height: 100%;
}
}
.right-side {
float: left;

View File

@ -11,7 +11,7 @@ import { Observable } from 'rxjs';
styleUrls: ['./main.page.component.scss']
})
export class MainPageComponent implements OnInit {
selectedChat$: Observable<number | null>;
selectedChat$: Observable<string | null>;
constructor(private store: Store<any>) {}

View File

@ -1,11 +1,22 @@
<div>
<div fxLayout="column">
<button
mat-raised-button
color="accent"
class="submit-button"
aria-label="Login"
(click)="onClickLogin()"
>
Login
</button>
<h3>User-list-item</h3>
<div>
<ucap-profile-user-list-item
[userInfo]="userInfo"
[profileImageRoot]="profileImageRoot"
[presence]="presence"
></ucap-profile-user-list-item>
>
</ucap-profile-user-list-item>
<ucap-profile-user-list-item
[userInfo]="userInfo"
[profileImageRoot]="profileImageRoot"
@ -18,4 +29,131 @@
>
</ucap-profile-user-list-item>
</div>
<h3>Organization</h3>
<div>
<div>
<div>
Tenant Search
</div>
<div>
<ucap-organization-tenant-search
[companyList]="companyList"
[companyCode]="companyCode"
></ucap-organization-tenant-search>
</div>
</div>
</div>
<h3>Chat::MessageBox</h3>
<div>
<div>
<div>
date splitter
</div>
<div>
<ucap-chat-message-box-date-splitter></ucap-chat-message-box-date-splitter>
</div>
</div>
<div>
<div>
file
</div>
<div>
<ucap-chat-message-box-file></ucap-chat-message-box-file>
</div>
</div>
<div>
<div>
image
</div>
<div>
<ucap-chat-message-box-image></ucap-chat-message-box-image>
</div>
</div>
<div>
<div>
information
</div>
<div>
<ucap-chat-message-box-information></ucap-chat-message-box-information>
</div>
</div>
<div>
<div>
mass-translation
</div>
<div>
<ucap-chat-message-box-mass-translation></ucap-chat-message-box-mass-translation>
</div>
</div>
<div>
<div>
mass
</div>
<div>
<ucap-chat-message-box-mass></ucap-chat-message-box-mass>
</div>
</div>
<div>
<div>
notice
</div>
<div>
<ucap-chat-message-box-notice></ucap-chat-message-box-notice>
</div>
</div>
<div>
<div>
recall
</div>
<div>
<ucap-chat-message-box-recall></ucap-chat-message-box-recall>
</div>
</div>
<div>
<div>schedule</div>
<div>
<ucap-chat-message-box-schedule></ucap-chat-message-box-schedule>
</div>
</div>
<div>
<div>
sticker
</div>
<div>
<ucap-chat-message-box-sticker></ucap-chat-message-box-sticker>
</div>
</div>
<div>
<div>
text
</div>
<div>
<ucap-chat-message-box-text></ucap-chat-message-box-text>
</div>
</div>
<div>
<div>
translation
</div>
<div>
<ucap-chat-message-box-translation></ucap-chat-message-box-translation>
</div>
</div>
<div>
<div>
video
</div>
<div>
<ucap-chat-message-box-video></ucap-chat-message-box-video>
</div>
</div>
<div>
<div>
video-conference
</div>
<div>
<ucap-chat-message-box-video-conference></ucap-chat-message-box-video-conference>
</div>
</div>
</div>
</div>

View File

@ -8,6 +8,8 @@ import {
TerminalStatusNumber
} from '@ucap-webmessenger/protocol-status';
import { StatusCode } from '@ucap-webmessenger/core';
import { Router } from '@angular/router';
import { Company } from '@ucap-webmessenger/api-external';
@Component({
selector: 'app-template.page',
@ -21,9 +23,17 @@ export class TemplatePageComponent implements OnInit {
presence: StatusBulkInfo = status;
constructor() {}
companyList: Company[] = companyList;
companyCode: string = 'GUC006';
constructor(private router: Router) {}
ngOnInit() {}
onClickLogin() {
this.router.navigate(['/account/login']);
}
}
export const status: StatusBulkInfo = {
@ -79,3 +89,182 @@ export const buddyData: UserInfo = {
employeeType: EmployeeType.Regular,
nickName: '채책임(닉)'
};
const companyList: Company[] = [
{
companyCode: 'GUC002',
companyName: 'LG Electronics.',
companyDomain: 'lge.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC040',
companyName: 'LGE한국영업협력사',
companyDomain: 'lgepartner.com',
companyConfAuthYn: 'Y',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC021',
companyName: 'LG이노텍',
companyDomain: 'lginnotek.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC036',
companyName: '하이프라자',
companyDomain: 'hiplaza.co.kr',
companyConfAuthYn: 'Y',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC006',
companyName: 'LG CNS',
companyDomain: 'lgcns.com',
companyConfAuthYn: 'Y',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC041',
companyName: 'LGEIL',
companyDomain: 'lgeil.com',
companyConfAuthYn: 'Y',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC100',
companyName: 'LG UCAP',
companyDomain: 'lgucap.com',
companyConfAuthYn: 'Y',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUCIM',
companyName: '아메사용회사',
companyDomain: 'test.com',
companyConfAuthYn: 'N',
ucapUseYn: 'N',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC005',
companyName: 'LG화학',
companyDomain: 'lgchem.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GSGAL',
companyName: 'GS칼텍스',
companyDomain: 'gscaltex.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC001',
companyName: 'LG U+',
companyDomain: 'lguplus.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC007',
companyName: 'LG Display',
companyDomain: 'lgdisplay.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'N'
},
{
companyCode: 'GUC011',
companyName: 'LG인화원',
companyDomain: 'lgacademy.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC013',
companyName: 'LG MMA',
companyDomain: 'lgmma.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC015',
companyName: '(주)LG',
companyDomain: 'lg.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC016',
companyName: 'LGERI',
companyDomain: 'lgeri.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC024',
companyName: 'LG Hausys',
companyDomain: 'lghausys.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC028',
companyName: 'LG상사',
companyDomain: 'lgi.co.kr',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC032',
companyName: '코리아일레콤',
companyDomain: 'koreaelecom.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC035',
companyName: 'HLDS',
companyDomain: 'hlds.co.kr',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC038',
companyName: 'BizTech Partners',
companyDomain: 'GUC018',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
},
{
companyCode: 'GUC042',
companyName: 'Japan R&D Lab',
companyDomain: 'lgjlab.com',
companyConfAuthYn: 'N',
ucapUseYn: 'Y',
companyTimerChatAuthYn: 'Y'
}
];

View File

@ -3,20 +3,27 @@ import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MatButtonModule } from '@angular/material/button';
import { UCapUiChatModule } from '@ucap-webmessenger/ui-chat';
import { UCapUiGroupModule } from '@ucap-webmessenger/ui-group';
import { UCapUiOrganizationModule } from '@ucap-webmessenger/ui-organization';
import { UCapUiProfileModule } from '@ucap-webmessenger/ui-profile';
import { AppTemplateRoutingPageModule } from './template-routing.page.module';
import { COMPONENTS, MET_MODULES } from './components';
import { UcapUiProfileModule } from '@ucap-webmessenger/ui-profile';
@NgModule({
imports: [
...MET_MODULES,
CommonModule,
FlexLayoutModule,
MatButtonModule,
UCapUiChatModule,
UCapUiGroupModule,
UcapUiProfileModule,
UCapUiOrganizationModule,
UCapUiProfileModule,
AppTemplateRoutingPageModule
],
declarations: [...COMPONENTS],

View File

@ -4,15 +4,12 @@ import {
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '@angular/router';
import { Observable, throwError, of, EMPTY, forkJoin } from 'rxjs';
import { Observable, throwError, forkJoin } from 'rxjs';
import {
map,
tap,
mergeMap,
catchError,
take,
exhaustMap,
concatMap,
switchMap,
withLatestFrom
} from 'rxjs/operators';
@ -21,17 +18,14 @@ import { Store, select } from '@ngrx/store';
import { ProtocolService } from '@ucap-webmessenger/protocol';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
PublicApiService,
VersionInfo2Response
} from '@ucap-webmessenger/api-public';
import { PublicApiService } from '@ucap-webmessenger/api-public';
import {
LoginInfo,
KEY_LOGIN_INFO,
EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO
} from '../types';
} from '@app/types';
import { InnerProtocolService } from '@ucap-webmessenger/protocol-inner';
import {
AuthenticationProtocolService,
@ -40,16 +34,15 @@ import {
} from '@ucap-webmessenger/protocol-authentication';
import * as AuthenticationStore from '@app/store/account/authentication';
import { ConnResponse } from 'projects/ucap-webmessenger-protocol-inner/src/lib/models/conn';
import { PiService } from '@ucap-webmessenger/pi';
import { NGXLogger } from 'ngx-logger';
import { QueryProtocolService } from '@ucap-webmessenger/protocol-query';
import { OptionProtocolService } from '@ucap-webmessenger/protocol-option';
import * as AppStore from '@app/store';
import * as CompanyStore from '@app/store/setting/company';
import * as VersionInfoStore from '@app/store/setting/version-info';
import * as OptionStore from '@app/store/setting/option';
import * as QueryStore from '@app/store/setting/query';
import * as OptionStore from '@app/store/messenger/option';
import * as QueryStore from '@app/store/messenger/query';
import * as SyncStore from '@app/store/messenger/sync';
@Injectable()
@ -58,7 +51,6 @@ export class AppMessengerResolver implements Resolve<void> {
private store: Store<any>,
private sessionStorageService: SessionStorageService,
private publicApiService: PublicApiService,
private piService: PiService,
private protocolService: ProtocolService,
private queryProtocolService: QueryProtocolService,
private optionProtocolService: OptionProtocolService,
@ -72,8 +64,6 @@ export class AppMessengerResolver implements Resolve<void> {
routerStateSnapshot: RouterStateSnapshot
): void | Observable<void> | Promise<void> {
return new Promise<void>((resolve, reject) => {
let versionInfo2Res: VersionInfo2Response;
let connRres: ConnResponse;
let loginRes: LoginResponse;
const loginInfo = this.sessionStorageService.get<LoginInfo>(
@ -92,13 +82,14 @@ export class AppMessengerResolver implements Resolve<void> {
})
.pipe(
take(1),
tap(res => {
this.store.dispatch(VersionInfoStore.versionInfo2Success({ res }));
}),
switchMap(res => {
versionInfo2Res = res;
return this.protocolService.connect(versionInfo2Res.serverIp);
return this.protocolService.connect(res.serverIp);
}),
switchMap(() => this.innerProtocolService.conn({})),
switchMap(res => {
connRres = res;
return this.authenticationProtocolService.login({
loginId: loginInfo.loginId,
loginPw: loginInfo.loginPw,
@ -119,19 +110,28 @@ export class AppMessengerResolver implements Resolve<void> {
productName: 'EZMessenger'
});
}),
switchMap(res =>
forkJoin([
switchMap(res => {
loginRes = res;
return forkJoin([
this.queryProtocolService.auth({
deviceType: environmentsInfo.deviceType
}),
this.optionProtocolService.regView({})
])
),
tap(([authRes, regViewRes]) => {
]);
}),
map(([authRes, regViewRes]) => {
this.store.dispatch(
OptionStore.regViewSuccess({ res: regViewRes })
);
this.store.dispatch(QueryStore.authSuccess({ res: authRes }));
this.store.dispatch(
CompanyStore.companyList({
companyGroupCode: 'LG'
})
);
// this.store.dispatch(AuthenticationStore.postLogin({ loginRes }));
}),
withLatestFrom(
this.store.pipe(
@ -139,11 +139,26 @@ export class AppMessengerResolver implements Resolve<void> {
),
this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.group2SyncDate)
),
this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.roomSyncDate)
)
),
map(([[], buddy2SyncDate, group2SyncDate]) => {
map(([_, buddy2SyncDate, group2SyncDate, roomSyncDate]) => {
this.store.dispatch(SyncStore.buddy2({ syncDate: buddy2SyncDate }));
this.store.dispatch(SyncStore.group2({ syncDate: group2SyncDate }));
this.store.dispatch(
SyncStore.room({
syncDate: roomSyncDate,
localeCode: loginInfo.localeCode
})
);
this.store.dispatch(
QueryStore.dept({
divCd: 'ORG',
companyCode: loginInfo.companyCode
})
);
}),
catchError(err => {
return throwError(err);
@ -153,18 +168,13 @@ export class AppMessengerResolver implements Resolve<void> {
() => {
this.store.dispatch(
AuthenticationStore.loginSuccess({
loginInfo: loginRes
loginRes
})
);
console.log('next');
resolve();
},
err => {
console.log('err', err);
reject(err);
},
() => {
console.log('complete');
}
);
});

View File

@ -1,16 +1,15 @@
import { Injectable } from '@angular/core';
import { filter, tap } from 'rxjs/operators';
import { tap } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { ProtocolService } from '@ucap-webmessenger/protocol';
import {
SVC_TYPE_LOGOUT,
SSVC_TYPE_LOGOUT_RES,
SSVC_TYPE_LOGOUT_REMOTE_NOTI,
decodeLogout,
decodeLogoutRemoteNotification
AuthenticationProtocolService,
LogoutResponse,
LogoutRemoteNotification
} from '@ucap-webmessenger/protocol-authentication';
import * as AuthenticationStore from '../store/account/authentication';
@ -19,36 +18,29 @@ import { NGXLogger } from 'ngx-logger';
@Injectable()
export class AppNotificationService {
constructor(
private protocolService: ProtocolService,
private authenticationProtocolService: AuthenticationProtocolService,
private store: Store<any>,
private logger: NGXLogger
) {}
public subscribe(): void {
this.protocolService.serverMessage
this.authenticationProtocolService.logoutNotification$
.pipe(
filter(
message =>
message.serviceType === SVC_TYPE_LOGOUT &&
message.subServiceType === SSVC_TYPE_LOGOUT_RES
),
tap(message => {
const logoutRes = decodeLogout(message);
this.logger.debug('logoutRes', logoutRes);
this.store.dispatch(AuthenticationStore.logout());
})
)
.subscribe();
this.protocolService.serverMessage
.pipe(
filter(
message =>
message.serviceType === SVC_TYPE_LOGOUT &&
message.subServiceType === SSVC_TYPE_LOGOUT_REMOTE_NOTI
),
tap(message => {
const logoutRemoteNoti = decodeLogoutRemoteNotification(message);
tap(notiOrRes => {
switch (notiOrRes.Type) {
case SSVC_TYPE_LOGOUT_RES:
{
const res = notiOrRes as LogoutResponse;
}
break;
case SSVC_TYPE_LOGOUT_REMOTE_NOTI:
{
const noti = notiOrRes as LogoutRemoteNotification;
}
break;
default:
break;
}
this.store.dispatch(AuthenticationStore.logout());
})
)

View File

@ -3,7 +3,11 @@ import { createAction, props } from '@ngrx/store';
import { Login2Response } from '@ucap-webmessenger/pi';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
import { LoginInfo } from '../../../types';
import { LoginInfo } from '@app/types';
import {
UserPasswordSetRequest,
UserPasswordSetResponse
} from '@ucap-webmessenger/protocol-service';
export const webLogin = createAction(
'[Account::Authentication] Web Login',
@ -30,7 +34,7 @@ export const webLoginFailure = createAction(
export const loginSuccess = createAction(
'[Account::Authentication] Login Success',
props<{
loginInfo: LoginResponse;
loginRes: LoginResponse;
}>()
);
@ -52,3 +56,47 @@ export const logoutConfirmation = createAction(
export const logoutConfirmationDismiss = createAction(
'[Account::Authentication] Logout Confirmation Dismiss'
);
export const postLogin = createAction(
'[Account::Authentication] Post Login',
props<{
loginRes: LoginResponse;
}>()
);
export const privacyAgree = createAction(
'[Account::Authentication] Privacy Agree',
props<{
loginRes: LoginResponse;
}>()
);
export const privacyAgreeSuccess = createAction(
'[Account::Authentication] Privacy Agree Success'
);
export const privacyAgreeFailure = createAction(
'[Account::Authentication] Privacy Agree Failure',
props<{ error: any }>()
);
export const privacyDisagree = createAction(
'[Account::Authentication] Privacy Disagree'
);
export const changePassword = createAction(
'[Account::Authentication] Change Password',
props<{ req: UserPasswordSetRequest }>()
);
export const changePasswordSuccess = createAction(
'[Account::Authentication] Change Password Success',
props<{
res: UserPasswordSetResponse;
}>()
);
export const changePasswordFailure = createAction(
'[Account::Authentication] Change Password Failure',
props<{ error: any }>()
);

View File

@ -6,7 +6,11 @@ import { catchError, exhaustMap, map, tap, switchMap } from 'rxjs/operators';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { PiService, Login2Response } from '@ucap-webmessenger/pi';
import {
PiService,
Login2Response,
UserTermsActionResponse
} from '@ucap-webmessenger/pi';
import { NativeService, UCAP_NATIVE_SERVICE } from '@ucap-webmessenger/native';
import {
DialogService,
@ -22,11 +26,30 @@ import {
logoutConfirmationDismiss,
webLogin,
webLoginSuccess,
webLoginFailure
webLoginFailure,
postLogin,
privacyAgree,
privacyDisagree,
privacyAgreeFailure,
privacyAgreeSuccess,
changePassword,
changePasswordFailure,
changePasswordSuccess
} from './actions';
import { LoginInfo } from '../../../types';
import { AppAuthenticationService } from '../../../services/authentication.service';
import {
LoginInfo,
KEY_LOGIN_INFO,
EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO
} from '@app/types';
import { AppAuthenticationService } from '@app/services/authentication.service';
import { NGXLogger } from 'ngx-logger';
import { Store } from '@ngrx/store';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
ServiceProtocolService,
UserPasswordSetResponse
} from '@ucap-webmessenger/protocol-service';
@Injectable()
export class Effects {
@ -125,11 +148,139 @@ export class Effects {
)
);
postLogin$ = createEffect(
() =>
this.actions$.pipe(
ofType(postLogin),
map(action => action.loginRes),
tap(async loginRes => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
if (!loginRes.privateInformationAgree) {
const privacyTotalUrl = this.piService.privacyTotalUrl({
companyCode: loginInfo.companyCode,
userSeq: loginRes.userSeq,
token: loginRes.tokenString,
deviceType: environmentsInfo.deviceType,
localeCode: loginInfo.localeCode,
textOnly: 'true'
});
const result = await this.dialogService.open<
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
>(ConfirmDialogComponent, {
width: '100%',
height: '500px',
disableClose: true,
data: {
title: '개인정보 동의'
// html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />`
}
});
if (result.choice) {
this.store.dispatch(privacyAgree({ loginRes }));
} else {
this.store.dispatch(privacyDisagree());
return;
}
}
if (!!loginRes.passwordExpired) {
const result = await this.dialogService.open<
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
>(ConfirmDialogComponent, {
width: '100%',
height: '500px',
disableClose: true,
data: {
title: '패스워드 만료',
message: ''
}
});
if (result.choice) {
} else {
return;
}
}
})
),
{ dispatch: false }
);
privacyAgree$ = createEffect(() =>
this.actions$.pipe(
ofType(privacyAgree),
map(action => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
return {
loginInfo,
environmentsInfo,
loginResponse: action.loginRes
};
}),
exhaustMap(params =>
this.piService
.userTermsAction({
userSeq: params.loginResponse.userSeq,
token: params.loginResponse.tokenString,
deviceType: params.environmentsInfo.deviceType
})
.pipe(
map((res: UserTermsActionResponse) => {
if ('00' !== res.responseCode) {
return privacyAgreeFailure({ error: 'Failed' });
} else {
return privacyAgreeSuccess();
}
}),
catchError(error => of(privacyAgreeFailure({ error })))
)
)
)
);
changePassword$ = createEffect(() =>
this.actions$.pipe(
ofType(changePassword),
map(action => action.req),
exhaustMap(req =>
this.serviceProtocolService.userPasswordSet(req).pipe(
map((res: UserPasswordSetResponse) => {
return changePasswordSuccess({
res
});
}),
catchError(error => of(changePasswordFailure({ error })))
)
)
)
);
constructor(
private actions$: Actions,
private router: Router,
private store: Store<any>,
private sessionStorageService: SessionStorageService,
private piService: PiService,
private appAuthenticationService: AppAuthenticationService,
private serviceProtocolService: ServiceProtocolService,
private dialogService: DialogService,
@Inject(UCAP_NATIVE_SERVICE) private nativeService: NativeService,
private logger: NGXLogger

View File

@ -7,7 +7,7 @@ export const reducer = createReducer(
on(loginSuccess, (state, action) => {
return {
...state,
loginInfo: action.loginInfo
loginRes: action.loginRes
};
})
);

View File

@ -3,18 +3,18 @@ import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
// tslint:disable-next-line: no-empty-interface
export interface State {
loginInfo: LoginResponse | null;
loginRes: LoginResponse | null;
}
export const initialState: State = {
loginInfo: null
loginRes: null
};
export function selectors<S>(selector: Selector<any, State>) {
return {
loginInfo: createSelector(
loginRes: createSelector(
selector,
(state: State) => state.loginInfo
(state: State) => state.loginRes
)
};
}

View File

@ -2,22 +2,16 @@ import { Type } from '@angular/core';
import { Action, combineReducers, Selector, createSelector } from '@ngrx/store';
import * as AuthenticationStore from './authentication';
import * as PrivacyStore from './privacy';
export interface State {
authentication: AuthenticationStore.State;
privacy: PrivacyStore.State;
}
export const effects: Type<any>[] = [
AuthenticationStore.Effects,
PrivacyStore.Effects
];
export const effects: Type<any>[] = [AuthenticationStore.Effects];
export function reducers(state: State | undefined, action: Action) {
return combineReducers({
authentication: AuthenticationStore.reducer,
privacy: PrivacyStore.reducer
authentication: AuthenticationStore.reducer
})(state, action);
}
@ -28,12 +22,6 @@ export function selectors<S>(selector: Selector<any, State>) {
selector,
(state: State) => state.authentication
)
),
PrivacySelector: PrivacyStore.selectors(
createSelector(
selector,
(state: State) => state.privacy
)
)
};
}

View File

@ -1,25 +0,0 @@
import { createAction, props } from '@ngrx/store';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
export const agreeConfirmationNotNeeded = createAction(
'[Account::Privacy] Agree Confirmation not needed'
);
export const agreeConfirmationYes = createAction(
'[Account::Privacy] Agree Confirmation Yes',
props<{
loginInfo: LoginResponse;
}>()
);
export const agreeConfirmationNo = createAction(
'[Account::Privacy] Agree Confirmation No'
);
export const agreeSuccess = createAction('[Account::Privacy] Agree Success');
export const agreeFailure = createAction(
'[Account::Privacy] Agree Failure',
props<{ error: any }>()
);

View File

@ -1,157 +0,0 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, exhaustMap, map } from 'rxjs/operators';
import {
PiService,
UserTermsActionResponse,
ResponseStatus
} from '@ucap-webmessenger/pi';
import {
DialogService,
ConfirmDialogComponent,
ConfirmDialogData,
ConfirmDialogResult
} from '@ucap-webmessenger/ui';
import { AppAuthenticationService } from '@app/services/authentication.service';
import { loginSuccess, logout } from '../authentication';
import {
agreeConfirmationYes,
agreeConfirmationNo,
agreeConfirmationNotNeeded,
agreeSuccess,
agreeFailure
} from './actions';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
LoginInfo,
KEY_LOGIN_INFO,
EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO
} from '@app/types';
import { initSettings } from '@app/store/setting/init';
@Injectable()
export class Effects {
// agreeConfirmation$ = createEffect(() =>
// this.actions$.pipe(
// ofType(loginSuccess),
// exhaustMap(async params => {
// if (params.loginInfo.privateInformationAgree) {
// return null;
// }
// const loginInfo = this.sessionStorageService.get<LoginInfo>(
// KEY_LOGIN_INFO
// );
// const environmentsInfo = this.sessionStorageService.get<
// EnvironmentsInfo
// >(KEY_ENVIRONMENTS_INFO);
// const privacyTotalUrl = this.piService.privacyTotalUrl({
// companyCode: params.loginInfo.companyCode,
// userSeq: params.loginInfo.userSeq,
// token: params.loginInfo.tokenString,
// deviceType: environmentsInfo.deviceType,
// localeCode: loginInfo.localeCode,
// textOnly: 'true'
// });
// const result = await this.dialogService.open<
// ConfirmDialogComponent,
// ConfirmDialogData,
// ConfirmDialogResult
// >(ConfirmDialogComponent, {
// width: '100%',
// height: '500px',
// disableClose: true,
// data: {
// title: '개인정보 동의',
// html: `<iframe id="ifm_privacy" src="${privacyTotalUrl}" style="width: 100%;height: 300px;" />`
// }
// });
// return {
// loginInfo: params.loginInfo,
// choice: result.choice
// };
// }),
// map(params => {
// if (!params) {
// return agreeConfirmationNotNeeded();
// }
// return params.choice
// ? agreeConfirmationYes({ loginInfo: params.loginInfo })
// : agreeConfirmationNo();
// })
// )
// );
agreeConfirmationYes$ = createEffect(() =>
this.actions$.pipe(
ofType(agreeConfirmationYes),
map(action => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
const environmentsInfo = this.sessionStorageService.get<
EnvironmentsInfo
>(KEY_ENVIRONMENTS_INFO);
return {
loginInfo,
environmentsInfo,
loginResponse: action.loginInfo
};
}),
exhaustMap(params =>
this.piService
.userTermsAction({
userSeq: params.loginResponse.userSeq,
token: params.loginResponse.tokenString,
deviceType: params.environmentsInfo.deviceType
})
.pipe(
map((res: UserTermsActionResponse) => {
if ('00' !== res.responseCode) {
return agreeFailure({ error: 'Failed' });
} else {
return agreeSuccess();
}
}),
catchError(error => of(agreeFailure({ error })))
)
)
)
);
agreeSuccess$ = createEffect(() =>
this.actions$.pipe(
ofType(agreeSuccess),
map(() => initSettings())
)
);
agreeFailure$ = createEffect(() =>
this.actions$.pipe(
ofType(agreeFailure),
map(action => action),
map(() => logout())
)
);
constructor(
private actions$: Actions,
private router: Router,
private piService: PiService,
private sessionStorageService: SessionStorageService,
private appAuthenticationService: AppAuthenticationService,
private dialogService: DialogService
) {}
}

View File

@ -1,4 +0,0 @@
import { Action, combineReducers, createReducer, on } from '@ngrx/store';
import { State, initialState } from './state';
export const reducer = createReducer(initialState);

View File

@ -1,11 +0,0 @@
import { Selector, createSelector } from '@ngrx/store';
import { LoginResponse } from '@ucap-webmessenger/protocol-authentication';
// tslint:disable-next-line: no-empty-interface
export interface State {}
export const initialState: State = {};
export function selectors<S>(selector: Selector<any, State>) {
return {};
}

View File

@ -2,5 +2,5 @@ import { createAction, props } from '@ngrx/store';
export const selectedRoom = createAction(
'[Messenger::Chat] selectedRoom',
props<{ roomSeq: number }>()
props<{ roomSeq: string }>()
);

View File

@ -1,7 +1,7 @@
import { Selector, createSelector } from '@ngrx/store';
export interface State {
selectedRoom: number | null;
selectedRoom: string | null;
}
export const initialState: State = {

View File

@ -0,0 +1,51 @@
import { createAction, props } from '@ngrx/store';
import {
InfoRequest,
Info,
InfoResponse,
SendResponse,
SendRequest
} from '@ucap-webmessenger/protocol-event';
export const info = createAction(
'[Messenger::Event] Info',
props<InfoRequest>()
);
export const infoSuccess = createAction(
'[Messenger::Event] Info Success',
props<{
infoList: Info[];
res: InfoResponse;
}>()
);
export const infoFailure = createAction(
'[Messenger::Event] Info Failure',
props<{ error: any }>()
);
export const appendInfoList = createAction(
'[Messenger::Event] Append InfoList',
props<{
info: Info;
}>()
);
export const send = createAction(
'[Messenger::Event] Send',
props<{ senderSeq: number; req: SendRequest }>()
);
export const sendSuccess = createAction(
'[Messenger::Event] Send Success',
props<{
senderSeq: number;
res: SendResponse;
}>()
);
export const sendFailure = createAction(
'[Messenger::Event] Send Failure',
props<{ error: any }>()
);

View File

@ -0,0 +1,129 @@
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { NGXLogger } from 'ngx-logger';
import { of } from 'rxjs';
import { tap, switchMap, map, catchError, exhaustMap } from 'rxjs/operators';
import {
InfoData,
Info,
InfoResponse,
EventProtocolService,
SSVC_TYPE_EVENT_INFO_DATA,
SSVC_TYPE_EVENT_INFO_RES,
SendResponse
} from '@ucap-webmessenger/protocol-event';
import * as ChatStore from '@app/store/messenger/chat';
import {
info,
infoSuccess,
infoFailure,
send,
sendSuccess,
sendFailure,
appendInfoList
} from './actions';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
@Injectable()
export class Effects {
selectedRoomForInfo$ = createEffect(() =>
this.actions$.pipe(
ofType(ChatStore.selectedRoom),
map(action => {
return info({
roomSeq: action.roomSeq,
baseSeq: 0,
requestCount: 50
});
})
)
);
info$ = createEffect(
() => {
let infoList: Info[];
return this.actions$.pipe(
ofType(info),
tap(() => {
infoList = [];
}),
switchMap(req => {
return this.eventProtocolService.info(req).pipe(
map(res => {
switch (res.Type) {
case SSVC_TYPE_EVENT_INFO_DATA:
infoList.push(...(res as InfoData).infoList);
break;
case SSVC_TYPE_EVENT_INFO_RES:
this.store.dispatch(
infoSuccess({
infoList,
res: res as InfoResponse
})
);
break;
}
}),
catchError(error => of(infoFailure({ error })))
);
})
);
},
{ dispatch: false }
);
send$ = createEffect(() =>
this.actions$.pipe(
ofType(send),
exhaustMap(action =>
this.eventProtocolService.send(action.req).pipe(
map((res: SendResponse) => {
return sendSuccess({
senderSeq: action.senderSeq,
res
});
}),
catchError(error => of(sendFailure({ error })))
)
)
)
);
sendSuccess$ = createEffect(
() => {
return this.actions$.pipe(
ofType(sendSuccess),
tap(action => {
const res = action.res;
const appendInfo: Info = {
seq: res.seq,
type: res.eventType,
senderSeq: action.senderSeq,
sendDate: res.sendDate,
sentMessage: res.message,
receiverCount: res.receiverCount
};
this.store.dispatch(appendInfoList({ info: appendInfo }));
})
);
},
{ dispatch: false }
);
constructor(
private actions$: Actions,
private store: Store<any>,
private eventProtocolService: EventProtocolService,
private sessionStorageService: SessionStorageService,
private logger: NGXLogger
) {}
}

View File

@ -0,0 +1,36 @@
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state';
import { infoSuccess, appendInfoList, info, infoFailure } from './actions';
export const reducer = createReducer(
initialState,
on(info, (state, action) => {
return {
...state,
infoListProcessing: true
};
}),
on(infoSuccess, (state, action) => {
return {
...state,
infoList: action.infoList,
infoStatus: action.res,
infoListProcessing: false
};
}),
on(infoFailure, (state, action) => {
return {
...state,
infoListProcessing: false
};
}),
on(appendInfoList, (state, action) => {
return {
...state,
infoList: [...state.infoList, action.info]
};
})
);

View File

@ -0,0 +1,31 @@
import { Selector, createSelector } from '@ngrx/store';
import { InfoResponse, Info } from '@ucap-webmessenger/protocol-event';
export interface State {
infoListProcessing: boolean;
infoList: Info[] | null;
infoStatus: InfoResponse | null;
}
export const initialState: State = {
infoListProcessing: false,
infoList: null,
infoStatus: null
};
export function selectors<S>(selector: Selector<any, State>) {
return {
infoListProcessing: createSelector(
selector,
(state: State) => state.infoListProcessing
),
infoList: createSelector(
selector,
(state: State) => state.infoList
),
infoStatus: createSelector(
selector,
(state: State) => state.infoStatus
)
};
}

View File

@ -2,18 +2,41 @@ import { Type } from '@angular/core';
import { Action, combineReducers, Selector, createSelector } from '@ngrx/store';
import * as ChatStore from './chat';
import * as EventStore from './event';
import * as OptionStore from './option';
import * as QueryStore from './query';
import * as RoomStore from './room';
import * as StatusStore from './status';
import * as SyncStore from './sync';
export interface State {
chat: ChatStore.State;
event: EventStore.State;
option: OptionStore.State;
query: QueryStore.State;
room: RoomStore.State;
status: StatusStore.State;
sync: SyncStore.State;
}
export const effects: Type<any>[] = [ChatStore.Effects, SyncStore.Effects];
export const effects: Type<any>[] = [
ChatStore.Effects,
EventStore.Effects,
OptionStore.Effects,
QueryStore.Effects,
RoomStore.Effects,
StatusStore.Effects,
SyncStore.Effects
];
export function reducers(state: State | undefined, action: Action) {
return combineReducers({
chat: ChatStore.reducer,
event: EventStore.reducer,
option: OptionStore.reducer,
query: QueryStore.reducer,
room: RoomStore.reducer,
status: StatusStore.reducer,
sync: SyncStore.reducer
})(state, action);
}
@ -26,6 +49,36 @@ export function selectors<S>(selector: Selector<any, State>) {
(state: State) => state.chat
)
),
EventSelector: EventStore.selectors(
createSelector(
selector,
(state: State) => state.event
)
),
OptionSelector: OptionStore.selectors(
createSelector(
selector,
(state: State) => state.option
)
),
RoomSelector: RoomStore.selectors(
createSelector(
selector,
(state: State) => state.room
)
),
QuerySelector: QueryStore.selectors(
createSelector(
selector,
(state: State) => state.query
)
),
StatusSelector: StatusStore.selectors(
createSelector(
selector,
(state: State) => state.status
)
),
SyncSelector: SyncStore.selectors(
createSelector(
selector,

View File

@ -8,31 +8,31 @@ import {
} from '@ucap-webmessenger/protocol-option';
export const regView = createAction(
'[Setting::Option] RegView',
'[Messenger::Option] RegView',
props<RegViewRequest>()
);
export const regViewSuccess = createAction(
'[Setting::Option] RegView Success',
'[Messenger::Option] RegView Success',
props<{ res: RegViewResponse }>()
);
export const regViewFailure = createAction(
'[Setting::Option] RegView Failure',
'[Messenger::Option] RegView Failure',
props<{ error: any }>()
);
export const regUpdate = createAction(
'[Setting::Option] RegUpdate',
'[Messenger::Option] RegUpdate',
props<RegUpdateRequest>()
);
export const regUpdateSuccess = createAction(
'[Setting::Option] RegUpdate Success',
'[Messenger::Option] RegUpdate Success',
props<{ res: RegUpdateResponse }>()
);
export const regUpdateFailure = createAction(
'[Setting::Option] RegUpdate Failure',
'[Messenger::Option] RegUpdate Failure',
props<{ error: any }>()
);

View File

@ -6,24 +6,12 @@ import { of } from 'rxjs';
import { catchError, exhaustMap, map, tap } from 'rxjs/operators';
import { regViewSuccess, regViewFailure } from './actions';
import { initSettings } from '../init';
import { OptionProtocolService } from '@ucap-webmessenger/protocol-option';
import { loginSuccess } from '@app/store/account/authentication';
@Injectable()
export class Effects {
// initSettings$ = createEffect(() =>
// this.actions$.pipe(
// ofType(loginSuccess),
// exhaustMap(() =>
// this.optionProtocolService.regView({}).pipe(
// map(res => regViewSuccess({ res })),
// catchError(error => of(regViewFailure({ error })))
// )
// )
// )
// );
constructor(
private actions$: Actions,
private optionProtocolService: OptionProtocolService

View File

@ -1,7 +1,6 @@
import { Selector, createSelector } from '@ngrx/store';
import { RegViewResponse } from '@ucap-webmessenger/protocol-option';
// tslint:disable-next-line: no-empty-interface
export interface State {
reg?: RegViewResponse;
}

View File

@ -0,0 +1,56 @@
import { createAction, props } from '@ngrx/store';
import {
AuthRequest,
AuthResponse,
DeptRequest,
DeptInfo,
DeptUserRequest,
UserInfoSS,
DeptUserResponse
} from '@ucap-webmessenger/protocol-query';
export const auth = createAction(
'[Messenger::Query] Auth',
props<AuthRequest>()
);
export const authSuccess = createAction(
'[Messenger::Query] Auth Success',
props<{ res: AuthResponse }>()
);
export const authFailure = createAction(
'[Messenger::Query] Auth Failure',
props<{ error: any }>()
);
export const dept = createAction(
'[Messenger::Query] Dept',
props<DeptRequest>()
);
export const deptSuccess = createAction(
'[Messenger::Query] Dept Success',
props<{ departmentInfoList: DeptInfo[] }>()
);
export const deptFailure = createAction(
'[Messenger::Query] Dept Failure',
props<{ error: any }>()
);
export const deptUser = createAction(
'[Messenger::Query] Dept User',
props<DeptUserRequest>()
);
export const deptUserSuccess = createAction(
'[Messenger::Query] Dept User Success',
props<{ userInfos: UserInfoSS[]; res: DeptUserResponse }>()
);
export const deptUserFailure = createAction(
'[Messenger::Query] Dept User Failure',
props<{ error: any }>()
);

View File

@ -0,0 +1,108 @@
import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, tap, switchMap } from 'rxjs/operators';
import {
dept,
deptSuccess,
deptFailure,
deptUser,
deptUserSuccess,
deptUserFailure
} from './actions';
import {
QueryProtocolService,
DeptInfo,
SSVC_TYPE_QUERY_DEPT_DATA,
SSVC_TYPE_QUERY_DEPT_RES,
DeptData,
UserInfoSS,
SSVC_TYPE_QUERY_DEPT_USER_DATA,
DeptUserData,
SSVC_TYPE_QUERY_DEPT_USER_RES,
DeptUserResponse
} from '@ucap-webmessenger/protocol-query';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { Store } from '@ngrx/store';
@Injectable()
export class Effects {
dept$ = createEffect(
() => {
let departmentInfoList: DeptInfo[];
return this.actions$.pipe(
ofType(dept),
tap(() => {
departmentInfoList = [];
}),
switchMap(req => {
return this.queryProtocolService.dept(req).pipe(
map(res => {
switch (res.Type) {
case SSVC_TYPE_QUERY_DEPT_DATA:
departmentInfoList.push(...(res as DeptData).departmentInfos);
break;
case SSVC_TYPE_QUERY_DEPT_RES:
this.store.dispatch(
deptSuccess({
departmentInfoList
})
);
break;
}
}),
catchError(error => of(deptFailure({ error })))
);
})
);
},
{ dispatch: false }
);
deptUser$ = createEffect(
() => {
let userInfos: UserInfoSS[];
return this.actions$.pipe(
ofType(deptUser),
tap(() => {
userInfos = [];
}),
switchMap(req => {
return this.queryProtocolService.deptUser(req).pipe(
map(res => {
switch (res.Type) {
case SSVC_TYPE_QUERY_DEPT_USER_DATA:
userInfos.push(...(res as DeptUserData).userInfos);
break;
case SSVC_TYPE_QUERY_DEPT_USER_RES:
this.store.dispatch(
deptUserSuccess({
userInfos,
res: res as DeptUserResponse
})
);
break;
}
}),
catchError(error => of(deptUserFailure({ error })))
);
})
);
},
{ dispatch: false }
);
constructor(
private actions$: Actions,
private store: Store<any>,
private sessionStorageService: SessionStorageService,
private queryProtocolService: QueryProtocolService
) {}
}

View File

@ -0,0 +1,28 @@
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state';
import { authSuccess, deptSuccess, deptUserSuccess } from './actions';
export const reducer = createReducer(
initialState,
on(authSuccess, (state, action) => {
return {
...state,
auth: action.res
};
}),
on(deptSuccess, (state, action) => {
return {
...state,
departmentInfoList: action.departmentInfoList
};
}),
on(deptUserSuccess, (state, action) => {
return {
...state,
selectedDepartmentUserInfoList: action.userInfos,
selectedDepartmentStatus: action.res
};
})
);

View File

@ -0,0 +1,44 @@
import { Selector, createSelector } from '@ngrx/store';
import {
AuthResponse,
DeptInfo,
UserInfoSS,
DeptUserResponse
} from '@ucap-webmessenger/protocol-query';
export interface State {
auth?: AuthResponse;
departmentInfoList: DeptInfo[] | null;
selectedDepartmentUserInfoList: UserInfoSS[] | null;
selectedDepartmentStatus: DeptUserResponse | null;
}
export const initialState: State = {
auth: null,
departmentInfoList: null,
selectedDepartmentUserInfoList: null,
selectedDepartmentStatus: null
};
export function selectors<S>(selector: Selector<any, State>) {
return {
auth: createSelector(
selector,
(state: State) => state.auth
),
departmentInfoList: createSelector(
selector,
(state: State) => state.departmentInfoList
),
selectedDepartmentUserInfoList: createSelector(
selector,
(state: State) => state.selectedDepartmentUserInfoList
),
selectedDepartmentStatus: createSelector(
selector,
(state: State) => state.selectedDepartmentStatus
)
};
}

View File

@ -0,0 +1,26 @@
import { createAction, props } from '@ngrx/store';
import {
InfoRequest,
RoomInfo,
UserInfoShort,
UserInfo
} from '@ucap-webmessenger/protocol-room';
export const info = createAction(
'[Messenger::Room] Info',
props<InfoRequest>()
);
export const infoSuccess = createAction(
'[Messenger::Room] Info Success',
props<{
roomInfo: RoomInfo;
userInfoShortList: UserInfoShort[];
userInfoList: UserInfo[];
}>()
);
export const infoFailure = createAction(
'[Messenger::Room] Info Failure',
props<{ error: any }>()
);

View File

@ -0,0 +1,101 @@
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { NGXLogger } from 'ngx-logger';
import { of } from 'rxjs';
import { tap, switchMap, map, catchError } from 'rxjs/operators';
import {
RoomInfo,
UserInfoShort,
UserInfo,
RoomProtocolService,
SSVC_TYPE_ROOM_INFO_ROOM,
InfoData,
SSVC_TYPE_ROOM_INFO_USER,
SSVC_TYPE_ROOM_INFO_USER2,
SSVC_TYPE_ROOM_INFO_RES,
UserShortData,
UserData
} from '@ucap-webmessenger/protocol-room';
import * as ChatStore from '@app/store/messenger/chat';
import { info, infoSuccess, infoFailure } from './actions';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { LoginInfo, KEY_LOGIN_INFO } from '@app/types';
@Injectable()
export class Effects {
selectedRoomForInfo$ = createEffect(() =>
this.actions$.pipe(
ofType(ChatStore.selectedRoom),
map(action => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
return info({
roomSeq: action.roomSeq,
isDetail: true,
localeCode: loginInfo.localeCode
});
})
)
);
info$ = createEffect(
() => {
let roomInfo: RoomInfo;
let userInfoShortList: UserInfoShort[];
let userInfoList: UserInfo[];
return this.actions$.pipe(
ofType(info),
tap(() => {
roomInfo = null;
userInfoShortList = [];
userInfoList = [];
}),
switchMap(req => {
return this.roomProtocolService.info(req).pipe(
map(res => {
switch (res.Type) {
case SSVC_TYPE_ROOM_INFO_ROOM:
roomInfo = (res as InfoData).roomInfo;
break;
case SSVC_TYPE_ROOM_INFO_USER:
userInfoShortList.push(...(res as UserShortData).userInfos);
break;
case SSVC_TYPE_ROOM_INFO_USER2:
userInfoList.push(...(res as UserData).userInfos);
break;
case SSVC_TYPE_ROOM_INFO_RES:
this.store.dispatch(
infoSuccess({
roomInfo,
userInfoShortList,
userInfoList
})
);
break;
}
}),
catchError(error => of(infoFailure({ error })))
);
})
);
},
{ dispatch: false }
);
constructor(
private actions$: Actions,
private store: Store<any>,
private roomProtocolService: RoomProtocolService,
private sessionStorageService: SessionStorageService,
private logger: NGXLogger
) {}
}

View File

@ -0,0 +1,4 @@
export * from './actions';
export * from './effects';
export * from './reducers';
export * from './state';

View File

@ -0,0 +1,15 @@
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state';
import { infoSuccess } from './actions';
export const reducer = createReducer(
initialState,
on(infoSuccess, (state, action) => {
return {
...state,
roomInfo: action.roomInfo,
userInfoList: action.userInfoList,
userInfoShortList: action.userInfoShortList
};
})
);

View File

@ -0,0 +1,36 @@
import { Selector, createSelector } from '@ngrx/store';
import {
InfoRequest,
RoomInfo,
UserInfoShort,
UserInfo
} from '@ucap-webmessenger/protocol-room';
export interface State {
roomInfo: RoomInfo | null;
userInfoShortList: UserInfoShort[] | null;
userInfoList: UserInfo[] | null;
}
export const initialState: State = {
roomInfo: null,
userInfoShortList: null,
userInfoList: null
};
export function selectors<S>(selector: Selector<any, State>) {
return {
roomInfo: createSelector(
selector,
(state: State) => state.roomInfo
),
userInfoShortList: createSelector(
selector,
(state: State) => state.userInfoShortList
),
userInfoList: createSelector(
selector,
(state: State) => state.userInfoList
)
};
}

View File

@ -0,0 +1,20 @@
import { createAction, props } from '@ngrx/store';
import {
BulkInfoRequest,
StatusBulkInfo
} from '@ucap-webmessenger/protocol-status';
export const bulkInfo = createAction(
'[Messenger::Status] Bulk Info',
props<BulkInfoRequest>()
);
export const bulkInfoSuccess = createAction(
'[Messenger::Status] Bulk Info Success',
props<{ statusBulkInfoList: StatusBulkInfo[] }>()
);
export const bulkInfoFailure = createAction(
'[Messenger::Status] Bulk Info Failure',
props<{ error: any }>()
);

View File

@ -0,0 +1,77 @@
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { Store } from '@ngrx/store';
import { NGXLogger } from 'ngx-logger';
import * as SyncStore from '@app/store/messenger/sync';
import { bulkInfo, bulkInfoSuccess, bulkInfoFailure } from './actions';
import { tap, switchMap, map, catchError } from 'rxjs/operators';
import {
StatusProtocolService,
SSVC_TYPE_STATUS_BULK_INFO_DATA,
SSVC_TYPE_STATUS_BULK_INFO_RES,
BulkInfoData,
StatusBulkInfo
} from '@ucap-webmessenger/protocol-status';
import { of } from 'rxjs';
@Injectable()
export class Effects {
buddy2SuccessPostBulk$ = createEffect(() =>
this.actions$.pipe(
ofType(SyncStore.buddy2Success),
map(params => {
const userSeqList: number[] = [];
for (const buddy of params.buddyList) {
userSeqList.push(buddy.seq);
}
return bulkInfo({ divCd: 'bulk', userSeqs: userSeqList });
})
)
);
bulkInfo$ = createEffect(
() => {
let statusBulkInfoList: StatusBulkInfo[];
return this.actions$.pipe(
ofType(bulkInfo),
tap(() => {
statusBulkInfoList = [];
}),
switchMap(req => {
return this.statusProtocolService.bulkInfo(req).pipe(
map(res => {
switch (res.Type) {
case SSVC_TYPE_STATUS_BULK_INFO_DATA:
statusBulkInfoList.push(
...(res as BulkInfoData).statusBulkInfos
);
break;
case SSVC_TYPE_STATUS_BULK_INFO_RES:
this.store.dispatch(
bulkInfoSuccess({
statusBulkInfoList
})
);
break;
}
}),
catchError(error => of(bulkInfoFailure({ error })))
);
})
);
},
{ dispatch: false }
);
constructor(
private actions$: Actions,
private store: Store<any>,
private statusProtocolService: StatusProtocolService,
private logger: NGXLogger
) {}
}

View File

@ -0,0 +1,4 @@
export * from './actions';
export * from './effects';
export * from './reducers';
export * from './state';

View File

@ -1,13 +1,13 @@
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state';
import { authSuccess } from './actions';
import { bulkInfoSuccess } from './actions';
export const reducer = createReducer(
initialState,
on(authSuccess, (state, action) => {
on(bulkInfoSuccess, (state, action) => {
return {
...state,
auth: action.res
statusBulkInfoList: action.statusBulkInfoList
};
})
);

View File

@ -1,19 +1,19 @@
import { Selector, createSelector } from '@ngrx/store';
import { AuthResponse } from '@ucap-webmessenger/protocol-query';
import { StatusBulkInfo } from '@ucap-webmessenger/protocol-status';
export interface State {
auth?: AuthResponse;
statusBulkInfoList: StatusBulkInfo[];
}
export const initialState: State = {
auth: null
statusBulkInfoList: []
};
export function selectors<S>(selector: Selector<any, State>) {
return {
auth: createSelector(
statusBulkInfoList: createSelector(
selector,
(state: State) => state.auth
(state: State) => state.statusBulkInfoList
)
};
}

View File

@ -49,7 +49,7 @@ import {
RoomUserDetailData,
RoomResponse
} from '@ucap-webmessenger/protocol-sync';
import { regViewSuccess } from '@app/store/setting/option';
import { regViewSuccess } from '@app/store/messenger/option';
import {
RoomInfo,
UserInfoShort,
@ -127,29 +127,6 @@ export class Effects {
{ dispatch: false }
);
buddy2SuccessPostRoom$ = createEffect(() =>
this.actions$.pipe(
ofType(buddy2Success),
map(action => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
return loginInfo.localeCode;
}),
withLatestFrom(
this.store.pipe(
select(state => {
return state.messenger.sync.roomSyncDate as string;
})
)
),
map(([localeCode, roomSyncDate]) =>
room({ syncDate: roomSyncDate, localeCode })
)
)
);
room$ = createEffect(
() => {
let roomList: RoomInfo[];
@ -203,12 +180,6 @@ export class Effects {
break;
case SSVC_TYPE_SYNC_ROOM_RES:
{
this.logger.debug(
'roomList',
roomList,
'roomUserInfoMap',
roomUserInfoMap
);
this.store.dispatch(
roomSuccess({
roomList,

View File

@ -3,23 +3,17 @@ import { Action, combineReducers, Selector, createSelector } from '@ngrx/store';
import * as CompanyStore from './company';
import * as InitStore from './init';
import * as OptionStore from './option';
import * as QueryStore from './query';
import * as VersionInfoStore from './version-info';
export interface State {
company: CompanyStore.State;
init: InitStore.State;
option: OptionStore.State;
query: QueryStore.State;
versionInfo: VersionInfoStore.State;
}
export const effects: Type<any>[] = [
CompanyStore.Effects,
InitStore.Effects,
OptionStore.Effects,
QueryStore.Effects,
VersionInfoStore.Effects
];
@ -27,8 +21,6 @@ export function reducers(state: State | undefined, action: Action) {
return combineReducers({
company: CompanyStore.reducer,
init: InitStore.reducer,
option: OptionStore.reducer,
query: QueryStore.reducer,
versionInfo: VersionInfoStore.reducer
})(state, action);
}
@ -47,18 +39,6 @@ export function selectors<S>(selector: Selector<any, State>) {
(state: State) => state.init
)
),
OptionSelector: OptionStore.selectors(
createSelector(
selector,
(state: State) => state.option
)
),
QuerySelector: QueryStore.selectors(
createSelector(
selector,
(state: State) => state.query
)
),
VersionInfoSelector: VersionInfoStore.selectors(
createSelector(
selector,

View File

@ -1,15 +0,0 @@
import { createAction, props } from '@ngrx/store';
import { AuthRequest, AuthResponse } from '@ucap-webmessenger/protocol-query';
export const auth = createAction('[Setting::Query] Auth', props<AuthRequest>());
export const authSuccess = createAction(
'[Setting::Query] Auth Success',
props<{ res: AuthResponse }>()
);
export const authFailure = createAction(
'[Setting::Query] Auth Failure',
props<{ error: any }>()
);

View File

@ -1,55 +0,0 @@
import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, exhaustMap, map, tap } from 'rxjs/operators';
import { authSuccess, authFailure } from './actions';
import { initSettings } from '../init';
import {
QueryProtocolService,
AuthRequest
} from '@ucap-webmessenger/protocol-query';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
LoginInfo,
KEY_LOGIN_INFO,
EnvironmentsInfo,
KEY_ENVIRONMENTS_INFO
} from '@app/types';
import { loginSuccess } from '@app/store/account/authentication';
@Injectable()
export class Effects {
// initSettings$ = createEffect(() =>
// this.actions$.pipe(
// ofType(loginSuccess),
// map(() => {
// const loginInfo = this.sessionStorageService.get<LoginInfo>(
// KEY_LOGIN_INFO
// );
// const environmentsInfo = this.sessionStorageService.get<
// EnvironmentsInfo
// >(KEY_ENVIRONMENTS_INFO);
// return {
// deviceType: environmentsInfo.deviceType
// } as AuthRequest;
// }),
// exhaustMap(req =>
// this.queryProtocolService.auth(req).pipe(
// map(res => authSuccess({ res })),
// catchError(error => of(authFailure({ error })))
// )
// )
// )
// );
constructor(
private actions$: Actions,
private sessionStorageService: SessionStorageService,
private queryProtocolService: QueryProtocolService
) {}
}

View File

@ -5,17 +5,17 @@ import {
VersionInfo2Response
} from '@ucap-webmessenger/api-public';
export const fetch = createAction(
'[Setting::VersionInfo] Fetch',
export const versionInfo2 = createAction(
'[Setting::VersionInfo] VersionInfo2',
props<VersionInfo2Request>()
);
export const fetchSuccess = createAction(
'[Setting::VersionInfo] Fetch Success',
props<VersionInfo2Response>()
export const versionInfo2Success = createAction(
'[Setting::VersionInfo] VersionInfo2 Success',
props<{ res: VersionInfo2Response }>()
);
export const fetchFailure = createAction(
'[Setting::VersionInfo] Fetch Failure',
export const versionInfo2Failure = createAction(
'[Setting::VersionInfo] VersionInfo2 Failure',
props<{ error: any }>()
);

View File

@ -12,39 +12,33 @@ import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import { NGXLogger } from 'ngx-logger';
import { fetch, fetchSuccess, fetchFailure } from './actions';
import {
versionInfo2,
versionInfo2Success,
versionInfo2Failure
} from './actions';
@Injectable()
export class Effects {
fetch$ = createEffect(() =>
versionInfo2$ = createEffect(() =>
this.actions$.pipe(
ofType(fetch),
ofType(versionInfo2),
map(action => action),
exhaustMap(req =>
this.publicApiService.versionInfo2(req).pipe(
map(res => {
if (res.statusCode === StatusCode.Success) {
this.logger.debug('fetchSuccess', res);
return fetchSuccess(res);
return versionInfo2Success({ res });
} else {
return fetchFailure({ error: 'Failed' });
return versionInfo2Failure({ error: 'Failed' });
}
}),
catchError(error => of(fetchFailure({ error })))
catchError(error => of(versionInfo2Failure({ error })))
)
)
)
);
fetchSuccess$ = createEffect(
() =>
this.actions$.pipe(
ofType(fetchSuccess),
tap(params => {})
),
{ dispatch: false }
);
constructor(
private actions$: Actions,
private publicApiService: PublicApiService,

View File

@ -1,23 +1,23 @@
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state';
import { fetchSuccess } from './actions';
import { versionInfo2Success } from './actions';
export const reducer = createReducer(
initialState,
on(fetchSuccess, (state, action) => {
on(versionInfo2Success, (state, action) => {
return {
...state,
profileImageRoot: action.profileRoot,
profileImageUploadUrl: action.profileUploadUrl,
profileImageRoot: action.res.profileRoot,
profileImageUploadUrl: action.res.profileUploadUrl,
fileUploadMaxSize:
!!action.fileAllowSize &&
!isNaN(action.fileAllowSize) &&
0 < action.fileAllowSize
? action.fileAllowSize
!!action.res.fileAllowSize &&
!isNaN(action.res.fileAllowSize) &&
0 < action.res.fileAllowSize
? action.res.fileAllowSize
: 0,
fileUploadUrl: action.uploadUrl,
fileDownloadUrl: action.downloadUrl,
serverIp: action.serverIp
fileUploadUrl: action.res.uploadUrl,
fileDownloadUrl: action.res.downloadUrl,
serverIp: action.res.serverIp
};
})
);

Some files were not shown because too many files have changed in this diff Show More