Skip to content
Snippets Groups Projects
execution.component.ts 5.1 KiB
Newer Older
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;

  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 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;
  }

  openWeblogUrl(): void {
    // The base URL opens up to a file navigation URL, that's the default if the service doesn't find a pipeline directory
    let weblogUrl = this.getConfigWebLogBaseUrl() + '/vlass/weblog/' + this.queue.name + '/' + this.job.job_name;

    this.jobsService.getPipelineDir(this.job.job_id).subscribe(response => {
        // Append the pipeline directory and /html to the base weblog URL
        if (response !== null && response.body !== null && response.body !== '') {
          weblogUrl = weblogUrl + '/' + response.body + '/html';
        }
      },
      error => {
        this.alertService.error('Could not find a pipeline dir, using the base weblog URL.');
      },
      () => {
        window.open(weblogUrl, '_blank');
      });
  }

  getJobStatusClass(): string {
      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;
  }