buddy list is implemented

This commit is contained in:
병준 박 2019-09-25 17:26:19 +09:00
parent 41890118e3
commit f575d9768a
26 changed files with 423 additions and 11 deletions

View File

@ -15,6 +15,7 @@ import { UCapProtocolModule } from '@ucap-webmessenger/protocol';
import { UCapAuthenticationProtocolModule } from '@ucap-webmessenger/protocol-authentication'; import { UCapAuthenticationProtocolModule } from '@ucap-webmessenger/protocol-authentication';
import { UCapInnerProtocolModule } from '@ucap-webmessenger/protocol-inner'; import { UCapInnerProtocolModule } from '@ucap-webmessenger/protocol-inner';
import { UCapOptionProtocolModule } from '@ucap-webmessenger/protocol-option'; import { UCapOptionProtocolModule } from '@ucap-webmessenger/protocol-option';
import { UCapSyncProtocolModule } from '@ucap-webmessenger/protocol-sync';
import { UCapUiModule } from '@ucap-webmessenger/ui'; import { UCapUiModule } from '@ucap-webmessenger/ui';
import { UCapUiAccountModule } from '@ucap-webmessenger/ui-account'; import { UCapUiAccountModule } from '@ucap-webmessenger/ui-account';
@ -64,6 +65,7 @@ import { GUARDS } from './guards';
UCapAuthenticationProtocolModule.forRoot(), UCapAuthenticationProtocolModule.forRoot(),
UCapInnerProtocolModule.forRoot(), UCapInnerProtocolModule.forRoot(),
UCapOptionProtocolModule.forRoot(), UCapOptionProtocolModule.forRoot(),
UCapSyncProtocolModule.forRoot(),
UCapUiModule.forRoot(), UCapUiModule.forRoot(),
UCapUiAccountModule.forRoot(), UCapUiAccountModule.forRoot(),

View File

@ -1 +1,3 @@
<ucap-group-expansion-panel></ucap-group-expansion-panel> <ucap-group-expansion-panel
[buddyInfoList$]="buddyInfoList$"
></ucap-group-expansion-panel>

View File

@ -1,5 +1,13 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Store, select } from '@ngrx/store';
import { ucapAnimations } from '@ucap-webmessenger/ui'; import { ucapAnimations } from '@ucap-webmessenger/ui';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
import * as AppStore from '@app/store';
@Component({ @Component({
selector: 'app-layout-chat-left-sidenav-group', selector: 'app-layout-chat-left-sidenav-group',
@ -8,7 +16,13 @@ import { ucapAnimations } from '@ucap-webmessenger/ui';
animations: ucapAnimations animations: ucapAnimations
}) })
export class GroupComponent implements OnInit { export class GroupComponent implements OnInit {
constructor() {} buddyInfoList$: Observable<UserInfo[]>;
ngOnInit() {} constructor(private store: Store<any>) {}
ngOnInit() {
this.buddyInfoList$ = this.store.pipe(
select(AppStore.MessengerSelector.SyncSelector.buddyInfoList)
);
}
} }

View File

@ -12,11 +12,13 @@ import { storeFreeze } from 'ngrx-store-freeze';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
import * as AccountStore from './account'; import * as AccountStore from './account';
import * as MessengerStore from './messenger';
import * as SettingStore from './setting'; import * as SettingStore from './setting';
export interface State { export interface State {
router: fromRouter.RouterReducerState<any>; router: fromRouter.RouterReducerState<any>;
account: AccountStore.State; account: AccountStore.State;
messenger: MessengerStore.State;
setting: SettingStore.State; setting: SettingStore.State;
} }
@ -31,12 +33,14 @@ export const ROOT_REDUCERS = new InjectionToken<
factory: () => ({ factory: () => ({
router: fromRouter.routerReducer, router: fromRouter.routerReducer,
account: AccountStore.reducers, account: AccountStore.reducers,
messenger: MessengerStore.reducers,
setting: SettingStore.reducers setting: SettingStore.reducers
}) })
}); });
export const effects: Type<any>[] = [ export const effects: Type<any>[] = [
...AccountStore.effects, ...AccountStore.effects,
...MessengerStore.effects,
...SettingStore.effects ...SettingStore.effects
]; ];
@ -61,6 +65,10 @@ export const AccountSelector = AccountStore.selectors(
(state: State) => state.account (state: State) => state.account
); );
export const MessengerSelector = MessengerStore.selectors(
(state: State) => state.messenger
);
export const SettingSelector = SettingStore.selectors( export const SettingSelector = SettingStore.selectors(
(state: State) => state.setting (state: State) => state.setting
); );

View File

@ -0,0 +1,27 @@
import { Type } from '@angular/core';
import { Action, combineReducers, Selector, createSelector } from '@ngrx/store';
import * as SyncStore from './sync';
export interface State {
sync: SyncStore.State;
}
export const effects: Type<any>[] = [SyncStore.Effects];
export function reducers(state: State | undefined, action: Action) {
return combineReducers({
sync: SyncStore.reducer
})(state, action);
}
export function selectors<S>(selector: Selector<any, State>) {
return {
SyncSelector: SyncStore.selectors(
createSelector(
selector,
(state: State) => state.sync
)
)
};
}

View File

@ -0,0 +1,26 @@
import { createAction, props } from '@ngrx/store';
import {
BuddyRequest,
BuddyResponse,
BuddyDetailData
} from '@ucap-webmessenger/protocol-sync';
export const buddy2 = createAction(
'[Messenger::Sync] Buddy2',
props<BuddyRequest>()
);
export const buddy2Data = createAction(
'[Messenger::Sync] Buddy2 Data',
props<{ data: BuddyDetailData }>()
);
export const buddy2Success = createAction(
'[Messenger::Sync] Buddy2 Success',
props<{ res: BuddyResponse }>()
);
export const buddy2Failure = createAction(
'[Messenger::Sync] Buddy2 Failure',
props<{ error: any }>()
);

View File

@ -0,0 +1,52 @@
import { Injectable } from '@angular/core';
import { Actions, ofType, createEffect } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, exhaustMap, map } from 'rxjs/operators';
import { buddy2, buddy2Success, buddy2Failure, buddy2Data } from './actions';
import { SessionStorageService } from '@ucap-webmessenger/web-storage';
import {
SyncProtocolService,
SSVC_TYPE_SYNC_BUDDY2_DATA,
BuddyResponse,
BuddyDetailData
} from '@ucap-webmessenger/protocol-sync';
import { regViewSuccess } from '@app/store/setting/option';
@Injectable()
export class Effects {
regViewSuccess$ = createEffect(() =>
this.actions$.pipe(
ofType(regViewSuccess),
map(() => buddy2({ syncDate: '' }))
)
);
buddy2$ = createEffect(() =>
this.actions$.pipe(
ofType(buddy2),
exhaustMap(req =>
this.syncProtocolService.buddy2(req).pipe(
map(res => {
switch (res.Type) {
case SSVC_TYPE_SYNC_BUDDY2_DATA:
return buddy2Data({ data: res as BuddyDetailData });
}
return buddy2Success({ res: res as BuddyResponse });
}),
catchError(error => of(buddy2Failure({ error })))
)
)
)
);
constructor(
private actions$: Actions,
private syncProtocolService: SyncProtocolService,
private sessionStorageService: SessionStorageService
) {}
}

View File

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

View File

@ -0,0 +1,19 @@
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state';
import { buddy2Data, buddy2Success } from './actions';
export const reducer = createReducer(
initialState,
on(buddy2Data, (state, action) => {
return {
...state,
buddyInfoList: [...state.buddyInfoList, ...action.data.buddyInfos]
};
}),
on(buddy2Success, (state, action) => {
return {
...state,
buddy2SyncDate: action.res.syncDate
};
})
);

View File

@ -0,0 +1,21 @@
import { Selector, createSelector } from '@ngrx/store';
import { UserInfo } from '@ucap-webmessenger/protocol-sync';
export interface State {
buddyInfoList: UserInfo[];
buddy2SyncDate: string;
}
export const initialState: State = {
buddyInfoList: [],
buddy2SyncDate: ''
};
export function selectors<S>(selector: Selector<any, State>) {
return {
buddyInfoList: createSelector(
selector,
(state: State) => state.buddyInfoList
)
};
}

View File

@ -2,18 +2,29 @@ import { Type } from '@angular/core';
import { Action, combineReducers, Selector, createSelector } from '@ngrx/store'; import { Action, combineReducers, Selector, createSelector } from '@ngrx/store';
import * as InitStore from './init'; import * as InitStore from './init';
import * as OptionStore from './option';
import * as QueryStore from './query';
import * as VersionInfoStore from './version-info'; import * as VersionInfoStore from './version-info';
export interface State { export interface State {
init: InitStore.State; init: InitStore.State;
option: OptionStore.State;
query: QueryStore.State;
versionInfo: VersionInfoStore.State; versionInfo: VersionInfoStore.State;
} }
export const effects: Type<any>[] = [VersionInfoStore.Effects]; export const effects: Type<any>[] = [
InitStore.Effects,
OptionStore.Effects,
QueryStore.Effects,
VersionInfoStore.Effects
];
export function reducers(state: State | undefined, action: Action) { export function reducers(state: State | undefined, action: Action) {
return combineReducers({ return combineReducers({
init: InitStore.reducer, init: InitStore.reducer,
option: OptionStore.reducer,
query: QueryStore.reducer,
versionInfo: VersionInfoStore.reducer versionInfo: VersionInfoStore.reducer
})(state, action); })(state, action);
} }
@ -26,6 +37,18 @@ export function selectors<S>(selector: Selector<any, State>) {
(state: State) => state.init (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( VersionInfoSelector: VersionInfoStore.selectors(
createSelector( createSelector(
selector, selector,

View File

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

View File

@ -0,0 +1,30 @@
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 { regViewSuccess, regViewFailure } from './actions';
import { initSettings } from '../init';
import { OptionProtocolService } from '@ucap-webmessenger/protocol-option';
@Injectable()
export class Effects {
initSettings$ = createEffect(() =>
this.actions$.pipe(
ofType(initSettings),
exhaustMap(() =>
this.optionProtocolService.regView({}).pipe(
map(res => regViewSuccess({ res })),
catchError(error => of(regViewFailure({ error })))
)
)
)
);
constructor(
private actions$: Actions,
private optionProtocolService: OptionProtocolService
) {}
}

View File

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

View File

@ -0,0 +1,19 @@
import { createReducer, on } from '@ngrx/store';
import { initialState } from './state';
import { regViewSuccess, regUpdateSuccess } from './actions';
export const reducer = createReducer(
initialState,
on(regViewSuccess, (state, action) => {
return {
...state,
reg: action.res
};
}),
on(regUpdateSuccess, (state, action) => {
return {
...state,
reg: action.res
};
})
);

View File

@ -0,0 +1,20 @@
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;
}
export const initialState: State = {
reg: null
};
export function selectors<S>(selector: Selector<any, State>) {
return {
reg: createSelector(
selector,
(state: State) => state.reg
)
};
}

View File

@ -0,0 +1,15 @@
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

@ -0,0 +1,45 @@
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 } from '@app/types';
@Injectable()
export class Effects {
initSettings$ = createEffect(() =>
this.actions$.pipe(
ofType(initSettings),
map(() => {
const loginInfo = this.sessionStorageService.get<LoginInfo>(
KEY_LOGIN_INFO
);
return {
deviceType: loginInfo.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

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

View File

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

View File

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

View File

@ -80,7 +80,6 @@ export const decodeBuddyDetailData: ProtocolDecoder<BuddyDetailData> = (
const buddyInfos: UserInfo[] = []; const buddyInfos: UserInfo[] = [];
message.bodyList.forEach(buddyinfo => { message.bodyList.forEach(buddyinfo => {
const info = buddyinfo.split(BodyStringDivider); const info = buddyinfo.split(BodyStringDivider);
console.log('buddyinfo', info);
let i = 0; let i = 0;
buddyInfos.push({ buddyInfos.push({
seq: info[i], seq: info[i],

View File

@ -11,7 +11,8 @@ import {
encodeBuddy, encodeBuddy,
decodeBuddyData, decodeBuddyData,
decodeBuddy, decodeBuddy,
decodeBuddyDetailData decodeBuddyDetailData,
BuddyDetailData
} from '../models/buddy'; } from '../models/buddy';
import { import {
SVC_TYPE_SYNC_BUDDY, SVC_TYPE_SYNC_BUDDY,
@ -90,7 +91,9 @@ export class SyncProtocolService {
); );
} }
public buddy2(req: BuddyRequest): Observable<BuddyResponse | BuddyData> { public buddy2(
req: BuddyRequest
): Observable<BuddyResponse | BuddyDetailData> {
return this.protocolService return this.protocolService
.call(SVC_TYPE_SYNC_BUDDY, SSVC_TYPE_SYNC_BUDDY2_REQ, ...encodeBuddy(req)) .call(SVC_TYPE_SYNC_BUDDY, SSVC_TYPE_SYNC_BUDDY2_REQ, ...encodeBuddy(req))
.pipe( .pipe(

View File

@ -8,4 +8,5 @@ export * from './lib/services/sync-protocol.service';
export * from './lib/ucap-sync-protocol.module'; export * from './lib/ucap-sync-protocol.module';
export * from './lib/types/service';
export * from './lib/types/userInfo'; export * from './lib/types/userInfo';

View File

@ -1,8 +1,10 @@
<mat-accordion> <mat-accordion>
<mat-expansion-panel *ngFor="let group of groupList"> <mat-expansion-panel *ngFor="let buddyInfo of buddyInfoList$ | async">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title> </mat-panel-title> <mat-panel-title> {{ buddyInfo.name }} </mat-panel-title>
<mat-panel-description> </mat-panel-description> <mat-panel-description
>{{ buddyInfo.employeeNum }}
</mat-panel-description>
</mat-expansion-panel-header> </mat-expansion-panel-header>
</mat-expansion-panel> </mat-expansion-panel>
</mat-accordion> </mat-accordion>

View File

@ -1,4 +1,6 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input } from '@angular/core';
import { Observable } from 'rxjs';
import { UserInfo } from '@ucap-webmessenger/protocol-room';
@Component({ @Component({
selector: 'ucap-group-expansion-panel', selector: 'ucap-group-expansion-panel',
@ -7,7 +9,7 @@ import { Component, OnInit, Input } from '@angular/core';
}) })
export class ExpansionPanelComponent implements OnInit { export class ExpansionPanelComponent implements OnInit {
@Input() @Input()
groupList: any[]; buddyInfoList$: Observable<UserInfo[]>;
constructor() {} constructor() {}