Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/portal/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@
"avoidEscape": true
}
],
"class-methods-use-this": "off",
"radix": "error",
"eqeqeq": [
"error",
Expand Down
32 changes: 7 additions & 25 deletions apps/portal/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,10 @@
"outputPath": "dist/portal",
"index": "src/index.html",
"browser": "src/main.ts",
"polyfills": [
"zone.js"
],
"polyfills": ["zone.js"],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"assets": ["src/favicon.ico", "src/assets"],
"styles": [
"src/styles.scss",
"node_modules/primeng/resources/themes/lara-light-blue/theme.css",
Expand Down Expand Up @@ -88,38 +83,25 @@
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"polyfills": ["zone.js", "zone.js/testing"],
"tsConfig": "tsconfig.spec.json",
"inlineStyleLanguage": "scss",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.scss"],
"scripts": []
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
}
}
}
}
},
"cli": {
"analytics": false,
"schematicCollections": [
"@angular-eslint/schematics"
]
"schematicCollections": ["@angular-eslint/schematics"]
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="table-container">
<p-table [value]="jobDetail">
<p-table [value]="jobDetails">
<ng-template pTemplate="header">
<tr>
<th>Timestamp</th>
Expand All @@ -14,15 +14,15 @@
<td>{{ job.fileName }}</td>
<td>
<p-tag
[severity]="getSeverity(job.status)"
[severity]="getSeverity(job.jobStatus)"
styleClass="p-2 flex"
[value]="getStatusText(job.status)"
[value]="getStatusText(job.jobStatus)"
>
</p-tag>
</td>
<td class="action-cell p-0">
<p-button
*ngIf="job.status === 4"
*ngIf="job.jobStatus === 4"
(click)="downloadFile(job.summary, job.fileName)"
severity="info"
styleClass="h-2rem p-3 mx-3"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, OnDestroy } from '@angular/core';
import * as FileSaver from 'file-saver';
import { MessageService } from 'primeng/api';
import { TranslateService } from '@ngx-translate/core';
import { Subscription, interval } from 'rxjs';
import { JobDetails } from '../../shared/job-details.interface';
import { JobStatus } from '../../shared/jobs';
import { FileService } from '../file.service';
import { Summary } from '../../shared/summary.interface';

const POLLING_DELAY_IN_MILLISECONDS = 5000;
@Component({
selector: 'app-file-processor',
templateUrl: './file-processor.component.html',
styleUrl: './file-processor.component.scss',
styleUrls: ['./file-processor.component.scss'],
})
export class FileProcessorComponent implements OnInit {
// to do:the name will probably be changed to match the backend
jobDetail: JobDetails[] = [];
export class FileProcessorComponent implements OnInit, OnDestroy {
jobDetails: JobDetails[] = [];

summaries: Summary[] = [];

jobIds: number[] = [];

fetchInterval: Subscription | null = null;

constructor(
private fileService: FileService,
private messageService: MessageService,
Expand All @@ -30,72 +33,108 @@ export class FileProcessorComponent implements OnInit {

ngOnInit(): void {
this.fileService.jobIds$.subscribe((jobIds) => {
this.fileService.fetchSummaries(jobIds).subscribe(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(result: any) => {
this.summaries = result.data.summaries.summaries;
this.jobDetail = this.summaries.map((summary) => ({
fileName: summary.inputFile.split('_')[1],
status: summary.status,
timestamp: new Date(summary.createdOn).toLocaleString(),
summary: summary.outputText,
}));
this.jobDetail.reverse();
},
(error) => {
if (error.status === 0) {
this.translateService.get('ERRORS.UNHANDLED_ERROR').subscribe((translation: string) => {
this.messageService.add({
key: 'tst',
severity: 'error',
summary: 'Network Error',
detail: translation,
});
this.jobIds = jobIds;

if (this.jobIds.length !== 0) {
this.startFetchingSummaries();
} else {
this.stopFetchingSummaries();
}
});
}

ngOnDestroy(): void {
this.stopFetchingSummaries();
}

startFetchingSummaries(): void {
this.fetchSummaries();
this.fetchInterval = interval(POLLING_DELAY_IN_MILLISECONDS).subscribe(() => {
this.fetchSummaries();
});
}

stopFetchingSummaries(): void {
if (this.fetchInterval) {
this.fetchInterval.unsubscribe();
this.fetchInterval = null;
}
}

fetchSummaries(): void {
this.fileService.fetchSummaries(this.jobIds).subscribe(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(result: any) => {
this.summaries = result.data.summaries.summaries;
this.jobDetails = this.summaries.map((summary) => ({
fileName: summary.inputFile.split('_')[1] || summary.inputFile,
jobStatus: summary.jobStatus,
timestamp: new Date(summary.createdOn).toLocaleString(),
summary: summary.outputText || null,
})) as unknown as JobDetails[];

this.jobDetails.reverse();

// Check if all jobs are either failed or finished
const allJobsCompleted = this.jobDetails.every(
(job) => job.jobStatus === JobStatus.finished || job.jobStatus === JobStatus.failed,
);

if (allJobsCompleted) {
this.stopFetchingSummaries();
}
},
(error) => {
if (error.status === 0) {
this.translateService.get('ERRORS.UNHANDLED_ERROR').subscribe((translation: string) => {
this.messageService.add({
key: 'tst',
severity: 'error',
summary: 'Network Error',
detail: translation,
});
} else {
this.translateService.get('ERRORS.API_ERROR').subscribe((translation: string) => {
this.messageService.add({
key: 'tst',
severity: 'error',
summary: 'Error',
detail: translation,
});
});
} else {
this.translateService.get('ERRORS.API_ERROR').subscribe((translation: string) => {
this.messageService.add({
key: 'tst',
severity: 'error',
summary: 'Error',
detail: translation,
});
}
},
);
});
});
}
},
);
}

// eslint-disable-next-line class-methods-use-this
getSeverity(status: number): string {
const severityMap: { [key: number]: string } = {
1: 'warning',
2: 'primary',
3: 'info',
4: 'success',
5: 'danger',
};
return severityMap[status] || 'error';
}

// eslint-disable-next-line class-methods-use-this
getStatusText(status: number): string {
const statusTextMap: { [key: number]: JobStatus } = {
1: JobStatus.pending,
2: JobStatus.queued,
3: JobStatus.inProgress,
4: JobStatus.finished,
5: JobStatus.failed,
const statusTextMap: { [key: number]: string } = {
1: 'PENDING',
2: 'QUEUED',
3: 'IN PROGRESS',
4: 'FINISHED',
5: 'FAILED',
};

return statusTextMap[status];
}

// eslint-disable-next-line class-methods-use-this
downloadFile(summary: string | null | undefined, fileName: string): void {
if (summary !== undefined && summary !== null) {
const blob = new Blob([summary], { type: 'text/markdown' });
FileSaver.saveAs(blob, fileName);
FileSaver.saveAs(blob, `${fileName}.md`);
}
}
}
8 changes: 5 additions & 3 deletions apps/portal/src/app/features/file.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ export class FileService {
private graphqlService: GraphqlService,
private apollo: Apollo,
) {
this.jobIdsSubject.next(JSON.parse(localStorage.getItem('jobIds') || '[]'));
this.jobIdsSubject.next(JSON.parse(sessionStorage.getItem('jobIds') || '[]'));
}

updateJobIds(jobId: number): void {
const jobIds = [...this.jobIdsSubject.value, jobId];
localStorage.setItem('jobIds', JSON.stringify(jobIds));

sessionStorage.setItem('jobIds', JSON.stringify(jobIds));
this.jobIdsSubject.next(jobIds);
}

fetchSummaries(jobIds: number[]) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fetchSummaries(jobIds: number[]): Observable<any> {
const jobIdsString = JSON.stringify(jobIds);
const queryWithJobIdsString = fetchFileStatus(jobIdsString);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ export class TranscriptAnalyzerComponent {
const jobId = result?.data?.createSummary?.jobId;

if (jobId) {
const jobIdsArray = JSON.parse(localStorage.getItem('jobIds') || '[]');
const jobIdsArray = JSON.parse(sessionStorage.getItem('jobIds') || '[]');
jobIdsArray.push(jobId);
localStorage.setItem('jobIds', JSON.stringify(jobIdsArray));
sessionStorage.setItem('jobIds', JSON.stringify(jobIdsArray));
this.fileService.updateJobIds(jobId);
}
},
Expand Down
4 changes: 4 additions & 0 deletions apps/portal/src/app/graphql/graphql.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export class GraphqlService {
query<T>(query: DocumentNode): Observable<ApolloQueryResult<T>> {
const queryRef: QueryRef<T> = this.apollo.use('default').watchQuery({
query,
errorPolicy: 'all',
fetchPolicy: 'network-only',
});

return queryRef.valueChanges;
Expand All @@ -31,6 +33,8 @@ export class GraphqlService {
'x-apollo-operation-name': 'createSummary',
},
},
errorPolicy: 'all',
fetchPolicy: 'network-only',
});
}
}
4 changes: 3 additions & 1 deletion apps/portal/src/app/shared/job-details.interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { JobStatus } from './jobs';

export interface JobDetails {
fileName: string;
status: number;
jobStatus: JobStatus;
timestamp: string;
summary?: string | null;
}
10 changes: 5 additions & 5 deletions apps/portal/src/app/shared/jobs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export enum JobStatus {
pending = 'PENDING',
queued = 'QUEUED',
inProgress = 'IN PROGRESS',
finished = 'FINISHED',
failed = 'FAILED',
pending = 1,
queued = 2,
inProgress = 3,
finished = 4,
failed = 5,
}
12 changes: 3 additions & 9 deletions apps/portal/tsconfig.app.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,8 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": [
"@angular/localize"
]
"types": ["@angular/localize"]
},
"files": [
"src/main.ts"
],
"include": [
"src/**/*.d.ts"
]
"files": ["src/main.ts"],
"include": ["src/**/*.d.ts"]
}
5 changes: 1 addition & 4 deletions apps/portal/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"lib": [
"ES2022",
"dom"
]
"lib": ["ES2022", "dom"]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
Expand Down
Loading