From 28ef8e05454e1315943222ffe779bb97195ba993 Mon Sep 17 00:00:00 2001 From: insanity Date: Sun, 29 Apr 2018 19:43:14 +0900 Subject: [PATCH] unsubscribe test --- .../component/detail/detail.component.html | 7 +-- .../component/detail/detail.component.ts | 53 ++++++++++++------- .../probe/component/list/list.component.html | 2 +- .../probe/component/list/list.component.ts | 13 +++-- src/packages/probe/service/probe.service.ts | 4 ++ .../probe/store/detail/detail.action.ts | 3 -- .../probe/store/modify/modify.reducer.ts | 4 +- .../probe/store/modify/modify.state.ts | 4 +- src/packages/probe/store/remove/index.ts | 4 ++ .../probe/store/remove/remove.action.ts | 37 +++++++++++++ .../probe/store/remove/remove.effect.spec.ts | 15 ++++++ .../probe/store/remove/remove.effect.ts | 49 +++++++++++++++++ .../probe/store/remove/remove.reducer.ts | 49 +++++++++++++++++ .../probe/store/remove/remove.state.ts | 15 ++++++ 14 files changed, 226 insertions(+), 33 deletions(-) create mode 100644 src/packages/probe/store/remove/index.ts create mode 100644 src/packages/probe/store/remove/remove.action.ts create mode 100644 src/packages/probe/store/remove/remove.effect.spec.ts create mode 100644 src/packages/probe/store/remove/remove.effect.ts create mode 100644 src/packages/probe/store/remove/remove.reducer.ts create mode 100644 src/packages/probe/store/remove/remove.state.ts diff --git a/src/packages/probe/component/detail/detail.component.html b/src/packages/probe/component/detail/detail.component.html index d2ad479..ef03654 100644 --- a/src/packages/probe/component/detail/detail.component.html +++ b/src/packages/probe/component/detail/detail.component.html @@ -9,10 +9,10 @@
- + - +
@@ -43,4 +43,5 @@ (click)="onRemoveClick()">
- \ No newline at end of file + + \ No newline at end of file diff --git a/src/packages/probe/component/detail/detail.component.ts b/src/packages/probe/component/detail/detail.component.ts index fd589c4..b5f0235 100644 --- a/src/packages/probe/component/detail/detail.component.ts +++ b/src/packages/probe/component/detail/detail.component.ts @@ -6,33 +6,35 @@ import * as DetailStore from '../../store/detail'; import * as ModifyStore from '../../store/modify'; import { DetailSelector, ModifySelector } from '../../store'; import { Probe } from '../../model'; -import { ConfirmationService } from 'primeng/primeng'; +import { ConfirmationService, Message } from 'primeng/primeng'; import * as CIDR from 'ip-cidr'; import { Subscription } from 'rxjs/Subscription'; +import { MessageService } from 'primeng/components/common/messageservice'; // import { SettingComponent as DiscoverySettingComponent } from 'packages/discovery/component/setting/setting.component'; @Component({ selector: 'of-probe-detail', templateUrl: './detail.component.html', - providers: [ConfirmationService] + providers: [ConfirmationService, MessageService] }) export class DetailComponent implements OnInit, AfterContentInit, OnDestroy { probeSubscription$: Subscription; - modifySuccessSubscription$: Subscription; probe$ = this.detailStore.pipe(select(DetailSelector.select('probe'))); - modifySuccess$ = this.modifyStore.pipe(select(ModifySelector.select('probe'))); + modifySuccess$ = this.modifyStore.pipe(select(ModifySelector.select('modifiedProbe'))); probe: Probe = null; IPRange: string; display = false; + msgs: Message[] = []; constructor( private route: ActivatedRoute, private router: Router, private detailStore: Store, private modifyStore: Store, - private confirmationService: ConfirmationService + private confirmationService: ConfirmationService, + private messageService: MessageService ) { } ngOnInit() { @@ -47,23 +49,12 @@ export class DetailComponent implements OnInit, AfterContentInit, OnDestroy { console.log(error.response.message); } ); - this.modifySuccessSubscription$ = this.modifySuccess$.subscribe( - (probe: Probe) => { - if (probe) { - console.log('modify success'); - } else { - console.log('modify fail'); - } - }, - (error: RPCClientError) => { - console.log(error.response.message); - } - ); } ngOnDestroy() { - this.probeSubscription$.unsubscribe(); - this.modifySuccessSubscription$.unsubscribe(); + if (this.probeSubscription$) { + this.probeSubscription$.unsubscribe(); + } } ngAfterContentInit() { @@ -105,10 +96,34 @@ export class DetailComponent implements OnInit, AfterContentInit, OnDestroy { } onDisplayNameChange(value: string) { + if (value === this.probe.displayName) { + return; + } this.probe.displayName = value; this.modifyStore.dispatch( new ModifyStore.Modify(this.probe) ); + + const modifySuccessSubscription$: Subscription = this.modifySuccess$.subscribe( + (probe: Probe) => { + if (probe) { + this.msgs = []; + this.msgs.push({ severity: 'success', summary: 'Succeed', detail: 'Probe name has changed.' }); + } + if (modifySuccessSubscription$) { + modifySuccessSubscription$.unsubscribe(); + } + }, + (error: RPCClientError) => { + console.log(error.response.message); + } + ); + } + + onDisplayNameChangeKeypress(event, value) { + if (event.key === 'Enter') { + this.onDisplayNameChange(value); + } } } diff --git a/src/packages/probe/component/list/list.component.html b/src/packages/probe/component/list/list.component.html index 84bb8c1..c2ec4bd 100644 --- a/src/packages/probe/component/list/list.component.html +++ b/src/packages/probe/component/list/list.component.html @@ -17,7 +17,7 @@ {{probeHost.host.ipv4}} {{probeHost.host.os.vendor.name}} {{probeHost.probe.cidr}} - 반정규화 필요 + {{probeHost.probe.targetCount}} {{probeHost.probe.authorizeDate | date: 'dd.MM.yyyy'}} {{probeHost.probe.authorizeMember.name}} diff --git a/src/packages/probe/component/list/list.component.ts b/src/packages/probe/component/list/list.component.ts index b1047b9..ded8381 100644 --- a/src/packages/probe/component/list/list.component.ts +++ b/src/packages/probe/component/list/list.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, AfterViewInit, AfterContentInit, ViewChild } from '@angular/core'; +import { Component, OnInit, AfterViewInit, AfterContentInit, ViewChild, OnDestroy } from '@angular/core'; import { Router } from '@angular/router'; import { Store, select } from '@ngrx/store'; @@ -10,12 +10,14 @@ import { AuthSelector } from 'packages/member/store'; import { Probe, ProbeHost } from '../../model'; import * as ListStore from '../../store/probe-host-list'; import { ProbeHostListSelector } from '../../store'; +import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'of-probe-list', templateUrl: './list.component.html', }) -export class ListComponent implements OnInit, AfterContentInit { +export class ListComponent implements OnInit, AfterContentInit, OnDestroy { + probeHostsSubscription$: Subscription; probeHosts$ = this.store.pipe(select(ProbeHostListSelector.select('probeHosts'))); probeHosts: ProbeHost[]; @@ -26,7 +28,7 @@ export class ListComponent implements OnInit, AfterContentInit { } ngOnInit() { - this.probeHosts$.subscribe( + this.probeHostsSubscription$ = this.probeHosts$.subscribe( (probeHosts: ProbeHost[]) => { console.log(probeHosts); this.probeHosts = probeHosts; @@ -46,7 +48,12 @@ export class ListComponent implements OnInit, AfterContentInit { console.log(error); } ); + } + ngOnDestroy() { + if (this.probeHostsSubscription$) { + this.probeHostsSubscription$.unsubscribe(); + } } onRowSelect(event) { diff --git a/src/packages/probe/service/probe.service.ts b/src/packages/probe/service/probe.service.ts index 84602f4..8936302 100644 --- a/src/packages/probe/service/probe.service.ts +++ b/src/packages/probe/service/probe.service.ts @@ -31,4 +31,8 @@ export class ProbeService { return this.rpcService.call('ProbeService.modify', probe); } + public remove(id: string): Observable { + return this.rpcService.call('ProbeService.remove', id); + } + } diff --git a/src/packages/probe/store/detail/detail.action.ts b/src/packages/probe/store/detail/detail.action.ts index be8c298..e6a02bf 100644 --- a/src/packages/probe/store/detail/detail.action.ts +++ b/src/packages/probe/store/detail/detail.action.ts @@ -9,9 +9,6 @@ export enum ActionType { Read = '[probe.detail] Read', ReadSuccess = '[probe.detail] ReadSuccess', ReadFailure = '[probe.detail] ReadFailure', - Modify = '[probe.detail] Modify', - ModifySuccess = '[probe.detail] ModifySuccess', - ModifyFailure = '[probe.detail] ModifyFailure', } export class Read implements Action { diff --git a/src/packages/probe/store/modify/modify.reducer.ts b/src/packages/probe/store/modify/modify.reducer.ts index f3542b0..ec40bc0 100644 --- a/src/packages/probe/store/modify/modify.reducer.ts +++ b/src/packages/probe/store/modify/modify.reducer.ts @@ -26,7 +26,7 @@ export function reducer(state = initialState, action: Actions): State { ...state, error: null, isPending: false, - probe: action.payload, + modifiedProbe: action.payload, }; } @@ -35,7 +35,7 @@ export function reducer(state = initialState, action: Actions): State { ...state, error: action.payload, isPending: false, - probe: null, + modifiedProbe: null, }; } diff --git a/src/packages/probe/store/modify/modify.state.ts b/src/packages/probe/store/modify/modify.state.ts index 0284fdc..46d756c 100644 --- a/src/packages/probe/store/modify/modify.state.ts +++ b/src/packages/probe/store/modify/modify.state.ts @@ -7,12 +7,12 @@ import { createEntityAdapter, EntityAdapter, EntityState } from '@ngrx/entity'; export interface State extends EntityState { error: RPCClientError | null; isPending: boolean; - probe: Probe | null; + modifiedProbe: Probe | null; } export const adapter: EntityAdapter = createEntityAdapter(); export const initialState: State = adapter.getInitialState({ error: null, isPending: false, - probe: null, + modifiedProbe: null, }); diff --git a/src/packages/probe/store/remove/index.ts b/src/packages/probe/store/remove/index.ts new file mode 100644 index 0000000..68b5cb8 --- /dev/null +++ b/src/packages/probe/store/remove/index.ts @@ -0,0 +1,4 @@ +export * from './remove.action'; +export * from './remove.effect'; +export * from './remove.reducer'; +export * from './remove.state'; diff --git a/src/packages/probe/store/remove/remove.action.ts b/src/packages/probe/store/remove/remove.action.ts new file mode 100644 index 0000000..6075f25 --- /dev/null +++ b/src/packages/probe/store/remove/remove.action.ts @@ -0,0 +1,37 @@ +import { Action } from '@ngrx/store'; + +import { RPCClientError } from '@loafer/ng-rpc/protocol'; + +import { Probe } from '../../model'; + + +export enum ActionType { + Remove = '[probe.remove] Remove', + RemoveSuccess = '[probe.detail] RemoveSuccess', + RemoveFailure = '[probe.detail] RemoveFailure', +} + +export class Remove implements Action { + readonly type = ActionType.Remove; + + constructor(public payload: {id: string}) {} +} + +export class RemoveSuccess implements Action { + readonly type = ActionType.RemoveSuccess; + + constructor(public payload: boolean) {} +} + +export class RemoveFailure implements Action { + readonly type = ActionType.RemoveFailure; + + constructor(public payload: RPCClientError) {} +} + + +export type Actions = + | Remove + | RemoveSuccess + | RemoveFailure +; diff --git a/src/packages/probe/store/remove/remove.effect.spec.ts b/src/packages/probe/store/remove/remove.effect.spec.ts new file mode 100644 index 0000000..b625d89 --- /dev/null +++ b/src/packages/probe/store/remove/remove.effect.spec.ts @@ -0,0 +1,15 @@ +import { TestBed, inject } from '@angular/core/testing'; + +import { Effects } from './remove.effect'; + +describe('ProbeDetail.Effects', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [Effects] + }); + }); + + it('should be created', inject([Effects], (effects: Effects) => { + expect(effects).toBeTruthy(); + })); +}); diff --git a/src/packages/probe/store/remove/remove.effect.ts b/src/packages/probe/store/remove/remove.effect.ts new file mode 100644 index 0000000..4d7b480 --- /dev/null +++ b/src/packages/probe/store/remove/remove.effect.ts @@ -0,0 +1,49 @@ +import { Injectable } from '@angular/core'; +import { Router } from '@angular/router'; + +import { Effect, Actions, ofType } from '@ngrx/effects'; +import { Action } from '@ngrx/store'; + +import { Observable } from 'rxjs/Observable'; +import { of } from 'rxjs/observable/of'; + +import 'rxjs/add/operator/catch'; +import 'rxjs/add/operator/do'; +import 'rxjs/add/operator/exhaustMap'; +import 'rxjs/add/operator/switchMap'; +import 'rxjs/add/operator/map'; +import 'rxjs/add/operator/take'; + +import { RPCClientError } from '@loafer/ng-rpc/protocol'; + +import { Probe } from '../../model'; +import { ProbeService } from '../../service/probe.service'; + +import { + Remove, + RemoveSuccess, + RemoveFailure, + ActionType +} from './remove.action'; + +@Injectable() +export class Effects { + + constructor( + private actions$: Actions, + private probeService: ProbeService, + private router: Router + ) { } + + @Effect() + remove$: Observable = this.actions$ + .ofType(ActionType.Remove) + .map((action: Remove) => action.payload) + .switchMap(payload => this.probeService.remove(payload.id)) + .map(result => { + return new RemoveSuccess(result); + }) + .catch((error: RPCClientError) => { + return of(new RemoveFailure(error)); + }); +} diff --git a/src/packages/probe/store/remove/remove.reducer.ts b/src/packages/probe/store/remove/remove.reducer.ts new file mode 100644 index 0000000..5f22830 --- /dev/null +++ b/src/packages/probe/store/remove/remove.reducer.ts @@ -0,0 +1,49 @@ +import { + Remove, + RemoveFailure, + RemoveSuccess, + ActionType, + Actions, +} from './remove.action'; + +import { + State, + initialState, +} from './remove.state'; + +import { Probe } from '../../model'; + + +export function reducer(state = initialState, action: Actions): State { + switch (action.type) { + case ActionType.Remove: { + return { + ...state, + error: null, + isPending: true, + }; + } + + case ActionType.RemoveSuccess: { + return { + ...state, + error: null, + isPending: false, + succeed: action.payload, + }; + } + + case ActionType.RemoveFailure: { + return { + ...state, + error: action.payload, + isPending: false, + succeed: false, + }; + } + + default: { + return state; + } + } +} diff --git a/src/packages/probe/store/remove/remove.state.ts b/src/packages/probe/store/remove/remove.state.ts new file mode 100644 index 0000000..8866bc2 --- /dev/null +++ b/src/packages/probe/store/remove/remove.state.ts @@ -0,0 +1,15 @@ +import { RPCClientError } from '@loafer/ng-rpc/protocol'; +import { Probe } from '../../model'; + +export interface State { + error: RPCClientError | null; + isPending: boolean; + succeed: boolean | null; +} + +export const initialState: State = { + error: null, + isPending: false, + succeed: null, +}; +