Skip to content

Commit

Permalink
Merge pull request #1917 from asfadmin/test
Browse files Browse the repository at this point in the history
Prod release
  • Loading branch information
williamh890 authored Jun 17, 2024
2 parents ad4b4f3 + fb74d19 commit b68928a
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 187 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';

import { Store } from '@ngrx/store';
import { AppState } from '@store';
import { of, from } from 'rxjs';
import { tap, catchError, concatMap, finalize } from 'rxjs/operators';

import * as queueStore from '@store/queue';
import * as hyp3Store from '@store/hyp3';
import * as searchStore from '@store/search';

import * as models from '@models';
import * as services from '@services';

@Component({
selector: 'app-confirmation',
templateUrl: './confirmation.component.html',
styleUrls: ['./confirmation.component.scss']
})
export class ConfirmationComponent implements OnInit {
public allJobs: models.QueuedHyp3Job[] = [];
public jobTypesWithQueued = [];
public processingOptions: models.Hyp3ProcessingOptions;
public projectName: string;
public validateOnly: boolean;

public isQueueSubmitProcessing = false;
public progress = null;

constructor(
public dialogRef: MatDialogRef<ConfirmationComponent>,
@Inject(MAT_DIALOG_DATA) public data
public hyp3: services.Hyp3Service,
private store$: Store<AppState>,
private notificationService: services.NotificationService,
@Inject(MAT_DIALOG_DATA) public data: models.ConfirmationDialogData
) { }

ngOnInit(): void {
this.jobTypesWithQueued = this.data;
this.jobTypesWithQueued = this.data.jobTypesWithQueued;
this.processingOptions = this.data.processingOptions;
this.projectName = this.data.projectName;
this.validateOnly = this.data.validateOnly;
this.allJobs = this.jobTypesWithQueued.reduce((total, jobs) => {
total = [...total, ...jobs.jobs];

return total;
}, []);
}

public onToggleJobType(tabQueue): void {
Expand Down Expand Up @@ -54,6 +84,98 @@ export class ConfirmationComponent implements OnInit {
}

public onSubmitQueue(): void {
this.dialogRef.close(this.jobTypesWithQueued);
const jobTypesWithQueued = this.jobTypesWithQueued;

const hyp3JobsBatch = this.hyp3.formatJobs(jobTypesWithQueued, {
projectName: this.projectName,
processingOptions: this.processingOptions
});

const batchSize = 20;
const hyp3JobRequestBatches = this.chunk(hyp3JobsBatch, batchSize);
const total = hyp3JobRequestBatches.length;
let current = 0;

this.isQueueSubmitProcessing = true;
this.progress = null;

from(hyp3JobRequestBatches).pipe(
concatMap(batch => this.hyp3.submitJobBatch$({ jobs: batch, validate_only: this.validateOnly }).pipe(
catchError(resp => {
if (resp.error) {
if (resp.error.detail === 'No authorization token provided' || resp.error.detail === 'Provided apikey is not valid') {
this.notificationService.error('Your authorization has expired. Please sign in again.', 'Error', {
timeOut: 0,
extendedTimeOut: 0,
closeButton: true,
});
} else {
this.notificationService.error( resp.error.detail, 'Error', {
timeOut: 0,
extendedTimeOut: 0,
closeButton: true,
});
}
}

return of({jobs: null});
}),
)),
tap(_ => {
current += 1;
this.progress = Math.floor((current / total) * 100);
}),
finalize(() => {
this.progress = null;
this.isQueueSubmitProcessing = false;

this.store$.dispatch(new hyp3Store.LoadUser());
let numJobsSubmitted: number

if (this.allJobs.length !== hyp3JobsBatch.length) {
numJobsSubmitted = Math.abs(hyp3JobsBatch.length - this.allJobs.length);
} else {
numJobsSubmitted = hyp3JobsBatch.length;
}

const jobText = numJobsSubmitted > 1 ? `${numJobsSubmitted} Jobs` : 'Job';

this.notificationService.info(`Click to view Submitted Products.`, `${jobText} Submitted`, {
closeButton: true,
disableTimeOut: true,
}).onTap.subscribe(() => {
const searchType = models.SearchType.CUSTOM_PRODUCTS;
this.store$.dispatch(new searchStore.SetSearchType(searchType));
});

this.dialogRef.close(this.jobTypesWithQueued);
}),
).subscribe(
(resp: any) => {
if (resp.jobs === null) {
return;
}

const successfulJobs = resp.jobs.map(job => ({
granules: job.job_parameters.granules.map(g => ({name: g})),
job_type: models.hyp3JobTypes[job.job_type]
}));

this.store$.dispatch(new queueStore.RemoveJobs(successfulJobs));
}
);
}

private chunk(arr, chunkSize) {
if (chunkSize <= 0) {
throw new Error('Invalid chunk size');
}

const R = [];
for (let i = 0, len = arr.length; i < len; i += chunkSize) {
R.push(arr.slice(i, i + chunkSize));
}

return R;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@
!isUnlimitedUser && (
allJobs.length > remaining ||
allJobs.length === 0 ||
remaining < totalCreditCost ||
!isUserLoggedIn ||
userStatus === 'NOT_STARTED' ||
userStatus === 'PENDING' ||
Expand Down
123 changes: 19 additions & 104 deletions src/app/components/header/processing-queue/processing-queue.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import { ConfirmationComponent } from './confirmation/confirmation.component';
import { Store } from '@ngrx/store';
import { AppState } from '@store';
import moment from 'moment';
import { of, from, combineLatest } from 'rxjs';
import { tap, catchError, delay, concatMap, finalize } from 'rxjs/operators';
import { of, combineLatest } from 'rxjs';
import { delay } from 'rxjs/operators';
import { ApplicationStatus } from '@models';

import * as queueStore from '@store/queue';
import * as hyp3Store from '@store/hyp3';
import * as searchStore from '@store/search';
import * as userStore from '@store/user';
import * as uiStore from '@store/ui';
import * as models from '@models';
Expand Down Expand Up @@ -61,7 +60,7 @@ export class ProcessingQueueComponent implements OnInit {
public hyp3JobTypes = models.hyp3JobTypes;
public hyp3JobTypesList: models.Hyp3JobType[];
public selectedJobTypeId: string | null = null;
public jobTypesWithQueued = [];
public jobTypesWithQueued: models.JobTypesWithQueued[] = [];
public costPerJobByType = {};
public totalCreditCost = 0;

Expand All @@ -83,7 +82,6 @@ export class ProcessingQueueComponent implements OnInit {
private dialogRef: MatDialogRef<ProcessingQueueComponent>,
private store$: Store<AppState>,
private screenSize: services.ScreenSizeService,
private notificationService: services.NotificationService,
) { }

ngOnInit(): void {
Expand Down Expand Up @@ -214,7 +212,12 @@ export class ProcessingQueueComponent implements OnInit {
height: '600px',
maxWidth: '350px',
maxHeight: '600px',
data: this.jobTypesWithQueued
data: {
jobTypesWithQueued: this.jobTypesWithQueued,
projectName: this.projectName,
processingOptions: this.processingOptions,
validateOnly: this.validateOnly,
}
});

confirmationRef.afterClosed().subscribe(
Expand All @@ -227,10 +230,7 @@ export class ProcessingQueueComponent implements OnInit {
this.validateOnly = false;
}

this.onSubmitQueue(
jobTypesWithQueued,
this.validateOnly
);
this.onSubmitQueue();
}
);
}
Expand All @@ -241,103 +241,18 @@ export class ProcessingQueueComponent implements OnInit {
);
}

private chunk(arr, chunkSize) {
if (chunkSize <= 0) {
throw new Error('Invalid chunk size');
}

const R = [];
for (let i = 0, len = arr.length; i < len; i += chunkSize) {
R.push(arr.slice(i, i + chunkSize));
public onSubmitQueue(): void {
if(this.allJobs.length === 0) {
this.dialogRef.close();
}

return R;
}

public onSubmitQueue(jobTypesWithQueued, validateOnly: boolean): void {
const hyp3JobsBatch = this.hyp3.formatJobs(jobTypesWithQueued, {
projectName: this.projectName,
processingOptions: this.processingOptions
});

const batchSize = 20;
const hyp3JobRequestBatches = this.chunk(hyp3JobsBatch, batchSize);
const total = hyp3JobRequestBatches.length;
let current = 0;

this.isQueueSubmitProcessing = true;

from(hyp3JobRequestBatches).pipe(
concatMap(batch => this.hyp3.submitJobBatch$({ jobs: batch, validate_only: validateOnly }).pipe(
catchError(resp => {
if (resp.error) {
if (resp.error.detail === 'No authorization token provided' || resp.error.detail === 'Provided apikey is not valid') {
this.notificationService.error('Your authorization has expired. Please sign in again.', 'Error', {
timeOut: 0,
extendedTimeOut: 0,
closeButton: true,
});
} else {
this.notificationService.error( resp.error.detail, 'Error', {
timeOut: 0,
extendedTimeOut: 0,
closeButton: true,
});
}
}

return of({jobs: null});
}),
)),
tap(_ => {
current += 1;
this.progress = Math.floor((current / total) * 100);
}),
finalize(() => {
this.progress = null;
this.isQueueSubmitProcessing = false;

this.store$.dispatch(new hyp3Store.LoadUser());
let jobText;
if (this.allJobs.length === 0) {
this.dialogRef.close();
jobText = hyp3JobsBatch.length > 1 ? `${hyp3JobsBatch.length} Jobs` : 'Job';
} else if (this.allJobs.length !== hyp3JobsBatch.length) {
const submittedJobs = Math.abs(hyp3JobsBatch.length - this.allJobs.length);
jobText = submittedJobs > 1 ? `${submittedJobs} Jobs` : 'Job';
}
if (jobText) {
this.notificationService.info(`Click to view Submitted Products.`, `${jobText} Submitted`, {
closeButton: true,
disableTimeOut: true,
}).onTap.subscribe(() => {
const searchType = models.SearchType.CUSTOM_PRODUCTS;
this.store$.dispatch(new searchStore.SetSearchType(searchType));
});
}
}),
).subscribe(
(resp: any) => {
if (resp.jobs === null) {
return;
}

const successfulJobs = resp.jobs.map(job => ({
granules: job.job_parameters.granules.map(g => ({name: g})),
job_type: models.hyp3JobTypes[job.job_type]
}));

this.store$.dispatch(new queueStore.RemoveJobs(successfulJobs));

const jobsInTab = this.allJobs.filter(
job => job.job_type.id === this.selectedJobTypeId
);

if (jobsInTab.length === 0) {
this.setNextTabIndex(models.hyp3JobTypes[this.selectedJobTypeId]);
}
}
const jobsInTab = this.allJobs.filter(
job => job.job_type.id === this.selectedJobTypeId
);

if (jobsInTab.length === 0) {
this.setNextTabIndex(models.hyp3JobTypes[this.selectedJobTypeId]);
}
}

public onSetSelectedJobType(jobType: models.Hyp3JobType): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
}
.list-item {
word-wrap: break-word;
overflow: visible;
height: auto;
overflow: visible !important;
height: auto !important;
}
.list-item-content {
overflow: visible;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export class SceneFileComponent implements OnInit, OnDestroy {
of(this.product).pipe(
filter(prod => !!prod.metadata)
).subscribe( prod => {

if (!prod.metadata.job) {
this.paramsList = [];
} else {
Expand Down Expand Up @@ -179,7 +178,7 @@ export class SceneFileComponent implements OnInit, OnDestroy {
const processinglevel = this.product.metadata.productType;
const productType = models.opera_s1.productTypes.find(product => product.apiValue == processinglevel);
const operaburstid = this.product.metadata?.opera?.operaBurstID;

[
new searchStore.SetSearchType(models.SearchType.DATASET),
new filterStore.ClearDatasetFilters(),
Expand Down
Loading

0 comments on commit b68928a

Please sign in to comment.