import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core'; import {Job, JobQueue} from "../../model/job"; import {verticleSlide} from "../../animations"; import {faCopy, faExclamationTriangle, faExternalLinkAlt} from "@fortawesome/free-solid-svg-icons"; import {ProductsService} from "../../services/products.service"; import {AlertService} from "../../services/alert.service"; import {ConfigurationService} from "../../env/configuration.service"; import {JobsService} from "../../services/jobs.service"; @Component({ selector: 'app-execution-job', templateUrl: './execution.component.html', styleUrls: ['./execution.component.scss'], animations: [verticleSlide] }) export class ExecutionComponent implements OnInit, OnChanges { @Input() job: Job; @Input() queue: JobQueue; @Input() alertThresholdDays: number; @Output() reload = new EventEmitter(); productStatuses: Array<string> = [ 'PROCESSING', 'ERROR', 'QA_READY', 'QA_MANUAL', 'QA_REJECTED', 'QA_ACCEPTED', 'QA_ON_HOLD']; public faCopy = faCopy; public faExternalLinkAlt = faExternalLinkAlt; public detailsExposed: boolean = false; public duration: string = '...'; public faExclamationTriangle = faExclamationTriangle; constructor( private productService: ProductsService, private jobsService: JobsService, private alertService: AlertService, private configService: ConfigurationService, ) { } ngOnInit() { } ngOnChanges(changes: SimpleChanges): void { if (changes.hasOwnProperty('job')) { this.getDuration(); } if (changes.hasOwnProperty('alertThresholdDays')) { } } copyToClipboard(text: string): void { const selBox = document.createElement('textarea'); selBox.style.position = 'fixed'; selBox.style.left = '0'; selBox.style.top = '0'; selBox.style.opacity = '0'; selBox.value = text; document.body.appendChild(selBox); selBox.focus(); selBox.select(); document.execCommand('copy'); document.body.removeChild(selBox); } getConfigRootDataDirectory(): string { return this.configService.config.rootDataDirectory; } getConfigWebLogBaseUrl(): string { return this.configService.config.weblogbaseurl; } getJobStatusClass(): string { switch (this.job.job_status) { case 'ERROR': return 'btn-danger'; case 'QA_REJECTED': return 'btn-secondary'; case 'PROCESSING': return 'btn-primary'; case 'QA_READY': return 'btn-success'; case 'QA_ACCEPTED': return 'btn-info'; case 'QA_MANUAL': return 'btn-warning'; default: return 'btn-outline-info'; } } getArchiveStatusClass(): string { switch (this.job.job_arch_status) { case 'ARCHIVED': return 'badge-dark'; case 'ARCHIVE-ERROR': return 'badge-error'; default: return 'badge-light border'; } } showWarning(job: Job): boolean { if (job.jobspec_status === 'PROCESSING') { let start_date = new Date(job.job_starttime); let current_date = new Date(); let diffInDays = (current_date.getTime() - start_date.getTime()) / (1000 * 60 * 60 * 24); if (diffInDays >= this.alertThresholdDays) { return true; } } return false; } updateStatus(status: string): void { if (status.toLowerCase() !== this.job.jobspec_status.toLowerCase()) { this.jobsService.updateJobStatus(this.job.job_id, status).subscribe(response => { this.job.jobspec_status = response; this.alertService.success('Status Updated'); }); } } getDuration(): void { let dur = ''; let diff = this.job.job_endtime ? this.job.job_endtime - this.job.job_starttime : Date.now() - this.job.job_starttime; const weeksDiff = Math.floor(diff / 1000 / 60 / 60 / 24 / 7); diff -= weeksDiff * 1000 * 60 * 60 * 24 * 7; dur += weeksDiff > 0 ? weeksDiff + 'w ' : ''; const daysDiff = Math.floor(diff / 1000 / 60 / 60 / 24); diff -= daysDiff * 1000 * 60 * 60 * 24; dur += daysDiff > 0 ? daysDiff + 'd ' : ''; const hoursDiff = Math.floor(diff / 1000 / 60 / 60); diff -= hoursDiff * 1000 * 60 * 60; dur += hoursDiff > 0 ? hoursDiff + 'h ' : ''; const minutesDiff = Math.floor(diff / 1000 / 60); dur += minutesDiff > 0 ? minutesDiff + 'm ' : ''; this.duration = dur; } }