@versatiledatakit/data-pipelines
Version:
Data Pipelines help Data Engineers develop, deploy, run, and manage data processing workloads (called 'Data Job')
641 lines • 120 kB
JavaScript
/*
* Copyright 2023-2025 Broadcom
* SPDX-License-Identifier: Apache-2.0
*/
/* eslint-disable @typescript-eslint/member-ordering */
import { Component, Inject } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { concatMap, interval, of, Subject, timer } from 'rxjs';
import { catchError, filter, finalize, map, switchMap, take, takeUntil, takeWhile, tap } from 'rxjs/operators';
import { ClrLoadingState } from '@clr/angular';
import * as fileSaver from 'file-saver';
import { ASC, CollectionsUtil, TaurusBaseComponent, VmwToastType } from '@versatiledatakit/shared';
import { DataJobUtil, ErrorUtil } from '../../shared/utils';
import { ExtractJobStatusPipe } from '../../shared/pipes';
import { ConfirmationModalOptions, DeleteModalOptions } from '../../shared/model';
import { DATA_PIPELINES_CONFIGS, DataJobStatus, ToastDefinitions } from '../../model';
import * as i0 from "@angular/core";
import * as i1 from "@versatiledatakit/shared";
import * as i2 from "@angular/router";
import * as i3 from "../../services";
import * as i4 from "@angular/common";
import * as i5 from "@clr/angular";
import * as i6 from "../../shared/components/delete-modal/delete-modal.component";
import * as i7 from "../../shared/components/confirmation-dialog-modal/confirmation-dialog-modal.component";
function DataJobPageComponent_div_3_Template(rf, ctx) { if (rf & 1) {
const _r8 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "div", 14)(1, "h2", 15)(2, "a", 16);
i0.ɵɵlistener("click", function DataJobPageComponent_div_3_Template_a_click_2_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r7 = i0.ɵɵnextContext(); return ctx_r7.doNavigateBack($event); });
i0.ɵɵelement(3, "clr-icon", 17);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(4, "span", 18)(5, "strong");
i0.ɵɵtext(6, "Data Job:");
i0.ɵɵelementEnd();
i0.ɵɵtext(7);
i0.ɵɵelementEnd()()();
} if (rf & 2) {
const ctx_r0 = i0.ɵɵnextContext();
i0.ɵɵadvance(7);
i0.ɵɵtextInterpolate1(" ", ctx_r0.jobName, "");
} }
function DataJobPageComponent_ng_template_4_Template(rf, ctx) { if (rf & 1) {
const _r10 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "div", 19)(1, "h1", 20)(2, "a", 16);
i0.ɵɵlistener("click", function DataJobPageComponent_ng_template_4_Template_a_click_2_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r9 = i0.ɵɵnextContext(); return ctx_r9.doNavigateBack($event); });
i0.ɵɵelement(3, "clr-icon", 17);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(4, "span");
i0.ɵɵtext(5);
i0.ɵɵelementEnd()()();
} if (rf & 2) {
const ctx_r2 = i0.ɵɵnextContext();
i0.ɵɵadvance(5);
i0.ɵɵtextInterpolate1("Data Job: ", ctx_r2.jobName, "");
} }
function DataJobPageComponent_div_6_button_1_Template(rf, ctx) { if (rf & 1) {
const _r15 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "button", 25);
i0.ɵɵlistener("click", function DataJobPageComponent_div_6_button_1_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r14 = i0.ɵɵnextContext(2); return ctx_r14.cancelExecution(); });
i0.ɵɵtext(1, " Cancel Execution ");
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r11 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("clrLoading", ctx_r11.stopButtonsState)("disabled", ctx_r11.cancelDataJobDisabled);
} }
function DataJobPageComponent_div_6_button_2_Template(rf, ctx) { if (rf & 1) {
const _r17 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "button", 26);
i0.ɵɵlistener("click", function DataJobPageComponent_div_6_button_2_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r16 = i0.ɵɵnextContext(2); return ctx_r16.executeJob(); });
i0.ɵɵtext(1, " Execute ");
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r12 = i0.ɵɵnextContext(2);
i0.ɵɵproperty("disabled", !ctx_r12.areJobExecutionsLoaded || ctx_r12.loadingInProgress || ctx_r12.isExecutionInProgress())("clrLoading", ctx_r12.executeButtonsState);
} }
function DataJobPageComponent_div_6_clr_dropdown_3_button_5_Template(rf, ctx) { if (rf & 1) {
const _r20 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "button", 32);
i0.ɵɵlistener("click", function DataJobPageComponent_div_6_clr_dropdown_3_button_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r19 = i0.ɵɵnextContext(3); return ctx_r19.downloadJobKey(); });
i0.ɵɵtext(1, " Download key ");
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r18 = i0.ɵɵnextContext(3);
i0.ɵɵproperty("disabled", ctx_r18.loadingInProgress)("clrLoading", ctx_r18.downloadButtonsState);
} }
function DataJobPageComponent_div_6_clr_dropdown_3_Template(rf, ctx) { if (rf & 1) {
const _r22 = i0.ɵɵgetCurrentView();
i0.ɵɵelementStart(0, "clr-dropdown")(1, "button", 27);
i0.ɵɵtext(2, " Actions ");
i0.ɵɵelement(3, "clr-icon", 28);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(4, "clr-dropdown-menu", 29);
i0.ɵɵtemplate(5, DataJobPageComponent_div_6_clr_dropdown_3_button_5_Template, 2, 2, "button", 30);
i0.ɵɵelementStart(6, "button", 31);
i0.ɵɵlistener("click", function DataJobPageComponent_div_6_clr_dropdown_3_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r22); const ctx_r21 = i0.ɵɵnextContext(2); return ctx_r21.removeJob(); });
i0.ɵɵtext(7, " Delete ");
i0.ɵɵelementEnd()()();
} if (rf & 2) {
const ctx_r13 = i0.ɵɵnextContext(2);
i0.ɵɵadvance(3);
i0.ɵɵattribute("size", 15);
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", ctx_r13.isDownloadJobKeyAllowed);
i0.ɵɵadvance(1);
i0.ɵɵproperty("disabled", !ctx_r13.areJobExecutionsLoaded || ctx_r13.loadingInProgress || ctx_r13.isExecutionInProgress())("clrLoading", ctx_r13.deleteButtonsState);
} }
function DataJobPageComponent_div_6_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "div", 21);
i0.ɵɵtemplate(1, DataJobPageComponent_div_6_button_1_Template, 2, 2, "button", 22);
i0.ɵɵtemplate(2, DataJobPageComponent_div_6_button_2_Template, 2, 2, "button", 23);
i0.ɵɵtemplate(3, DataJobPageComponent_div_6_clr_dropdown_3_Template, 8, 4, "clr-dropdown", 24);
i0.ɵɵelementEnd();
} if (rf & 2) {
const ctx_r3 = i0.ɵɵnextContext();
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r3.isDataJobRunning && ctx_r3.isJobWithRunningStatus());
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r3.isJobAvailable && ctx_r3.isExecuteJobAllowed && !ctx_r3.isDataJobRunning);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx_r3.isJobAvailable);
} }
const _c0 = function () { return ["executions"]; };
function DataJobPageComponent_li_15_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "li", 9)(1, "a", 33, 34);
i0.ɵɵtext(3, "Executions");
i0.ɵɵelementEnd()();
} if (rf & 2) {
const _r23 = i0.ɵɵreference(2);
const ctx_r5 = i0.ɵɵnextContext();
i0.ɵɵadvance(1);
i0.ɵɵproperty("routerLink", i0.ɵɵpureFunction0(3, _c0))("queryParams", ctx_r5.queryParams);
i0.ɵɵattribute("aria-selected", _r23.isActive);
} }
const _c1 = function () { return ["lineage"]; };
function DataJobPageComponent_li_16_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "li", 9)(1, "a", 35, 36);
i0.ɵɵtext(3, "Lineage ");
i0.ɵɵelement(4, "clr-icon", 37);
i0.ɵɵelementEnd()();
} if (rf & 2) {
const _r24 = i0.ɵɵreference(2);
const ctx_r6 = i0.ɵɵnextContext();
i0.ɵɵadvance(1);
i0.ɵɵproperty("routerLink", i0.ɵɵpureFunction0(3, _c1))("queryParams", ctx_r6.queryParams);
i0.ɵɵattribute("aria-selected", _r24.isActive);
} }
const _c2 = function (a0) { return { "data-pipelines-job__actions--margin-0": a0 }; };
const _c3 = function () { return ["details"]; };
var TypeButtonState;
(function (TypeButtonState) {
/* eslint-disable-next-line @typescript-eslint/naming-convention */
TypeButtonState[TypeButtonState["DOWNLOAD"] = 0] = "DOWNLOAD";
/* eslint-disable-next-line @typescript-eslint/naming-convention */
TypeButtonState[TypeButtonState["EXECUTE"] = 1] = "EXECUTE";
/* eslint-disable-next-line @typescript-eslint/naming-convention */
TypeButtonState[TypeButtonState["DELETE"] = 2] = "DELETE";
/* eslint-disabe-next-line @typescript-eslint/naming-convention */
TypeButtonState[TypeButtonState["STOP"] = 3] = "STOP";
})(TypeButtonState || (TypeButtonState = {}));
export class DataJobPageComponent extends TaurusBaseComponent {
constructor(componentService, navigationService, activatedRoute, routerService, dataJobsService, dataJobsApiService, toastService, errorHandlerService, dataPipelinesModuleConfig) {
super(componentService, navigationService, activatedRoute);
this.routerService = routerService;
this.dataJobsService = dataJobsService;
this.dataJobsApiService = dataJobsApiService;
this.toastService = toastService;
this.errorHandlerService = errorHandlerService;
this.dataPipelinesModuleConfig = dataPipelinesModuleConfig;
this.uuid = 'DataJobPageComponent';
this.teamName = '';
this.jobName = '';
this.isDataJobRunning = false;
this.cancelDataJobDisabled = false;
this.queryParams = {};
this.isSubpageNavigation = false;
this.isJobAvailable = false;
this.isJobEditable = false;
this.isExecuteJobAllowed = false;
this.isDownloadJobKeyAllowed = false;
this.areJobExecutionsLoaded = false;
this.loadingInProgress = false;
this.jobExecutions = [];
this.jobDeployments = [];
this.deleteButtonsState = ClrLoadingState.DEFAULT;
this.executeButtonsState = ClrLoadingState.DEFAULT;
this.downloadButtonsState = ClrLoadingState.DEFAULT;
this.stopButtonsState = ClrLoadingState.DEFAULT;
this._nonExistingJobMsgShowed = false;
this.isSubpageNavigation = !!activatedRoute.snapshot.data['activateSubpageNavigation'];
this.deleteOptions = new DeleteModalOptions();
this.executeNowOptions = new ConfirmationModalOptions();
this.cancelNowOptions = new ConfirmationModalOptions();
}
/**
* ** Navigate back leveraging provided router config.
*/
doNavigateBack($event) {
$event?.preventDefault();
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.navigateBack({ '$.team': this.teamName }).then();
}
/**
* ** Returns if execution is in progress.
*/
isExecutionInProgress() {
return DataJobUtil.isJobRunning(this.jobExecutions);
}
/**
* ** Show confirmation dialog for Job execution.
*/
executeJob() {
this.executeNowOptions.title = `Execute ${this.jobName} now?`;
this.executeNowOptions.message = `Job <strong>${this.jobName}</strong> will be queued for execution.`;
this.executeNowOptions.infoText = `Confirming will result in immediate data job execution.`;
this.executeNowOptions.opened = true;
}
/**
* ** On User confirm continue with Job execution.
*/
confirmExecuteJob() {
this._submitOperationStarted(TypeButtonState.EXECUTE);
this.subscriptions.push(this.dataJobsApiService
.executeDataJob(this.teamName, this.jobName, this._extractJobDeployment()?.id)
.pipe(finalize(() => {
this._submitOperationEnded();
}))
.subscribe({
next: () => {
this.toastService.show(ToastDefinitions.successfullyRanJob(this.jobName));
let previousReqFinished = true;
this.areJobExecutionsLoaded = false;
this.subscriptions.push(interval(1250) // Send polling request on every 1.25s until execution is accepted from backend
.pipe(
// eslint-disable-next-line rxjs/no-unsafe-takeuntil
takeUntil(timer(30000)), // Timer limit when polling to stop = 30s
filter(() => previousReqFinished), tap(() => (previousReqFinished = false)), switchMap(() => this.dataJobsApiService
.getJobExecutions(this.teamName, this.jobName, true, null, {
property: 'startTime',
direction: ASC
})
.pipe(catchError((error) => {
this.errorHandlerService.processError(ErrorUtil.extractError(error));
return of([]);
}), finalize(() => {
previousReqFinished = true;
}))), map((executions) => (executions.content ? [...executions.content] : [])), takeWhile((executions) => {
if (CollectionsUtil.isArrayEmpty(executions) || executions.length <= this.jobExecutions.length) {
return true;
}
this.jobExecutions = executions;
this.areJobExecutionsLoaded = true;
const lastExecution = executions[executions.length - 1];
if (!DataJobUtil.isJobRunningPredicate(lastExecution)) {
return true;
}
this.dataJobsService.notifyForJobExecutions(executions);
this.dataJobsService.notifyForRunningJobExecutionId(lastExecution.id);
return false; // Stop polling if above condition is met.
}))
.subscribe() // eslint-disable-line rxjs/no-nested-subscribe
);
},
error: (error) => {
this.errorHandlerService.processError(ErrorUtil.extractError(error), {
title: error?.status === 409
? 'Failed, Data job is already executing'
: 'Failed to queue Data job for execution'
});
}
}));
}
/**
* ** Download Job key.
*/
downloadJobKey() {
this._submitOperationStarted(TypeButtonState.DOWNLOAD);
this.dataJobsApiService
.downloadFile(this.teamName, this.jobName)
.pipe(finalize(() => {
this._submitOperationEnded();
}))
.subscribe({
next: (response) => {
const blob = new Blob([response], {
type: 'application/octet-stream'
});
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
fileSaver.saveAs(blob, `${this.jobName}.keytab`);
this.toastService.show({
type: VmwToastType.INFO,
title: `Download completed`,
description: `Data job keytab "${this.jobName}.keytab" successfully downloaded`
});
},
error: (error) => {
const errorDescription = error?.status === 404
? `Download failed. Keytab file doesn't exist for this job.`
: `Download failed. Keytab file failed to download.`;
this.errorHandlerService.processError(ErrorUtil.extractError(error), {
description: errorDescription
});
}
});
}
/**
* ** Show confirmation dialog for Job Remove (Delete).
*/
removeJob() {
this.deleteOptions.message = `Job <strong>${this.jobName}</strong> will be deleted.
Currently executing Data Jobs will be left to finish but the credentials will be revoked.`;
this.deleteOptions.infoText = `Deleting this job means that <strong> it will be permanently removed from the system</strong>
including all its state (properties), source code and any deployments.`;
this.deleteOptions.showOkBtn = true;
this.deleteOptions.cancelBtn = 'Cancel';
this.deleteOptions.opened = true;
}
/**
* ** On User confirm continue with Job Remove (Delete).
*/
confirmRemoveJob() {
this._submitOperationStarted(TypeButtonState.DELETE);
this.dataJobsApiService
.removeJob(this.teamName, this.jobName)
.pipe(finalize(() => {
this._submitOperationEnded();
}))
.subscribe({
next: () => {
this.toastService.show({
type: VmwToastType.INFO,
title: `Data job delete completed`,
description: `Data job "${this.jobName}" successfully deleted`
});
this.doNavigateBack();
},
error: (error) => {
this.errorHandlerService.processError(ErrorUtil.extractError(error), {
title: `Data job delete failed`
});
}
});
}
confirmCancelDataJob() {
this._submitOperationStarted(TypeButtonState.STOP);
this.dataJobsApiService
.cancelDataJobExecution(this.teamName, this.jobName, this.lastExecution()?.id)
.pipe(finalize(() => {
this._submitOperationEnded();
}))
.subscribe({
next: () => {
this.cancelDataJobDisabled = true;
this.toastService.show({
type: VmwToastType.INFO,
title: `Data job execution cancellation completed`,
description: `Data job "${this.jobName}" successfully canceled`
});
},
error: (error) => {
this.errorHandlerService.processError(ErrorUtil.extractError(error), {
title: `Data job cancellation failed`
});
}
});
}
/**
* ** Show confirmation dialog for Job execution cancellation.
*/
cancelExecution() {
this.cancelNowOptions.title = `Cancel ${this.lastExecution()?.id} now?`;
this.cancelNowOptions.message = `Execution <strong>${this.lastExecution()?.id}</strong> will be canceled.`;
this.cancelNowOptions.infoText = `Confirming will result in immediate data job execution cancellation.`;
this.cancelNowOptions.opened = true;
}
lastExecution() {
return this.jobExecutions[this.jobExecutions.length - 1];
}
isJobWithRunningStatus() {
return this.lastExecution().status === 'RUNNING';
}
/**
* @inheritDoc
*/
onModelInit() {
this.routerService
.getState()
.pipe(take(1))
.subscribe((state) => this._initialize(state));
}
/**
* @inheritDoc
*/
onModelError(model, _task, newErrorRecords) {
newErrorRecords.forEach((errorRecord) => {
const error = ErrorUtil.extractError(errorRecord.error);
this.errorHandlerService.processError(error);
});
}
_initialize(state) {
const teamParamKey = state.getData('teamParamKey');
this.teamName = state.getParam(teamParamKey);
if (CollectionsUtil.isNil(teamParamKey) || CollectionsUtil.isNil(this.teamName)) {
this._subscribeForImplicitTeam();
}
const jobParamKey = state.getData('jobParamKey');
this.jobName = state.getParam(jobParamKey);
this.isJobEditable = !!state.getData('editable');
this.queryParams = state.queryParams;
this.isDownloadJobKeyAllowed = this.dataPipelinesModuleConfig.manageConfig?.allowKeyTabDownloads && this.isJobEditable;
this._subscribeForTeamChange(state);
this._subscribeForExecutionsChange();
this._subscribeForExecutionIdChange();
this._loadJobDetails();
this._loadJobExecutions();
}
_subscribeForImplicitTeam() {
this.dataJobsService
.getNotifiedForTeamImplicitly()
.pipe(take(1))
.subscribe((teamName) => (this.teamName = teamName));
}
_subscribeForTeamChange(state) {
const shouldActivateListener = !!state.getData('activateListenerForTeamChange');
if (shouldActivateListener && this.dataPipelinesModuleConfig?.manageConfig?.selectedTeamNameObservable) {
this.subscriptions.push(this.dataPipelinesModuleConfig.manageConfig.selectedTeamNameObservable.subscribe((newTeam) => {
if (this.teamName !== newTeam) {
this.teamName = newTeam;
this.doNavigateBack();
}
}));
}
}
_subscribeForExecutionsChange() {
this.subscriptions.push(this.dataJobsService.getNotifiedForJobExecutions().subscribe((executions) => {
this.jobExecutions = [...executions];
}));
}
_subscribeForExecutionIdChange() {
const scheduleLastExecutionPolling = new Subject();
this.subscriptions.push(scheduleLastExecutionPolling
.pipe(switchMap((id) => interval(5000).pipe(switchMap(() => this.dataJobsApiService.getJobExecution(this.teamName, this.jobName, id).pipe(map((execution) => {
return {
execution,
error: null
};
}), catchError((error) => {
this.errorHandlerService.processError(ErrorUtil.extractError(error));
return of({
execution: null,
error: error
});
}))), tap((data) => this._replaceRunningExecutionAndNotify(data.execution)), takeWhile((data) => {
if (data.error instanceof HttpErrorResponse) {
if (data.error.status === 404 || data.error.status >= 500) {
this.isDataJobRunning = false;
return false;
}
}
const isRunning = CollectionsUtil.isNil(data.execution) || DataJobUtil.isJobRunningPredicate(data.execution);
if (!isRunning) {
this.isDataJobRunning = false;
}
return isRunning;
}))))
.subscribe());
this.subscriptions.push(this.dataJobsService
.getNotifiedForRunningJobExecutionId()
.pipe(concatMap((executionId) => this.dataJobsApiService.getJobExecution(this.teamName, this.jobName, executionId).pipe(map((executionDetails) => [executionId, executionDetails]), catchError((error) => {
this.errorHandlerService.processError(ErrorUtil.extractError(error));
return of([executionId]);
}))))
.subscribe(([executionId, executionDetails]) => {
this.isDataJobRunning = true;
this.cancelDataJobDisabled = false;
this._replaceRunningExecutionAndNotify(executionDetails);
scheduleLastExecutionPolling.next(executionId);
}));
}
_loadJobDetails() {
this.subscriptions.push(this.dataJobsApiService.getJobDetails(this.teamName, this.jobName).subscribe({
error: (error) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 404) {
this._showMessageJobNotExist();
this.doNavigateBack();
}
console.error('Error loading jobDetails', error);
}
}
}));
this.subscriptions.push(this.dataJobsApiService.getJob(this.teamName, this.jobName).subscribe({
next: (job) => {
if (CollectionsUtil.isDefined(job)) {
this.isJobAvailable = true;
this.jobDeployments = job.deployments;
this.isExecuteJobAllowed = ExtractJobStatusPipe.transform(this.jobDeployments) !== DataJobStatus.NOT_DEPLOYED;
return;
}
this._showMessageJobNotExist();
this.doNavigateBack();
},
error: (error) => {
this.errorHandlerService.processError(ErrorUtil.extractError(error), {
title: `Loading Data job "${this.jobName}" failed`
});
}
}));
}
_loadJobExecutions() {
this.subscriptions.push(this.dataJobsApiService
.getJobExecutions(this.teamName, this.jobName, true, null, {
property: 'startTime',
direction: ASC
})
.subscribe({
next: (value) => {
if (value?.content) {
this.dataJobsService.notifyForJobExecutions([...value.content]);
// eslint-disable-next-line @typescript-eslint/unbound-method
const runningExecution = value.content.find(DataJobUtil.isJobRunningPredicate);
if (runningExecution) {
this.dataJobsService.notifyForRunningJobExecutionId(runningExecution.id);
}
}
this.areJobExecutionsLoaded = true;
},
error: (error) => {
this.errorHandlerService.processError(ErrorUtil.extractError(error));
}
}));
}
_replaceRunningExecutionAndNotify(executionDetails) {
if (CollectionsUtil.isNil(executionDetails)) {
return;
}
const convertedExecution = DataJobUtil.convertFromExecutionDetailsToExecutionState(executionDetails);
const foundIndex = this.jobExecutions.findIndex((ex) => ex.id === convertedExecution.id);
if (foundIndex !== -1) {
this.jobExecutions.splice(foundIndex, 1, convertedExecution);
}
else {
this.jobExecutions.push(convertedExecution);
}
this.dataJobsService.notifyForJobExecutions(this.jobExecutions);
}
_submitOperationStarted(type) {
switch (type) {
case TypeButtonState.DELETE:
this.deleteButtonsState = ClrLoadingState.LOADING;
break;
case TypeButtonState.DOWNLOAD:
this.downloadButtonsState = ClrLoadingState.LOADING;
break;
case TypeButtonState.EXECUTE:
this.executeButtonsState = ClrLoadingState.LOADING;
break;
case TypeButtonState.STOP:
this.stopButtonsState = ClrLoadingState.LOADING;
break;
}
this.loadingInProgress = true;
}
_submitOperationEnded() {
this.deleteButtonsState = ClrLoadingState.DEFAULT;
this.downloadButtonsState = ClrLoadingState.DEFAULT;
this.executeButtonsState = ClrLoadingState.DEFAULT;
this.stopButtonsState = ClrLoadingState.DEFAULT;
this.loadingInProgress = false;
}
_extractJobDeployment() {
if (!this.jobDeployments) {
return null;
}
return this.jobDeployments[this.jobDeployments.length - 1];
}
_showMessageJobNotExist() {
if (!this._nonExistingJobMsgShowed) {
this._nonExistingJobMsgShowed = true;
this.toastService.show({
type: VmwToastType.FAILURE,
title: `Job "${this.jobName}" doesn't exist`,
description: `Data Job "${this.jobName}" for Team "${this.teamName}" doesn't exist, will load Data Jobs list`
});
}
}
}
DataJobPageComponent.ɵfac = function DataJobPageComponent_Factory(t) { return new (t || DataJobPageComponent)(i0.ɵɵdirectiveInject(i1.ComponentService), i0.ɵɵdirectiveInject(i1.NavigationService), i0.ɵɵdirectiveInject(i2.ActivatedRoute), i0.ɵɵdirectiveInject(i1.RouterService), i0.ɵɵdirectiveInject(i3.DataJobsService), i0.ɵɵdirectiveInject(i3.DataJobsApiService), i0.ɵɵdirectiveInject(i1.ToastService), i0.ɵɵdirectiveInject(i1.ErrorHandlerService), i0.ɵɵdirectiveInject(DATA_PIPELINES_CONFIGS)); };
DataJobPageComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: DataJobPageComponent, selectors: [["lib-data-job-page"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 19, vars: 15, consts: [["id", "data-job-page", "data-cy", "data-pipelines-job-page", 1, "page-container", "data-pipelines-job__page"], [1, "data-pipelines-job__actions", 3, "ngClass"], [1, "data-pipelines-job__actions-left"], ["class", "data-pipelines-job__subpage-navigation", 4, "ngIf", "ngIfElse"], ["rootPageNavigation", ""], ["class", "data-pipelines-job__actions-right", "data-cy", "data-pipelines-job-actions-container", 4, "ngIf"], [3, "options", "delete"], [3, "options", "changeStatus"], ["role", "tablist", "aria-owns", "dataPipelinesJobDetails dataPipelinesJobExecutions dataPipelinesJobLineage", 1, "nav", "data-pipelines-job__tabs-navigation"], ["role", "presentation", 1, "nav-item"], ["id", "dataPipelinesJobDetails", "role", "tab", "aria-hidden", "false", "data-cy", "data-pipelines-job-details-tab", "routerLinkActive", "active", 1, "nav-link", 3, "routerLink", "queryParams"], ["detailsLink", "routerLinkActive"], ["role", "presentation", "class", "nav-item", 4, "ngIf"], [1, "data-pipelines-job__router-outlet-container"], [1, "data-pipelines-job__subpage-navigation"], ["data-cy", "data-pipelines-job-main-title", 1, "m-0", "page-title"], ["href", "javascript:;", "data-cy", "data-pipelines-job-navigate-back", 1, "label-link", "data-pipelines-job__navigate-back", 3, "click"], ["shape", "redo", "flip", "horizontal", "size", "25", "role", "none", 1, "redo-icon"], ["data-cy", "dp-main-title"], [1, "data-pipelines-job__root-page-navigation"], ["data-cy", "data-pipelines-page-title", 1, "m-0", "page-title"], ["data-cy", "data-pipelines-job-actions-container", 1, "data-pipelines-job__actions-right"], ["class", "btn btn-secondary", "data-cy", "data-pipelines-job-cancel-execution-btn", 3, "clrLoading", "disabled", "click", 4, "ngIf"], ["class", "btn btn-secondary", "data-cy", "data-pipelines-job-execute-btn", "aria-label", "Execute now", 3, "disabled", "clrLoading", "click", 4, "ngIf"], [4, "ngIf"], ["data-cy", "data-pipelines-job-cancel-execution-btn", 1, "btn", "btn-secondary", 3, "clrLoading", "disabled", "click"], ["data-cy", "data-pipelines-job-execute-btn", "aria-label", "Execute now", 1, "btn", "btn-secondary", 3, "disabled", "clrLoading", "click"], ["clrDropdownTrigger", "", "data-cy", "data-pipelines-job-action-dropdown-btn", 1, "btn", "btn-secondary", "data-pipelines-job__action-dropdown-trigger"], ["title", "Actions", "shape", "caret"], ["clrPosition", "bottom-right"], ["clrDropdownItem", "", "class", "btn btn-secondary", "aria-label", "Download Key", "data-cy", "data-pipelines-job-download-btn", 3, "disabled", "clrLoading", "click", 4, "ngIf"], ["clrDropdownItem", "", "aria-label", "Delete Job", "data-cy", "data-pipelines-job-delete-btn", 1, "btn", "btn-secondary", 3, "disabled", "clrLoading", "click"], ["clrDropdownItem", "", "aria-label", "Download Key", "data-cy", "data-pipelines-job-download-btn", 1, "btn", "btn-secondary", 3, "disabled", "clrLoading", "click"], ["id", "dataPipelinesJobExecutions", "role", "tab", "aria-hidden", "false", "data-cy", "data-pipelines-job-executions-tab", "routerLinkActive", "active", 1, "nav-link", 3, "routerLink", "queryParams"], ["executionsLink", "routerLinkActive"], ["id", "dataPipelinesJobLineage", "role", "tab", "aria-hidden", "false", "data-cy", "data-pipelines-job-lineage-tab", "routerLinkActive", "active", 1, "nav-link", 3, "routerLink", "queryParams"], ["lineage", "routerLinkActive"], ["shape", "beta", 1, "beta-icon"]], template: function DataJobPageComponent_Template(rf, ctx) { if (rf & 1) {
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
i0.ɵɵtemplate(3, DataJobPageComponent_div_3_Template, 8, 1, "div", 3);
i0.ɵɵtemplate(4, DataJobPageComponent_ng_template_4_Template, 6, 1, "ng-template", null, 4, i0.ɵɵtemplateRefExtractor);
i0.ɵɵelementEnd();
i0.ɵɵtemplate(6, DataJobPageComponent_div_6_Template, 4, 3, "div", 5);
i0.ɵɵelementStart(7, "lib-delete-modal", 6);
i0.ɵɵlistener("delete", function DataJobPageComponent_Template_lib_delete_modal_delete_7_listener() { return ctx.confirmRemoveJob(); });
i0.ɵɵelementEnd();
i0.ɵɵelementStart(8, "lib-confirmation-dialog-modal", 7);
i0.ɵɵlistener("changeStatus", function DataJobPageComponent_Template_lib_confirmation_dialog_modal_changeStatus_8_listener() { return ctx.confirmExecuteJob(); });
i0.ɵɵelementEnd();
i0.ɵɵelementStart(9, "lib-confirmation-dialog-modal", 7);
i0.ɵɵlistener("changeStatus", function DataJobPageComponent_Template_lib_confirmation_dialog_modal_changeStatus_9_listener() { return ctx.confirmCancelDataJob(); });
i0.ɵɵelementEnd()();
i0.ɵɵelementStart(10, "ul", 8)(11, "li", 9)(12, "a", 10, 11);
i0.ɵɵtext(14, "Details");
i0.ɵɵelementEnd()();
i0.ɵɵtemplate(15, DataJobPageComponent_li_15_Template, 4, 4, "li", 12);
i0.ɵɵtemplate(16, DataJobPageComponent_li_16_Template, 5, 4, "li", 12);
i0.ɵɵelementEnd();
i0.ɵɵelementStart(17, "div", 13);
i0.ɵɵelement(18, "router-outlet");
i0.ɵɵelementEnd()();
} if (rf & 2) {
const _r1 = i0.ɵɵreference(5);
const _r4 = i0.ɵɵreference(13);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(12, _c2, !ctx.isSubpageNavigation));
i0.ɵɵadvance(2);
i0.ɵɵproperty("ngIf", ctx.isSubpageNavigation)("ngIfElse", _r1);
i0.ɵɵadvance(3);
i0.ɵɵproperty("ngIf", ctx.isJobEditable);
i0.ɵɵadvance(1);
i0.ɵɵproperty("options", ctx.deleteOptions);
i0.ɵɵadvance(1);
i0.ɵɵproperty("options", ctx.executeNowOptions);
i0.ɵɵadvance(1);
i0.ɵɵproperty("options", ctx.cancelNowOptions);
i0.ɵɵadvance(3);
i0.ɵɵproperty("routerLink", i0.ɵɵpureFunction0(14, _c3))("queryParams", ctx.queryParams);
i0.ɵɵattribute("aria-selected", _r4.isActive);
i0.ɵɵadvance(3);
i0.ɵɵproperty("ngIf", ctx.dataPipelinesModuleConfig.showExecutionsPage && ctx.isJobEditable);
i0.ɵɵadvance(1);
i0.ɵɵproperty("ngIf", ctx.dataPipelinesModuleConfig.showLineagePage);
} }, directives: [i4.NgClass, i4.NgIf, i5.ClrIconCustomTag, i5.ClrLoadingButton, i5.ClrLoading, i5.ClrDropdown, i5.ClrDropdownTrigger, i5.ClrDropdownMenu, i5.ClrDropdownItem, i6.DeleteModalComponent, i7.ConfirmationDialogModalComponent, i2.RouterLinkWithHref, i2.RouterLinkActive, i2.RouterOutlet], styles: ["hr[_ngcontent-%COMP%]{border:0;height:1px;background:#8f9ba3}.label-link[_ngcontent-%COMP%]{cursor:pointer}.label-link-suppress-decoration[_ngcontent-%COMP%]:hover{text-decoration:none}.status-icon-enabled[_ngcontent-%COMP%]{color:#5aa220}.clr-col-6[_ngcontent-%COMP%]{border-right:1px solid #999999}.loading-spinner[_ngcontent-%COMP%]{margin-left:45%;margin-top:100px}[_nghost-%COMP%]{display:flex;flex-direction:column;flex:1 1 auto;height:100%}.data-pipelines-job__page[_ngcontent-%COMP%]{display:flex;flex-direction:column;flex:1 1 auto}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%]{display:inline-flex;margin-top:.8rem}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .data-pipelines-job__actions-right[_ngcontent-%COMP%]{margin-left:auto}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .data-pipelines-job__actions-right[_ngcontent-%COMP%] clr-dropdown[_ngcontent-%COMP%]{margin-top:var(--clr-btn-vertical-margin, .3rem);margin-bottom:var(--clr-btn-vertical-margin, .3rem);margin-left:0}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .data-pipelines-job__actions-right[_ngcontent-%COMP%] .data-pipelines-job__action-dropdown-trigger[_ngcontent-%COMP%]{padding-right:1.5rem}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .data-pipelines-job__actions-right[_ngcontent-%COMP%] .data-pipelines-job__action-dropdown-trigger[_ngcontent-%COMP%] clr-icon[_ngcontent-%COMP%]{transform:translateY(-50%) rotate(180deg);top:.85rem}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions.data-pipelines-job__actions--margin-0[_ngcontent-%COMP%]{margin:0}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .data-pipelines-job__navigate-back[_ngcontent-%COMP%]{margin-right:10px;margin-top:-1px}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .data-pipelines-job__navigate-back[_ngcontent-%COMP%] .redo-icon[_ngcontent-%COMP%]{color:var(--clr-link-color, #0072a3);height:25px;width:25px}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .data-pipelines-job__info[_ngcontent-%COMP%]{display:inline-flex}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .data-pipelines-job__info[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{margin-right:.5rem}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__actions[_ngcontent-%COMP%] .page-title[_ngcontent-%COMP%] span[_ngcontent-%COMP%]{font-size:x-large}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__tabs-navigation[_ngcontent-%COMP%]{margin-top:7px}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__tabs-navigation[_ngcontent-%COMP%] .job-details__promotion-icon[_ngcontent-%COMP%]{margin-top:-.75rem;margin-left:.25rem}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__tabs-navigation[_ngcontent-%COMP%] .beta-icon[_ngcontent-%COMP%]{vertical-align:baseline}.data-pipelines-job__page[_ngcontent-%COMP%] .data-pipelines-job__router-outlet-container[_ngcontent-%COMP%]{display:flex;flex-direction:column;flex:1 1 auto}"] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DataJobPageComponent, [{
type: Component,
args: [{ selector: 'lib-data-job-page', template: "<!--\n ~ Copyright 2023-2025 Broadcom\n ~ SPDX-License-Identifier: Apache-2.0\n -->\n\n<!-- eslint-disable @angular-eslint/template/no-call-expression -->\n\n<div\n id=\"data-job-page\"\n class=\"page-container data-pipelines-job__page\"\n data-cy=\"data-pipelines-job-page\"\n>\n <div\n class=\"data-pipelines-job__actions\"\n [ngClass]=\"{\n 'data-pipelines-job__actions--margin-0': !isSubpageNavigation\n }\"\n >\n <div class=\"data-pipelines-job__actions-left\">\n <div\n *ngIf=\"isSubpageNavigation; else rootPageNavigation\"\n class=\"data-pipelines-job__subpage-navigation\"\n >\n <h2\n class=\"m-0 page-title\"\n data-cy=\"data-pipelines-job-main-title\"\n >\n <a\n class=\"label-link data-pipelines-job__navigate-back\"\n href=\"javascript:;\"\n data-cy=\"data-pipelines-job-navigate-back\"\n (click)=\"doNavigateBack($event)\"\n >\n <clr-icon\n shape=\"redo\"\n flip=\"horizontal\"\n class=\"redo-icon\"\n size=\"25\"\n role=\"none\"\n ></clr-icon>\n </a>\n <span data-cy=\"dp-main-title\"\n ><strong>Data Job:</strong> {{ jobName }}</span\n >\n </h2>\n </div>\n <ng-template #rootPageNavigation>\n <div class=\"data-pipelines-job__root-page-navigation\">\n <h1\n class=\"m-0 page-title\"\n data-cy=\"data-pipelines-page-title\"\n >\n <a\n class=\"label-link data-pipelines-job__navigate-back\"\n href=\"javascript:;\"\n data-cy=\"data-pipelines-job-navigate-back\"\n (click)=\"doNavigateBack($event)\"\n >\n <clr-icon\n shape=\"redo\"\n flip=\"horizontal\"\n class=\"redo-icon\"\n size=\"25\"\n role=\"none\"\n ></clr-icon>\n </a>\n <span>Data Job: {{ jobName }}</span>\n </h1>\n </div>\n </ng-template>\n </div>\n\n <div\n *ngIf=\"isJobEditable\"\n class=\"data-pipelines-job__actions-right\"\n data-cy=\"data-pipelines-job-actions-container\"\n >\n <button\n *ngIf=\"isDataJobRunning && isJobWithRunningStatus()\"\n class=\"btn btn-secondary\"\n data-cy=\"data-pipelines-job-cancel-execution-btn\"\n [clrLoading]=\"stopButtonsState\"\n [disabled]=\"cancelDataJobDisabled\"\n (click)=\"cancelExecution()\"\n >\n Cancel Execution\n </button>\n <button\n *ngIf=\"\n isJobAvailable && isExecuteJobAllowed && !isDataJobRunning\n \"\n class=\"btn btn-secondary\"\n data-cy=\"data-pipelines-job-execute-btn\"\n aria-label=\"Execute now\"\n [disabled]=\"\n !areJobExecutionsLoaded ||\n loadingInProgress ||\n isExecutionInProgress()\n \"\n [clrLoading]=\"executeButtonsState\"\n (click)=\"executeJob()\"\n >\n Execute\n </button>\n\n <clr-dropdown *ngIf=\"isJobAvailable\">\n <button\n clrDropdownTrigger\n class=\"btn btn-secondary data-pipelines-job__action-dropdown-trigger\"\n data-cy=\"data-pipelines-job-action-dropdown-btn\"\n >\n Actions\n <clr-icon\n title=\"Actions\"\n shape=\"caret\"\n [attr.size]=\"15\"\n ></clr-icon>\n </button>\n\n <clr-dropdown-menu clrPosition=\"bottom-right\">\n <button\n *ngIf=\"isDownloadJobKeyAllowed\"\n clrDropdownItem\n class=\"btn btn-secondary\"\n aria-label=\"Download Key\"\n data-cy=\"data-pipelines-job-download-btn\"\n [disabled]=\"loadingInProgress\"\n [clrLoading]=\"downloadButtonsState\"\n (click)=\"downloadJobKey()\"\n >\n Download key\n </button>\n\n <button\n clrDropdownItem\n class=\"btn btn-secondary\"\n aria-label=\"Delete Job\"\n data-cy=\"data-pipelines-job-delete-btn\"\n [disabled]=\"\n !areJobExecutionsLoaded ||\n loadingInProgress ||\n isExecutionInProgress()\n \"\n [clrLoading]=\"deleteButtonsState\"\n (click)=\"removeJob()\"\n >\n Delete\n </button>\n </clr-dropdown-menu>\n </clr-dropdown>\n </div>\n\n <lib-delete-modal\n [options]=\"deleteOptions\"\n (delete)=\"confirmRemoveJob()\"\n ></lib-delete-modal>\n\n <lib-confirmation-dialog-modal\n [options]=\"executeNowOptions\"\n (changeStatus)=\"confirmExecuteJob()\"\n ></lib-confirmation-dialog-modal>\n\n <lib-confirmation-dialog-modal\n [options]=\"cancelNowOptions\"\n (changeStatus)=\"confirmCancelDataJob()\"\n ></lib-confirmation-dialog-modal>\n </div>\n\n <ul\n class=\"nav data-pipelines-job__tabs-navigation\"\n role=\"tablist\"\n aria-owns=\"dataPipelinesJobDetails dataPipelinesJobExecutions dataPipelinesJobLineage\"\n >\n <li role=\"presentation\" class=\"nav-item\">\n <a\n id=\"dataPipelinesJobDetails\"\n class=\"nav-link\"\n role=\"tab\"\n aria-hidden=\"false\"\n data-cy=\"data-pipelines-job-details-tab\"\n [attr.aria-selected]=\"detailsLink.isActive\"\n [routerLink]=\"['details']\"\n [queryParams]=\"queryParams\"\n routerLinkActive=\"active\"\n #detailsLink=\"routerLinkActive\"\n >Details</a\n >\n </li>\n <li\n *ngIf=\"\n dataPipelinesModuleConfig.showExecutionsPage && isJobEditable\n \"\n role=\"presentation\"\n class=\"nav-item\"\n >\n <a\n id=\"dataPipelinesJobExecutions\"\n class=\"nav-link\"\n role=\"tab\"\n aria-hidden=\"false\"\n data-cy=\"data-pipelines-job-executions-tab\"\n [attr.aria-selected]=\"executionsLink.isActive\"\n [routerLink]=\"['executions']\"\n [queryParams]=\"queryParams\"\n routerLinkActive=\"active\"\n #executionsLink=\"routerLinkActive\"\n >Executions</a\n >\n </li>\n <li\n *ngIf=\"dataPipelinesModuleConfig.showLineagePage\"\n role=\"presentation\"\n class=\"nav-item\"\n >\n <a\n id=\"dataPipelinesJobLineage\"\n class=\"nav-link\"\n role=\"tab\"\n aria-hidden=\"false\"\n data-cy=\"data-pipelines-job-lineage-tab\"\n [attr.aria-selected]=\"lineage.isActive\"\n [routerLink]=\"['lineage']\"\n [queryParams]=\"queryParams\"\n routerLinkActive=\"active\"\n #lineage=\"routerLinkActive\"\n >Lineage\n <clr-icon class=\"beta-icon\" shape=\"beta\"></clr-icon>\n </a>\n </li>\n </ul>\n\n <div class=\"data-pipelines-job__router-outlet-container\">\n <router-outlet></router-outlet>\n </div>\n</div>\n", styles: ["/*!\n * Copyright 2023-2025 Broadcom\n * SPDX-License-Identifier: Apache-2.0\n */hr{border:0;height:1px;background:#8f9ba3}.label-link{cursor:pointer}.label-link-suppress-decoration:hover{text-decoration:none}.status-icon-enabled{color:#5aa220}.clr-col-6{border-right:1px solid #999999}.loading-spinner{margin-left:45%;margin-top:100px}:host{display:flex;flex-direction:column;flex:1 1 auto;height:100%}.data-pipelines-job__page{display:flex;flex-direction:column;flex:1 1 auto}.data-pipelines-job__page .data-pipelines-job__actions{display:inline-flex;margin-top:.8rem}.data-pipelines-job__page .data-pipelines-job__actions .data-pipelines-job__actions-right{margin-left:auto}.data-pipelines-job__page .data-pipelines-job__actions .data-pipelines-job__actions-right clr-dropdown{margin-top:var(--clr-btn-vertical-margin, .3rem);margin-bottom:var(--clr-btn-vertical-margin, .3rem);margin-left:0}.data-pipelines-job__page .data-pipelines-job__actions .data-pipelines-job__actions-right .data-pipelines-job__action-dropdown-trigger{padding-right:1.5rem}.data-pipelines-job__page .data-pipelines-job__actions .data-pipelines-job__actions-right .data-pipelines-job__action-dropdown-trigger clr-icon{transform:translateY(-50%) rotate(180deg);top:.85rem}.data-pipelines-job__page .data-pipelines-job__actions.data-pipelines-job__actions--margin-0{margin:0}.data-pipelines-job__page .data-pipelines-job__actions .data-pipelines-job__navigate-back{margin-right:10px;margin-top:-1px}.data-pipelines-job__page .data-pipelines-job__actions .data-pipelines-job__navigate-back .redo-icon{color:var(--clr-link-color, #0072a3);height:25px;width:25px}.data-pipelines-job__page .data-pipelines-job__actions .data-pipelines-job__info{display:inline-flex}.data-pipelines-job__page .data-pipelines-job__actions .data-pipelines-job__info span{margin-right:.5rem}.data-pipelines-job__page .data-pipelines-job__actions .page-title span{font-size:x-large}.data-pipelines-job__page .data-pipelines-job__tabs-navigation{margin-top:7px}.data-pipelines-job__page .data-pipelines-job__tabs-navigation .job-details__promotion-icon{margin-top:-.75rem;margin-left:.25rem}.data-pipelines-job__page .data-pipelines-job__tabs-navigation .beta-icon{vertical-align:baseline}.data-pipelines-job__page .data-pipelines-job__router-outlet-container{display:flex;flex-direction:column;flex:1 1 auto}\n"] }]
}], function () { return [{ type: i1.ComponentService }, { type: i1.NavigationService }, { type: i2.ActivatedRoute }, { type: i1.RouterService }, { type: i3.DataJobsService }, { type: i3.DataJobsApiService }, { type: i1.ToastService }, { type: i1.ErrorHandlerService }, { type: undefined, decorators: [{
type: Inject,
args: [DATA_PIPELINES_CONFIGS]
}] }]; }, null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1qb2ItcGFnZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXRhLXBpcGVsaW5lcy9zcmMvbGliL2NvbXBvbmVudHMvZGF0YS1qb2IvZGF0YS1qb2ItcGFnZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXRhLXBpcGVsaW5lcy9zcmMvbGliL2NvbXBvbmVudHMvZGF0YS1qb2IvZGF0YS1qb2ItcGFnZS5jb21w