diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.css b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.css index e69de29bb2d1..4ed97c9fb379 100644 --- a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.css +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.css @@ -0,0 +1,16 @@ +:host { + display: block; +} + +.apdex-score-wrapper { + cursor: pointer; + position: relative; +} + +.fa-question-circle { + position: absolute; + top: 1px; + right: 37px; + font-size: 0.6em; + color: var(--icon-default); +} diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.html b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.html index 0c0ddc0e92fc..7a3f019e3bac 100644 --- a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.html +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.html @@ -1,3 +1,8 @@ - - + +
+ + + +
+
diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.ts b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.ts index 02de5d2d1166..bedeb0208720 100644 --- a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.ts +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-container.component.ts @@ -1,10 +1,13 @@ -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { ChangeDetectorRef, Component, ComponentFactoryResolver, Injector, OnDestroy, OnInit } from '@angular/core'; import { Subject, merge } from 'rxjs'; import { filter, switchMap, tap, map, takeUntil } from 'rxjs/operators'; -import { MessageQueueService, MESSAGE_TO, NewUrlStateNotificationService } from 'app/shared/services'; -import { ApdexScoreDataService } from './apdex-score-data.service'; +import { AnalyticsService, DynamicPopupService, MessageQueueService, MESSAGE_TO, NewUrlStateNotificationService, TRACKED_EVENT_LIST } from 'app/shared/services'; +import { IApdexFormulaData, ApdexScoreDataService } from './apdex-score-data.service'; import { ServerMapData } from 'app/core/components/server-map/class/server-map-data.class'; +import { HELP_VIEWER_LIST, HelpViewerPopupContainerComponent } from 'app/core/components/help-viewer-popup/help-viewer-popup-container.component'; +import { ApdexScoreGuideComponent } from './apdex-score-guide.component'; +import { ApdexScoreInteractionService } from './apdex-score-interaction.service'; @Component({ selector: 'pp-apdex-score-container', @@ -25,6 +28,11 @@ export class ApdexScoreContainerComponent implements OnInit, OnDestroy { private messageQueueService: MessageQueueService, private newUrlStateNotificationService: NewUrlStateNotificationService, private cd: ChangeDetectorRef, + private injector: Injector, + private analyticsService: AnalyticsService, + private dynamicPopupService: DynamicPopupService, + private componentFactoryResolver: ComponentFactoryResolver, + private apdexScoreInteractionService: ApdexScoreInteractionService ) { } ngOnInit() { @@ -52,8 +60,9 @@ export class ApdexScoreContainerComponent implements OnInit, OnDestroy { switchMap(({applicationName, serviceTypeCode}: INodeInfo) => { return this.apdexScoreDataService.getApdexScore({applicationName, serviceTypeCode, from: this.previousRange[0], to: this.previousRange[1]}); }) - ).subscribe(({apdexScore}: {apdexScore: number}) => { + ).subscribe(({apdexScore, apdexFormula: apdexFormulaData}: {apdexScore: number, apdexFormula: IApdexFormulaData}) => { this.apdexScore = apdexScore; + this.apdexScoreInteractionService.setApdexFormulaData(apdexFormulaData); this.cd.detectChanges(); }); } @@ -62,4 +71,22 @@ export class ApdexScoreContainerComponent implements OnInit, OnDestroy { this.unsubscribe.next(); this.unsubscribe.complete(); } + + onShowHelp($event: MouseEvent): void { + this.analyticsService.trackEvent(TRACKED_EVENT_LIST.CLICK_APDEX_SCORE, HELP_VIEWER_LIST.APDEX_SCORE); + const {left, top, height} = ($event.target as HTMLElement).getBoundingClientRect(); + + this.dynamicPopupService.openPopup({ + data: HELP_VIEWER_LIST.APDEX_SCORE, + template: ApdexScoreGuideComponent, + coord: { + coordX: left, + coordY: top + height / 2 + }, + component: HelpViewerPopupContainerComponent + }, { + resolver: this.componentFactoryResolver, + injector: this.injector + }); + } } diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-data.service.ts b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-data.service.ts index 356ce3273173..c2367d3dbacc 100644 --- a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-data.service.ts +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-data.service.ts @@ -2,6 +2,12 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; +export interface IApdexFormulaData { + satisfiedCount: number; + toleratingCount: number; + totalSamples: number; +} + @Injectable({providedIn: 'root'}) export class ApdexScoreDataService { private url = 'getApdexScore.pinpoint'; @@ -10,7 +16,7 @@ export class ApdexScoreDataService { private http: HttpClient, ) { } - getApdexScore(params: {[key: string]: any}): Observable<{apdexScore: number}> { - return this.http.get<{apdexScore: number}>(this.url, {params}); + getApdexScore(params: {[key: string]: any}): Observable<{apdexScore: number, apdexFormula: IApdexFormulaData}> { + return this.http.get<{apdexScore: number, apdexFormula: IApdexFormulaData}>(this.url, {params}); } } diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.css b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.css new file mode 100644 index 000000000000..41a75b6a3b14 --- /dev/null +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.css @@ -0,0 +1,119 @@ +:host { + display: block; +} + +.title-group { + display: block; + padding: 14px 18px; + height: auto; + border-bottom: 1px solid var(--border-primary); + font-size: 13px; + font-weight: 600; + color: var(--text-primary); +} + +.desc-group { + font-size: 12px; + color: var(--text-secondary); + border-bottom: 1px solid var(--border-primary); + padding: 14px 18px 7px 18px; + font-weight: 600; +} + +.title-group .title-text { + font-size: 16px; + font-weight: 600; + color: var(--primary); + margin-bottom: 15px; +} + +.title-group .title-desc { + font-size: 12px; + color: var(--text-secondary); +} + +.contents-group { + padding: 14px 14px; +} + +.contents-group .category-title { + font-size: 13px; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 12px; + padding-left: 26px; +} + +.contents-group .category-item-list { + display: flex; + padding: 5px 0; + line-height: 20px; +} + +.apdex-formula-wrapper { +} + +.upper { + display: flex; + justify-content: center; +} + +.lower { + display: flex; + justify-content: center; +} + +.sign { + padding: 5px; +} + +.divider { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 5px 0; + padding: 0; +} + +.formula-elem { + padding: 5px; +} + +.apdex-score-range { + font-size: 12px; + font-weight: 600; + color: var(--text-primary-lightest); + width: 80px; + display: flex; + align-items: center; + justify-content: center; + margin-right: 5px; + text-align: center; +} + +.apdex-score-rank { + font-size: 12px; + color: var(--text-secondary); + flex: 1; + display: flex; + align-items: center; +} + +.fas { + font-size: 15px; + margin-right: 3px; +} + +.excellent { + color: var(--status-success); +} +.good { + color: var(--status-good); +} +.poor { + color: var(--status-warn); +} +.unacceptable { + color: var(--status-fail); +} \ No newline at end of file diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.html b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.html new file mode 100644 index 000000000000..9bee1335235c --- /dev/null +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.html @@ -0,0 +1,31 @@ +
+
+
Apdex Score
+
+
+
+
{{apdexFormulaData.satisfiedCount}}
+
+ [
+
{{apdexFormulaData.toleratingCount}}
+
/
+
2
+
]
+
+
+
+
{{apdexFormulaData.totalSamples}}
+
+
+
+
+
+
Score
+
+ {{score.range}} + + + {{score.rank | titlecase}} + +
+
+
diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.ts b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.ts new file mode 100644 index 000000000000..3ed3c8db612b --- /dev/null +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-guide.component.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; + +import { IApdexFormulaData } from './apdex-score-data.service'; +import { ApdexScoreInteractionService } from './apdex-score-interaction.service'; +import { APDEX_SCORE_RANK } from './apdex-score-utils'; + +@Component({ + selector: 'pp-apdex-score-guide', + templateUrl: './apdex-score-guide.component.html', + styleUrls: ['./apdex-score-guide.component.css'] +}) +export class ApdexScoreGuideComponent implements OnInit { + apdexScoreGuide: {range: string, rank: APDEX_SCORE_RANK}[]; + apdexFormulaData: IApdexFormulaData; + + constructor( + private apdexScoreInteractionService: ApdexScoreInteractionService + ) { } + + ngOnInit() { + this.apdexScoreGuide = [ + {range: '0.94 ~ 1.00', rank: APDEX_SCORE_RANK.EXCELLENT}, + {range: '0.85 ~ 0.94', rank: APDEX_SCORE_RANK.GOOD}, + {range: '0.7 ~ 0.85', rank: APDEX_SCORE_RANK.FAIR}, + {range: '0.5 ~ 0.7', rank: APDEX_SCORE_RANK.POOR}, + {range: '< 0.5', rank: APDEX_SCORE_RANK.UNACCEPTABLE}, + ]; + + this.apdexScoreInteractionService.onApdexFormulaData$.subscribe((data: IApdexFormulaData) => { + this.apdexFormulaData = data; + }); + } + + getIconClass(apdexScoreRank: APDEX_SCORE_RANK) { + const iconClass = apdexScoreRank === APDEX_SCORE_RANK.EXCELLENT ? 'fa-smile-beam' + : apdexScoreRank === APDEX_SCORE_RANK.GOOD ? 'fa-smile' + : apdexScoreRank === APDEX_SCORE_RANK.FAIR ? 'fa-meh' + : apdexScoreRank === APDEX_SCORE_RANK.POOR ? 'fa-frown' + : 'fa-angry'; + + return `${apdexScoreRank} ${iconClass}`; + } +} diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-interaction.service.ts b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-interaction.service.ts new file mode 100644 index 000000000000..6cccfc6e1982 --- /dev/null +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-interaction.service.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; + +import { IApdexFormulaData } from './apdex-score-data.service'; + +@Injectable({providedIn: 'root'}) +export class ApdexScoreInteractionService { + private outApdexFormulaData = new BehaviorSubject(null); + + onApdexFormulaData$: Observable; + + constructor() { + this.onApdexFormulaData$ = this.outApdexFormulaData.asObservable(); + } + + setApdexFormulaData(apdexFormulaData: IApdexFormulaData): void { + this.outApdexFormulaData.next(apdexFormulaData); + } +} diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-utils.ts b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-utils.ts new file mode 100644 index 000000000000..4188a359bc9c --- /dev/null +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score-utils.ts @@ -0,0 +1,15 @@ +export enum APDEX_SCORE_RANK { + EXCELLENT = 'excellent', + GOOD = 'good', + FAIR = 'fair', + POOR = 'poor', + UNACCEPTABLE = 'unacceptable', +} + +export function getApdexScoreRank(score: number): string { + return score < 0.5 ? APDEX_SCORE_RANK.UNACCEPTABLE + : score < 0.7 ? APDEX_SCORE_RANK.POOR + : score < 0.85 ? APDEX_SCORE_RANK.FAIR + : score < 0.94 ? APDEX_SCORE_RANK.GOOD + : APDEX_SCORE_RANK.EXCELLENT; +} diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.css b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.css index 33fb1ea4a917..f9bd970b846f 100644 --- a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.css +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.css @@ -2,12 +2,7 @@ font-size: 16px; } -div { - cursor: pointer; -} - .title { - position: relative; margin-right: 15px; color: var(--text-primary); } @@ -16,14 +11,6 @@ div { font-weight: bold; } -button { - position: absolute; - top: 1px; - right: -6.5px; - font-size: 0.6em; - color: var(--icon-default); -} - .excellent { color: var(--status-success); } @@ -35,4 +22,4 @@ button { } .unacceptable { color: var(--status-fail); -} \ No newline at end of file +} diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.html b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.html index 1495f8386626..fef6f7787e11 100644 --- a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.html +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.html @@ -1,7 +1,2 @@ -
- - Apdex - - - {{ fixedScore }} -
\ No newline at end of file +Apdex +{{fixedScore}} diff --git a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.ts b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.ts index b48b9beeaf18..5461e2f84235 100644 --- a/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.ts +++ b/web/src/main/angular/src/app/core/components/apdex-score/apdex-score.component.ts @@ -1,15 +1,6 @@ -import { Component, ComponentFactoryResolver, Injector, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; -import { AnalyticsService, DynamicPopupService, TRACKED_EVENT_LIST } from 'app/shared/services'; +import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; -import { HELP_VIEWER_LIST, HelpViewerPopupContainerComponent } from 'app/core/components/help-viewer-popup/help-viewer-popup-container.component'; - -const enum APDEX_SCORE_RANK { - EXCELLENT = 'excellent', - GOOD = 'good', - FAIR = 'fair', - POOR = 'poor', - UNACCEPTABLE = 'unacceptable', -} +import { getApdexScoreRank } from './apdex-score-utils'; @Component({ selector: 'pp-apdex-score', @@ -20,61 +11,16 @@ export class ApdexScoreComponent implements OnInit, OnChanges { @Input() score: number; fixedScore: string; + scoreStyleClass: string - constructor( - private injector: Injector, - private analyticsService: AnalyticsService, - private dynamicPopupService: DynamicPopupService, - private componentFactoryResolver: ComponentFactoryResolver, - ) { } - - ngOnInit() { - } - + constructor() {} + ngOnInit() {} ngOnChanges(changes: SimpleChanges) { const score: number = changes.score.currentValue; - if (!isNaN(Number(score))) { + if (!isNaN(Number(score))) { + this.scoreStyleClass = getApdexScoreRank(score); this.fixedScore = (Math.floor(score * 100) / 100).toFixed(2); } } - - getScoreTextClassName() { - let className = ''; - - if (!this.score) { - return 'score'; - } - - if (this.score < 0.5) { - className = APDEX_SCORE_RANK.UNACCEPTABLE; - } else if (this.score < 0.7) { - className = APDEX_SCORE_RANK.POOR; - } else if (this.score < 0.85) { - className = APDEX_SCORE_RANK.FAIR; - } else if (this.score < 0.94) { - className = APDEX_SCORE_RANK.GOOD; - } else { - className = APDEX_SCORE_RANK.EXCELLENT; - } - - return `score ${className}`; - } - - onShowHelp($event: MouseEvent): void { - this.analyticsService.trackEvent(TRACKED_EVENT_LIST.CLICK_APDEX_SCORE, HELP_VIEWER_LIST.APDEX_SCORE); - const { left, top, height } = ($event.target as HTMLElement).getBoundingClientRect(); - - this.dynamicPopupService.openPopup({ - data: HELP_VIEWER_LIST.APDEX_SCORE, - coord: { - coordX: left, - coordY: top + height / 2 - }, - component: HelpViewerPopupContainerComponent - }, { - resolver: this.componentFactoryResolver, - injector: this.injector - }); - } } diff --git a/web/src/main/angular/src/app/core/components/apdex-score/index.ts b/web/src/main/angular/src/app/core/components/apdex-score/index.ts index 3d4487a2df4c..aa073b0eb456 100644 --- a/web/src/main/angular/src/app/core/components/apdex-score/index.ts +++ b/web/src/main/angular/src/app/core/components/apdex-score/index.ts @@ -4,11 +4,13 @@ import { SharedModule } from 'app/shared'; import { HelpViewerPopupModule } from 'app/core/components/help-viewer-popup'; import { ApdexScoreComponent } from './apdex-score.component'; import { ApdexScoreContainerComponent } from './apdex-score-container.component'; +import { ApdexScoreGuideComponent } from './apdex-score-guide.component'; @NgModule({ declarations: [ ApdexScoreComponent, - ApdexScoreContainerComponent + ApdexScoreContainerComponent, + ApdexScoreGuideComponent ], imports: [ HelpViewerPopupModule, @@ -16,6 +18,10 @@ import { ApdexScoreContainerComponent } from './apdex-score-container.component' ], exports: [ ApdexScoreContainerComponent, + ApdexScoreGuideComponent + ], + entryComponents: [ + ApdexScoreGuideComponent ], providers: [ ] diff --git a/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup-container.component.html b/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup-container.component.html index a48b77ec7b97..10efdb92c822 100644 --- a/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup-container.component.html +++ b/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup-container.component.html @@ -1,6 +1,7 @@ diff --git a/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup-container.component.ts b/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup-container.component.ts index d4a8a28dd76d..0fd5ea240e72 100644 --- a/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup-container.component.ts +++ b/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup-container.component.ts @@ -71,6 +71,7 @@ const enum HELP_VIEWER_HEIGHT_STATE { export class HelpViewerPopupContainerComponent implements OnInit, AfterViewInit, DynamicPopup { @Input() data: HELP_VIEWER_LIST; @Input() coord: ICoordinate; + @Input() template: any; @Output() outCreated = new EventEmitter(); @Output() outClose = new EventEmitter(); @Output() outReInit = new EventEmitter<{[key: string]: any}>(); @@ -101,12 +102,12 @@ export class HelpViewerPopupContainerComponent implements OnInit, AfterViewInit, this.outCreated.emit(this.getPosition(this.coord)); } - onInputChange({data, coord}: {data: HELP_VIEWER_LIST, coord: ICoordinate}): void { + onInputChange({data, coord, template}: {data: HELP_VIEWER_LIST, coord: ICoordinate, template: any}): void { if (this.coord) { const { coordX: x1, coordY: y1 } = this.coord; const { coordX: x2, coordY: y2 } = coord; - x1 === x2 && y1 === y2 ? this.outClose.emit() : this.outReInit.emit({ data, coord }); + x1 === x2 && y1 === y2 ? this.outClose.emit() : this.outReInit.emit({data, coord, template}); } } diff --git a/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup.component.html b/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup.component.html index c08b0868ee30..ad7996374efb 100644 --- a/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup.component.html +++ b/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup.component.html @@ -1,17 +1,24 @@ -
-
-
{{helpViewerText.TITLE}}
-
{{helpViewerText.DESC}}
-
-
-
-
{{category.TITLE}}
-
-
-
-
-
-
-
-
-
+ + + + + + +
+
+
{{helpViewerText.TITLE}}
+
{{helpViewerText.DESC}}
+
+
+
+
{{category.TITLE}}
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup.component.ts b/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup.component.ts index 3a18ec7b326a..4f3b196f0262 100644 --- a/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup.component.ts +++ b/web/src/main/angular/src/app/core/components/help-viewer-popup/help-viewer-popup.component.ts @@ -7,6 +7,8 @@ import { Component, OnInit, Input } from '@angular/core'; }) export class HelpViewerPopupComponent implements OnInit { @Input() data: {[key: string]: any}[]; + @Input() template: any; + constructor() {} ngOnInit() {} diff --git a/web/src/main/angular/src/app/core/components/help-viewer-popup/index.ts b/web/src/main/angular/src/app/core/components/help-viewer-popup/index.ts index e73f2d8344a4..2753f1576ae8 100644 --- a/web/src/main/angular/src/app/core/components/help-viewer-popup/index.ts +++ b/web/src/main/angular/src/app/core/components/help-viewer-popup/index.ts @@ -10,11 +10,12 @@ import { HelpViewerPopupComponent } from './help-viewer-popup.component'; HelpViewerPopupComponent ], imports: [ - SharedModule + SharedModule, ], exports: [], entryComponents: [ - HelpViewerPopupContainerComponent + HelpViewerPopupContainerComponent, + HelpViewerPopupComponent, ], providers: [] }) diff --git a/web/src/main/angular/src/app/shared/services/dynamic-popup.service.ts b/web/src/main/angular/src/app/shared/services/dynamic-popup.service.ts index 503ef285c0a0..c9caa6eeac73 100644 --- a/web/src/main/angular/src/app/shared/services/dynamic-popup.service.ts +++ b/web/src/main/angular/src/app/shared/services/dynamic-popup.service.ts @@ -16,6 +16,7 @@ import { export interface DynamicPopup { data?: any; coord?: ICoordinate; + template?: any; outCreated?: EventEmitter; outClose?: EventEmitter; outReInit?: EventEmitter<{[key: string]: any}>; // HelpViewer처럼 컴포넌트를 아예 destroy하고 새로 init해야 하는 경우 @@ -28,9 +29,10 @@ export interface IContext { } interface IPopupParam { + component: any; data?: any; coord?: ICoordinate; - component: any; + template?: any; onCloseCallback?: Function; } @@ -64,14 +66,14 @@ export class DynamicPopupService { this.injector = injector; this.resolver = resolver; - const {data, coord, component} = $param; + const {component, data, coord, template} = $param; if (!this.componentRef) { // The very first this.initPopup($param); } else if (this.componentRef && this.componentRef.instance instanceof component) { // Update input binding - this.bindInputProps(this.componentRef.instance, data, coord); + this.bindInputProps(this.componentRef.instance, data, coord, template); } else { // Close the current popup and create a new one this.closePopup(); @@ -85,21 +87,21 @@ export class DynamicPopupService { this.componentRef = null; } - private initPopup({data, coord, component, onCloseCallback}: IPopupParam): void { + private initPopup({data, coord, component, template, onCloseCallback}: IPopupParam): void { this.componentRef = this.resolver.resolveComponentFactory(component).create(this.injector); const popupComponent = this.componentRef.instance; const domElem = (this.componentRef.hostView as EmbeddedViewRef).rootNodes[0] as HTMLElement; - this.bindInputProps(popupComponent, data, coord); + this.bindInputProps(popupComponent, data, coord, template); this.bindOutputProps(popupComponent, domElem, onCloseCallback); this.renderer.addClass(domElem, 'popup'); this.renderer.appendChild((this.appRef.components[0].location).nativeElement, domElem); this.appRef.attachView(this.componentRef.hostView); } - private bindInputProps(popupComponent: DynamicPopup, data: any, coord: ICoordinate): void { + private bindInputProps(popupComponent: DynamicPopup, data: any, coord: ICoordinate, template: any): void { if (popupComponent.onInputChange) { - popupComponent.onInputChange({data, coord}); + popupComponent.onInputChange({data, coord, template}); } if (data) { popupComponent.data = data; @@ -107,6 +109,9 @@ export class DynamicPopupService { if (coord) { popupComponent.coord = coord; } + if (template) { + popupComponent.template = template; + } } private bindOutputProps(popupComponent: DynamicPopup, domElem: HTMLElement, onCloseCallback: Function): void { @@ -126,14 +131,15 @@ export class DynamicPopupService { }); } if (popupComponent.outReInit) { - popupComponent.outReInit.subscribe(({data, coord}: {data: any, coord: ICoordinate}) => { + popupComponent.outReInit.subscribe(({data, coord, template}: {data: any, coord: ICoordinate, template: any}) => { const component = this.componentRef.componentType; this.closePopup(); this.openPopup({ data, coord, - component + component, + template }, { resolver: this.resolver, injector: this.injector