1 import {Component, OnInit, ViewChild} from '@angular/core';
2 import {ServiceInfoService} from '../shared/server/serviceInfo/serviceInfo.service';
3 import {ServiceInfoModel} from '../shared/server/serviceInfo/serviceInfo.model';
4 import {InstantiationStatusComponentService} from './instantiationStatus.component.service';
5 import {ContextMenuComponent, ContextMenuService} from 'ngx-contextmenu';
6 import {AuditInfoModalComponent} from "../shared/components/auditInfoModal/auditInfoModal.component";
7 import * as _ from 'lodash';
8 import {ScrollToConfigOptions, ScrollToService} from '@nicky-lenaers/ngx-scroll-to';
9 import {ConfigurationService} from "../shared/services/configuration.service";
10 import {LogService} from '../shared/utils/log/log.service';
11 import {AppState} from "../shared/store/reducers";
12 import {NgRedux} from '@angular-redux/store';
13 import {JobStatus, ServiceAction} from "../shared/models/serviceInstanceActions";
14 import {ActivatedRoute} from "@angular/router";
15 import {FeatureFlagsService, Features} from "../shared/services/featureFlag/feature-flags.service";
16 import {updateServiceInfoModel} from "../shared/storeUtil/utils/service/service.actions";
18 export interface MenuAction{
23 click(item: ServiceInfoModel): void;
24 enabled (item?: ServiceInfoModel): boolean;
25 visible (item?: ServiceInfoModel): boolean;
29 selector : 'instantiation-status',
30 templateUrl : './instantiationStatus.component.html',
31 styleUrls : ['./instantiationStatus.component.scss']
33 export class InstantiationStatusComponent implements OnInit {
35 TIMER_TIME_IN_SECONDS : number = 0;
37 dataIsReady : boolean = false;
38 scroll : boolean = false;
39 lastUpdatedDate: Date = null;
40 instantiationStatusComponentService: InstantiationStatusComponentService;
41 configurationService : ConfigurationService;
42 serviceInfoData: ServiceInfoModel[] = null;
43 @ViewChild(ContextMenuComponent, {static: false}) public contextMenu: ContextMenuComponent;
45 public contextMenuActions: Array<MenuAction> = [
48 dataTestId: "context-menu-retry",
49 className: "fa-repeat",
50 click: (item: ServiceInfoModel) => this.retryItem(item),
52 visible: (item: ServiceInfoModel) => (item.isRetryEnabled && (item.jobStatus !== JobStatus.COMPLETED_AND_PAUSED)),
56 dataTestId: "context-menu-retry",
57 className: "fa-repeat",
58 click: (item: ServiceInfoModel) => this.resumeItem(item),
60 visible: (item: ServiceInfoModel) => (item.isRetryEnabled && (item.jobStatus === JobStatus.COMPLETED_AND_PAUSED)),
64 dataTestId: "context-menu-open",
65 className: "fa-external-link",
66 click: (item: ServiceInfoModel) => this.openModule(item),
67 enabled: (item: ServiceInfoModel) => this.isOpenEnabled(item),
71 name: "New View/Edit",
72 dataTestId: "context-menu-new-view-edit",
73 className: "fa-pencil",
74 click: (item: ServiceInfoModel) => this.newViewEdit(item),
76 visible: () => this.instantiationStatusComponentService.isNewViewEditVisible(),
79 name: "Create another one",
80 dataTestId: "context-menu-create-another-one",
81 className: "fa-clone",
82 click: (item: ServiceInfoModel) => this.recreateItem(item),
83 enabled: (item: ServiceInfoModel) => this.instantiationStatusComponentService.isRecreateEnabled(item),
84 visible: () => this.instantiationStatusComponentService.isRecreateVisible(),
88 dataTestId: "context-menu-audit-info",
89 className: "fa-info-circle",
90 click: (item: ServiceInfoModel) => this.auditInfo(item),
91 enabled: (item: ServiceInfoModel) => this.isAuditInfoEnabled(item),
96 dataTestId: "context-menu-remove",
97 className: "fa-trash-o",
98 click: (item: ServiceInfoModel) => this.deleteItem(item),
99 enabled: (item: ServiceInfoModel) => this.isDeleteEnabled(item),
103 name: "Hide request",
104 dataTestId: "context-menu-hide",
105 className: "fa-eye-slash",
106 tooltip: "Hide this service from this table",
107 click: (item: ServiceInfoModel) => this.hideItem(item),
108 enabled: (item: ServiceInfoModel) => this.isHideEnabled(item),
115 constructor(private _serviceInfoService: ServiceInfoService,
116 private _instantiationStatusComponentService : InstantiationStatusComponentService,
117 private _contextMenuService: ContextMenuService,
118 private _configurationService : ConfigurationService,
119 private _scrollToService: ScrollToService,
120 private _logService : LogService,
121 private route: ActivatedRoute,
122 private _store: NgRedux<AppState>) {
123 this.instantiationStatusComponentService = _instantiationStatusComponentService;
124 this.configurationService = this._configurationService;
125 this.configurationService.getConfiguration("refreshTimeInstantiationDashboard").subscribe(response => {
126 this.TIMER_TIME_IN_SECONDS = _.isNumber(response) ? response : 0;
127 this.activateInterval();
133 let filterTextParam = this.route.snapshot.queryParams["filterText"];
134 this.filterText = filterTextParam ? filterTextParam : "" ;
138 if (this.TIMER_TIME_IN_SECONDS > 0) {
139 this.timer = setInterval(() => {
141 }, this.TIMER_TIME_IN_SECONDS * 1000);
145 deactivateInterval() {
146 clearInterval(this.timer);
149 openModule(item: ServiceInfoModel){
150 this._store.dispatch(updateServiceInfoModel(item));
151 this.instantiationStatusComponentService.open(item);
154 refreshData(): void {
155 this.dataIsReady = false;
156 this._serviceInfoService.getServicesJobInfo(this.lastUpdatedDate === null)
157 .subscribe((res: ServiceInfoModel[]) => {
158 this._instantiationStatusComponentService.convertObjectToArray(res).subscribe((res) => {
159 this._logService.info('refresh instantiation status table', res);
160 this.dataIsReady = true;
161 this.lastUpdatedDate = new Date();
162 if (!_.isEqual(this.serviceInfoData, res)) {
163 this.serviceInfoData = res;
164 this.scrollToElement(this.findFirstVisibleJob());
170 trackByFn(index: number, item: ServiceInfoModel){
171 return _.isNil(item) ? null : item.jobId;
174 deleteItem(item: ServiceInfoModel): void {
175 this._store.dispatch(updateServiceInfoModel(item));
176 this._serviceInfoService.deleteJob(item.jobId).subscribe(() => {
181 hideItem(item: ServiceInfoModel): void {
182 this._serviceInfoService.hideJob(item.jobId).subscribe(() => {
187 retryItem(item: ServiceInfoModel) : void {
188 this._store.dispatch(updateServiceInfoModel(item));
189 if (item.isRetryEnabled) {
190 this._instantiationStatusComponentService.retry(item);
194 recreateItem(item: ServiceInfoModel){
195 this._store.dispatch(updateServiceInfoModel(item));
196 this.instantiationStatusComponentService.recreate(item)
199 newViewEdit(item: ServiceInfoModel) : void {
200 this._store.dispatch(updateServiceInfoModel(item));
201 this.instantiationStatusComponentService.forwardToNewViewEdit(item)
204 resumeItem(item: ServiceInfoModel) : void {
205 this._store.dispatch(updateServiceInfoModel(item));
206 if(item.isRetryEnabled && item.jobStatus === JobStatus.COMPLETED_AND_PAUSED){
207 this._instantiationStatusComponentService.resume(item);
211 auditInfo(jobData : ServiceInfoModel): void {
212 AuditInfoModalComponent.openModal.next(jobData);
215 isOpenEnabled(item: ServiceInfoModel):boolean {
216 switch(item.action) {
217 case ServiceAction.DELETE:
218 return _.includes([ JobStatus.PENDING, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED, JobStatus.FAILED_AND_PAUSED], item.jobStatus);
219 case ServiceAction.UPDATE:
220 return _.includes([JobStatus.PENDING, JobStatus.PAUSE, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.COMPLETED, JobStatus.FAILED, JobStatus.FAILED_AND_PAUSED], item.jobStatus);
222 return _.includes([JobStatus.COMPLETED, JobStatus.PAUSE, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED_AND_PAUSED], item.jobStatus);
226 isAuditInfoEnabled(item: ServiceInfoModel): boolean {
227 if(item.action === ServiceAction.DELETE || item.action=== ServiceAction.UPDATE) {
228 return _.includes([JobStatus.FAILED, JobStatus.IN_PROGRESS, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED_AND_PAUSED, JobStatus.PAUSE, JobStatus.COMPLETED], item.jobStatus);
230 return true;// ServiceAction.INSTANTIATE
233 isDeleteEnabled(item: ServiceInfoModel):boolean {
234 if( item.action === ServiceAction.DELETE || item.action === ServiceAction.UPDATE){
235 return _.includes([JobStatus.PENDING], item.jobStatus);
237 return _.includes([JobStatus.PENDING, JobStatus.STOPPED], item.jobStatus);
240 isHideEnabled(item: ServiceInfoModel):boolean {
241 return _.includes([JobStatus.COMPLETED, JobStatus.FAILED, JobStatus.STOPPED, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED_AND_PAUSED], item.jobStatus);
244 public onContextMenu($event: MouseEvent, item: any): void {
245 this._contextMenuService.show.next({
246 contextMenu: this.contextMenu,
250 $event.preventDefault();
251 $event.stopPropagation();
254 getImagesSrc(imageName : string) : string {
255 return './' + imageName + '.svg';
258 private getHeaderHeaderClientRect(): ClientRect {
259 const element = document.querySelector("#instantiation-status thead") as HTMLElement;
260 return element.getBoundingClientRect();
263 findFirstVisibleJob(): HTMLElement {
264 const elements : any = document.querySelectorAll('#instantiation-status tr');
265 const headerRect = this.getHeaderHeaderClientRect();
267 const topEdge = headerRect.bottom;
268 for (let i = 0; i < elements.length; i++) {
269 if (elements[i].getBoundingClientRect().top >= topEdge)
276 scrollToElement(currentJob: HTMLElement) {
278 const config: ScrollToConfigOptions = {
281 offset: -1 * (this.getHeaderHeaderClientRect().height + 2),
286 this._scrollToService.scrollTo(config);
291 isInstantiationStatusFilterFlagOn() {
292 return FeatureFlagsService.getFlagState(Features.FLAG_2004_INSTANTIATION_STATUS_FILTER, this._store);