blob: 676c3a4512999f249f13f89a194272f1f0ad46e6 [file] [log] [blame]
import {Component, OnInit, ViewChild} from '@angular/core';
import {ServiceInfoService} from '../shared/server/serviceInfo/serviceInfo.service';
import {ServiceInfoModel} from '../shared/server/serviceInfo/serviceInfo.model';
import {InstantiationStatusComponentService} from './instantiationStatus.component.service';
import {ContextMenuComponent, ContextMenuService} from 'ngx-contextmenu';
import {AuditInfoModalComponent} from "../shared/components/auditInfoModal/auditInfoModal.component";
import * as _ from 'lodash';
import {ScrollToConfigOptions, ScrollToService} from '@nicky-lenaers/ngx-scroll-to';
import {ConfigurationService} from "../shared/services/configuration.service";
import {LogService} from '../shared/utils/log/log.service';
import {AppState} from "../shared/store/reducers";
import {NgRedux} from '@angular-redux/store';
import {JobStatus, ServiceAction} from "../shared/models/serviceInstanceActions";
import {ActivatedRoute} from "@angular/router";
import {FeatureFlagsService, Features} from "../shared/services/featureFlag/feature-flags.service";
export interface MenuAction{
name: string;
dataTestId: string;
className: string;
tooltip?: string;
click(item: ServiceInfoModel): void;
enabled (item?: ServiceInfoModel): boolean;
visible (item?: ServiceInfoModel): boolean;
}
@Component({
selector : 'instantiation-status',
templateUrl : './instantiationStatus.component.html',
styleUrls : ['./instantiationStatus.component.scss']
})
export class InstantiationStatusComponent implements OnInit {
TIMER_TIME_IN_SECONDS : number = 0;
timer = null;
dataIsReady : boolean = false;
scroll : boolean = false;
lastUpdatedDate: Date = null;
instantiationStatusComponentService: InstantiationStatusComponentService;
configurationService : ConfigurationService;
serviceInfoData: ServiceInfoModel[] = null;
@ViewChild(ContextMenuComponent, {static: false}) public contextMenu: ContextMenuComponent;
public contextMenuActions: Array<MenuAction> = [
{
name: "Redeploy",
dataTestId: "context-menu-retry",
className: "fa-repeat",
click: (item: ServiceInfoModel) => this.retryItem(item),
enabled: () => true,
visible: (item: ServiceInfoModel) => (item.isRetryEnabled && (item.jobStatus !== JobStatus.COMPLETED_AND_PAUSED)),
},
{
name: "Resume",
dataTestId: "context-menu-retry",
className: "fa-repeat",
click: (item: ServiceInfoModel) => this.resumeItem(item),
enabled: () => true,
visible: (item: ServiceInfoModel) => (item.isRetryEnabled && (item.jobStatus === JobStatus.COMPLETED_AND_PAUSED)),
},
{
name: "Open",
dataTestId: "context-menu-open",
className: "fa-external-link",
click: (item: ServiceInfoModel) => this.instantiationStatusComponentService.open(item),
enabled: (item: ServiceInfoModel) => this.isOpenEnabled(item),
visible: () => true,
},
{
name: "New View/Edit",
dataTestId: "context-menu-new-view-edit",
className: "fa-pencil",
click: (item: ServiceInfoModel) => this.instantiationStatusComponentService.forwardToNewViewEdit(item),
enabled: () => true,
visible: () => this.instantiationStatusComponentService.isNewViewEditVisible(),
},
{
name: "Create another one",
dataTestId: "context-menu-create-another-one",
className: "fa-clone",
click: (item: ServiceInfoModel) => this.instantiationStatusComponentService.recreate(item),
enabled: (item: ServiceInfoModel) => this.instantiationStatusComponentService.isRecreateEnabled(item),
visible: () => this.instantiationStatusComponentService.isRecreateVisible(),
},
{
name: "Audit info",
dataTestId: "context-menu-audit-info",
className: "fa-info-circle",
click: (item: ServiceInfoModel) => this.auditInfo(item),
enabled: (item: ServiceInfoModel) => this.isAuditInfoEnabled(item),
visible: () => true,
},
{
name: "Delete",
dataTestId: "context-menu-remove",
className: "fa-trash-o",
click: (item: ServiceInfoModel) => this.deleteItem(item),
enabled: (item: ServiceInfoModel) => this.isDeleteEnabled(item),
visible: () => true,
},
{
name: "Hide request",
dataTestId: "context-menu-hide",
className: "fa-eye-slash",
tooltip: "Hide this service from this table",
click: (item: ServiceInfoModel) => this.hideItem(item),
enabled: (item: ServiceInfoModel) => this.isHideEnabled(item),
visible: () => true,
}
];
flags: any;
filterText: string;
constructor(private _serviceInfoService: ServiceInfoService,
private _instantiationStatusComponentService : InstantiationStatusComponentService,
private _contextMenuService: ContextMenuService,
private _configurationService : ConfigurationService,
private _scrollToService: ScrollToService,
private _logService : LogService,
private route: ActivatedRoute,
private _store: NgRedux<AppState>) {
this.instantiationStatusComponentService = _instantiationStatusComponentService;
this.configurationService = this._configurationService;
this.configurationService.getConfiguration("refreshTimeInstantiationDashboard").subscribe(response => {
this.TIMER_TIME_IN_SECONDS = _.isNumber(response) ? response : 0;
this.activateInterval();
this.refreshData();
});
}
ngOnInit() {
let filterTextParam = this.route.snapshot.queryParams["filterText"];
this.filterText = filterTextParam ? filterTextParam : "" ;
}
activateInterval() {
if (this.TIMER_TIME_IN_SECONDS > 0) {
this.timer = setInterval(() => {
this.refreshData();
}, this.TIMER_TIME_IN_SECONDS * 1000);
}
}
deactivateInterval() {
clearInterval(this.timer);
}
refreshData(): void {
this.dataIsReady = false;
this._serviceInfoService.getServicesJobInfo(this.lastUpdatedDate === null)
.subscribe((res: ServiceInfoModel[]) => {
this._instantiationStatusComponentService.convertObjectToArray(res).subscribe((res) => {
this._logService.info('refresh instantiation status table', res);
this.dataIsReady = true;
this.lastUpdatedDate = new Date();
if (!_.isEqual(this.serviceInfoData, res)) {
this.serviceInfoData = res;
this.scrollToElement(this.findFirstVisibleJob());
}
});
})
}
trackByFn(index: number, item: ServiceInfoModel){
return _.isNil(item) ? null : item.jobId;
}
deleteItem(item: ServiceInfoModel): void {
this._serviceInfoService.deleteJob(item.jobId).subscribe(() => {
this.refreshData();
});
}
hideItem(item: ServiceInfoModel): void {
this._serviceInfoService.hideJob(item.jobId).subscribe(() => {
this.refreshData();
});
}
retryItem(item: ServiceInfoModel) : void {
if (item.isRetryEnabled) {
this._instantiationStatusComponentService.retry(item);
}
}
resumeItem(item: ServiceInfoModel) : void {
if(item.isRetryEnabled && item.jobStatus === JobStatus.COMPLETED_AND_PAUSED){
this._instantiationStatusComponentService.resume(item);
}
}
auditInfo(jobData : ServiceInfoModel): void {
AuditInfoModalComponent.openModal.next(jobData);
}
isOpenEnabled(item: ServiceInfoModel):boolean {
switch(item.action) {
case ServiceAction.DELETE:
return _.includes([ JobStatus.PENDING, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED, JobStatus.FAILED_AND_PAUSED], item.jobStatus);
case ServiceAction.UPDATE:
return _.includes([JobStatus.PENDING, JobStatus.PAUSE, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.COMPLETED, JobStatus.FAILED, JobStatus.FAILED_AND_PAUSED], item.jobStatus);
default:
return _.includes([JobStatus.COMPLETED, JobStatus.PAUSE, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED_AND_PAUSED], item.jobStatus);
}
}
isAuditInfoEnabled(item: ServiceInfoModel): boolean {
if(item.action === ServiceAction.DELETE || item.action=== ServiceAction.UPDATE) {
return _.includes([JobStatus.FAILED, JobStatus.IN_PROGRESS, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED_AND_PAUSED, JobStatus.PAUSE, JobStatus.COMPLETED], item.jobStatus);
}
return true;// ServiceAction.INSTANTIATE
}
isDeleteEnabled(item: ServiceInfoModel):boolean {
if( item.action === ServiceAction.DELETE || item.action === ServiceAction.UPDATE){
return _.includes([JobStatus.PENDING], item.jobStatus);
}
return _.includes([JobStatus.PENDING, JobStatus.STOPPED], item.jobStatus);
}
isHideEnabled(item: ServiceInfoModel):boolean {
return _.includes([JobStatus.COMPLETED, JobStatus.FAILED, JobStatus.STOPPED, JobStatus.COMPLETED_WITH_ERRORS, JobStatus.FAILED_AND_PAUSED], item.jobStatus);
}
public onContextMenu($event: MouseEvent, item: any): void {
this._contextMenuService.show.next({
contextMenu: this.contextMenu,
event: $event,
item: item,
});
$event.preventDefault();
$event.stopPropagation();
}
getImagesSrc(imageName : string) : string {
return './' + imageName + '.svg';
}
private getHeaderHeaderClientRect(): ClientRect {
const element = document.querySelector("#instantiation-status thead") as HTMLElement;
return element.getBoundingClientRect();
}
findFirstVisibleJob(): HTMLElement {
const elements : any = document.querySelectorAll('#instantiation-status tr');
const headerRect = this.getHeaderHeaderClientRect();
if (headerRect) {
const topEdge = headerRect.bottom;
for (let i = 0; i < elements.length; i++) {
if (elements[i].getBoundingClientRect().top >= topEdge)
return elements[i];
}
}
return null;
}
scrollToElement(currentJob: HTMLElement) {
if (currentJob) {
const config: ScrollToConfigOptions = {
target: currentJob,
duration: 0,
offset: -1 * (this.getHeaderHeaderClientRect().height + 2),
};
// wait after render
setTimeout(() => {
this._scrollToService.scrollTo(config);
}, 0)
}
}
isInstantiationStatusFilterFlagOn() {
return FeatureFlagsService.getFlagState(Features.FLAG_2004_INSTANTIATION_STATUS_FILTER, this._store);
}
}