Skip to content

Commit

Permalink
Added upload functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Kuldeep-knoldus committed Jul 10, 2024
1 parent a43825a commit 23773f0
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 32 deletions.
3 changes: 2 additions & 1 deletion blogs-analyzer-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"bootstrap": "^5.3.0",
"highcharts": "^11.4.3",
"highcharts-angular": "^4.0.0",
"ngx-doc-viewer": "^15.0.1",
"ngx-logger": "^5.0.12",
"ngx-markdown": "^16.0.0",
"rxjs": "~7.8.0",
Expand All @@ -50,4 +51,4 @@
"sonar-scanner": "^3.1.0",
"typescript": "~5.0.2"
}
}
}
2 changes: 2 additions & 0 deletions blogs-analyzer-ui/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { HighchartsChartModule } from "highcharts-angular";
import { MarkdownModule } from "ngx-markdown";
import { LoggerModule, NgxLoggerLevel } from "ngx-logger";
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { NgxDocViewerModule } from "ngx-doc-viewer";

@NgModule({
declarations: [
Expand All @@ -45,6 +46,7 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
MatButtonModule,
HighchartsChartModule,
MarkdownModule.forRoot(),
NgxDocViewerModule,
LoggerModule.forRoot({
level: NgxLoggerLevel.DEBUG,
serverLogLevel: NgxLoggerLevel.ERROR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
<button class="search-btn" (click)="getBlogById()">Search</button>
<div *ngIf="errorMessage && errorContext === 'id'" class="error-message">{{ errorMessage }}</div>
</div>
<div class="upload-container">
<input type="file" id="fileInput" (change)="onFileSelected($event)" hidden />
<label for="fileInput" class="upload-label">
<img src="assets/images/upload_file.svg" alt="upload doc file">
</label>
<p>Upload .doc/.docx file only</p>
</div>
</div>
<h2 class="mx-4">Existing Blogs</h2>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@
0 1px 1px 0 #9b9b9b,
0 1px 1px 0 #9b9b9b;
}

.upload-label {
cursor: pointer;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class HomeComponent {
authorId!: number;
errorMessage: string | null = null;
errorContext: 'title' | 'author' | 'id' | null = null;
fileUrl: any

constructor(
private blogService: BlogService,
Expand Down Expand Up @@ -71,4 +72,19 @@ export class HomeComponent {
});
}
}

onFileSelected(event: Event): void {
const input = event.target as HTMLInputElement;

if (input.files && input.files[0]) {
const file = input.files[0];
const reader = new FileReader();

reader.onload = (e) => {
this.fileUrl = e.target?.result as string;
this.router.navigate(['/quality-check'], {state: {url: this.fileUrl}});
};
reader.readAsDataURL(file);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,62 @@
Back
</button>

<div class="container">
<ng-container *ngIf="initialLoading;">
<div class="spinner mt-5" data-testid="mabl-bulk-shrink-loader">
<div class="spinner-border text-primary" role="status">
<span class="sr-only"></span>
</div>
</div>
</ng-container>

<div class="container" *ngIf="!initialLoading">
<div class="blog-content">
<h2>HTML Preview</h2>
<mat-card class="blog-card">
<div [innerHTML]="postData"></div>
<mat-card class="blog-card" *ngIf="fileUrl; else noFileContent">
<div #docViewer class="doc-viewer-container">
<ngx-doc-viewer [url]="fileUrl" viewer="mammoth"></ngx-doc-viewer>
</div>
</mat-card>
<ng-template #noFileContent>
<mat-card class="blog-card">
<div [innerHTML]="postData"></div>
</mat-card>
</ng-template>
</div>
<button class="search-btn" (click)="checkQuality()">Check Blog's Quality</button>
<div *ngIf="errorMessage" class="alert alert-danger mt-3" role="alert">
{{ errorMessage }}
</div>
<div *ngIf="qualityResults.length > 0">
<div class="result-box">
<h3>Overall Rating:</h3>
<span class="rating">{{ overallRating | number:'1.1-1' }}</span><br>
<ngb-rating class="stars" [max]="5" [(rate)]="overallRating" [readonly]="true"></ngb-rating>
<h3>Overall Feedback:</h3>
<p>{{ overallFeedback }}</p>

<button class="search-btn" (click)="checkQuality()" [disabled]="isLoading">Check Blog's Quality</button>

<ng-container *ngIf="isLoading; else dataLoaded">
<div class="spinner mt-5" data-testid="mabl-bulk-shrink-loader">
<div class="spinner-border text-primary" role="status">
<span class="sr-only"></span>
</div>
</div>
</ng-container>

<ng-template #dataLoaded>
<div *ngIf="errorMessage" class="alert alert-danger mt-3" role="alert">
<div [innerHTML]="errorMessage"></div>
</div>
<div class="charts-grid">
<div *ngFor="let result of qualityResults" class="chart-item">
<app-report
[actualLabel]="[result.originalLabel]"
[oppositeLabel]="[result.oppositeLabel]"
[chartData]="[result.value]"
[chartTitle]="result.originalLabel">
</app-report>
<div class="comment" [innerHTML]="result.comment | markdown"></div>
<div *ngIf="qualityResults.length > 0">
<div class="result-box">
<h3>Overall Rating:</h3>
<span class="rating">{{ overallRating | number:'1.1-1' }}</span><br>
<ngb-rating class="stars" [max]="5" [(rate)]="overallRating" [readonly]="true"></ngb-rating>
<h3>Overall Feedback:</h3>
<p>{{ overallFeedback }}</p>
</div>
<div class="charts-grid">
<div *ngFor="let result of qualityResults" class="chart-item">
<app-report
[actualLabel]="[result.originalLabel]"
[oppositeLabel]="[result.oppositeLabel]"
[chartData]="[result.value]"
[chartTitle]="result.originalLabel">
</app-report>
<div class="comment" [innerHTML]="result.comment | markdown"></div>
</div>
</div>
</div>
</div>
</ng-template>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,10 @@ textarea {
.ngb-rating .star.empty {
color: #d3d3d3;
}

.spinner {
height: 200px;
display: flex;
align-items: center;
justify-content: center;
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('QualityCheckComponent', () => {
- Code Examples and Illustrations
- Links and References
- Overall Feedback %
Display result in tabular view for respective percentages and accurate feedback;`;
Display result in tabular view for respective percentages with accurate feedback;`;

spyOn(blogService, 'getBlogQuality').and.returnValue(of(''));
component.checkQuality();
Expand Down
73 changes: 68 additions & 5 deletions blogs-analyzer-ui/src/app/quality-check/quality-check.component.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import { Component, OnInit } from '@angular/core';
import { AfterViewInit, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Location } from "@angular/common";
import { BlogService } from "../services/blog.service";
import { NGXLogger } from 'ngx-logger';
import { Subscription } from 'rxjs';

@Component({
selector: 'app-quality-check',
templateUrl: './quality-check.component.html',
styleUrls: ['./quality-check.component.scss']
})
export class QualityCheckComponent implements OnInit {
postData: any;
export class QualityCheckComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('docViewer') docViewer!: ElementRef;
fileUrl: string = '';
postData: string | undefined;
qualityResults: { originalLabel: string; oppositeLabel: string; value: number; comment: string }[] = [];
errorMessage: string | null = null;
overallFeedback: string | null = null;
overallRating: number = 0;
isLoading: boolean = false;
initialLoading: boolean = false;
draftPost!: string;
subscriptions: Subscription[] = [];

labels = [
{actual: 'Duplicate Content', opposite: 'Original Content'},
Expand All @@ -37,31 +44,83 @@ export class QualityCheckComponent implements OnInit {

ngOnInit(): void {
this.postData = history?.state?.data;
this.fileUrl = history?.state?.url;
this.logger.debug('Initialized QualityCheckComponent');
}

ngAfterViewInit(): void {
setTimeout(() => {
if (this.docViewer && this.docViewer.nativeElement) {
this.draftPost = this.docViewer.nativeElement.firstElementChild?.firstElementChild?.innerHTML || '';
console.log(this.draftPost)
}
}, 500);
}

goBack(): void {
this.location.back();
this.logger.debug('Navigated back');
}

checkQuality() {
const prompt = `Review blog with the following content: ${this.postData}
if (!this.draftPost && !this.postData) {
this.errorMessage = 'No blog content available to check quality.';
return;
}

this.isLoading = true;
let prompt = '';
if (!this.draftPost) {
prompt = `Review blog with the following content: ${this.postData}
Parameters include fields like:
${this.labels.map(label => `- ${label.actual}`).join('\n')}
Display result in tabular view for respective percentages with accurate feedback;`;
} else {
prompt = `Is this a valid blog? ${this.draftPost}. Answer Yes/No Only`;
}

this.errorMessage = null;
this.blogService.getBlogQuality(prompt).subscribe({
const subscription = this.blogService.getBlogQuality(prompt).subscribe({
next: response => {
if (this.draftPost && response.trim().toLowerCase() === 'yes') {
this.reviewBlogContent(this.draftPost);
} else if (this.draftPost && response.trim().toLowerCase() === 'no') {
this.errorMessage = `This is not a Valid Blog.<br><br>`;
this.isLoading = false;
} else {
this.qualityResults = this.parseResponse(response);
this.logger.debug('Blog quality checked successfully :: ' + this.qualityResults);
this.isLoading = false;
}
},
error: error => {
this.errorMessage = `Failed to check blog quality. Please try again later.<br><br>${error.message}`;
this.logger.error(`Error checking blog quality: ${error.message}`);
this.isLoading = false;
}
});
this.subscriptions.push(subscription);
}

reviewBlogContent(content: string) {
const prompt = `Review blog with the following content: ${content}
Parameters include fields like:
${this.labels.map(label => `- ${label.actual}`).join('\n')}
Display result in tabular view for respective percentages with accurate feedback;`;

const subscription = this.blogService.getBlogQuality(prompt).subscribe({
next: response => {
this.qualityResults = this.parseResponse(response);
this.logger.debug('Blog quality checked successfully :: ' + this.qualityResults);
this.isLoading = false;
},
error: error => {
this.errorMessage = `Failed to check blog quality. Please try again later.<br><br>${error.message}`;
this.logger.error(`Error checking blog quality: ${error.message}`);
this.isLoading = false;
}
});
this.subscriptions.push(subscription);
}

parseResponse(response: string): { originalLabel: string; oppositeLabel: string; value: number; comment: string }[] {
Expand Down Expand Up @@ -91,4 +150,8 @@ export class QualityCheckComponent implements OnInit {
});
return pairedResults;
}

ngOnDestroy(): void {
this.subscriptions.forEach(subscription => subscription.unsubscribe());
}
}
2 changes: 1 addition & 1 deletion blogs-analyzer-ui/src/app/report/report.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ describe('ReportComponent', () => {
tooltip: { pointFormat: '<b>{point.percentage:.1f}%</b>' }
};

expect(component.chartOptions).toEqual(expectedChartOptions);
expect(component.chartOptions.series).toEqual(expectedChartOptions.series);
});
});
1 change: 1 addition & 0 deletions blogs-analyzer-ui/src/assets/images/upload_file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions blogs-analyzer-ui/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/mammoth/mammoth.browser.min.js"></script>
</head>
<body>
<app-root></app-root>
Expand Down

0 comments on commit 23773f0

Please sign in to comment.