Commit feb71c3e authored by Gabriel Gutu-Robu's avatar Gabriel Gutu-Robu
parents 9aba498d db3dd7e7
......@@ -19,7 +19,12 @@
"assets": [
"src/assets",
"src/.well-known",
"src/favicon.ico"
"src/favicon.ico",
{
"glob": "**/*.json",
"input": "src/app/pages/experiments/intellit/graphs",
"output": "assets"
}
],
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
......
......@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from '../pages/home/home.component';
import { DemoComponent } from '../pages/demo/demo.component';
import { ExperimentsComponent } from '../pages/experiments/experiments.component';
import { SentimentAnalysisComponent } from '../pages/demo/sentiment-analysis/sentiment-analysis.component';
import { TextualComplexityComponent } from '../pages/demo/textual-complexity/textual-complexity.component';
import { KeywordsComponent } from '../pages/demo/keywords/keywords.component';
......@@ -18,15 +19,21 @@ import { PublicationsComponent } from '../pages/publications/publications.compon
import { ContactComponent } from '../pages/contact/contact.component';
import { ComprehensionModelComponent } from '../pages/demo/comprehension-model/comprehension-model.component';
import { KeywordsHeatmapComponent } from '../pages/demo/keywords-heatmap/keywords-heatmap.component';
import {CurriculumRecommendationComponent} from '../pages/demo/curriculum-recomandation/curriculum-recommendation.component';
import {DocumentAnalysisComponent} from "../pages/demo/document-analysis/document-analysis";
import { CurriculumRecommendationComponent } from '../pages/demo/curriculum-recomandation/curriculum-recommendation.component';
import { DocumentAnalysisComponent } from "../pages/demo/document-analysis/document-analysis";
import { CsclNewComponent } from '../pages/demo/cscl-new/cscl-new.component';
import { EssayFeedbackComponent } from '../pages/demo/essay-feedback/essay-feedback.component';
import { IntellitComponent } from '../pages/experiments/intellit/intellit.component';
const routes: Routes = [
{
path: 'demo',
component: DemoComponent,
},
{
path: 'experiments',
component: ExperimentsComponent,
},
{
path: 'people',
component: PeopleComponent,
......@@ -99,10 +106,18 @@ const routes: Routes = [
path: 'demo/curriculum-recommendation',
component: CurriculumRecommendationComponent,
},
{
{
path: 'demo/document-analysis',
component: DocumentAnalysisComponent,
},
},
{
path: 'demo/essay-feedback',
component: EssayFeedbackComponent
},
{
path: 'experiments/intellit',
component: IntellitComponent
},
{
path: '',
component: HomeComponent,
......
......@@ -38,6 +38,10 @@ import { CommunityKeywordsHeatmapComponent } from './pages/demo/community/keywor
import { ClusteredForceLayoutComponent } from './pages/demo/community/clustered-force-layout/clustered-force-layout.component';
import { MultiLevelEdgeBundlingComponent } from './pages/demo/community/multi-level-edge-bundling/multi-level-edge-bundling.component';
import { ExperimentsComponent } from './pages/experiments/experiments.component';
import { ExperimentsMenuComponent } from './pages/experiments/sections/menu/menu.component';
import { ExperimentsServicesComponent } from './pages/experiments/sections/services/services.component'
import { IntellitComponent } from './pages/experiments/intellit/intellit.component';
import { DemoServicesComponent } from './pages/demo/sections/services/services.component';
import { DemoCommonFieldsComponent } from './pages/demo/sections/common-fields/common-fields.component';
......@@ -45,6 +49,12 @@ import { DemoSemDiffCommonFieldsComponent } from './pages/demo/sections/sem-diff
import { ReaderBenchCommonModule } from '@reader-bench/common';
import { KeywordsModule } from './pages/demo/keywords/keywords.module';
import { EssayFeedbackComponent } from './pages/demo/essay-feedback/essay-feedback.component';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
// Import library module
import { NgxSpinnerModule } from "ngx-spinner";
import 'jquery';
import { PeopleComponent } from './pages/people/people.component';
import { ProjectsComponent } from './pages/projects/projects.component';
......@@ -67,6 +77,9 @@ import { Ng5SliderModule } from 'ng5-slider';
import { MultiDocumentCohesionGridComponent } from './pages/demo/document-analysis/multi-document-cohesion-grid/multi-document-cohesion-grid';
import { CsclNewComponent } from './pages/demo/cscl-new/cscl-new.component';
import { DropzoneModule, DropzoneConfigInterface, DROPZONE_CONFIG } from 'ngx-dropzone-wrapper';
import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar';
import { PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar';
import { PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar';
const DEFAULT_DROPZONE_CONFIG: DropzoneConfigInterface = {
// Change this to your upload POST address:
......@@ -74,6 +87,11 @@ const DEFAULT_DROPZONE_CONFIG: DropzoneConfigInterface = {
// acceptedFiles: 'image/*',
createImageThumbnails: true
};
const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
suppressScrollX: true
};
@NgModule({
declarations: [
AppComponent,
......@@ -94,7 +112,8 @@ const DEFAULT_DROPZONE_CONFIG: DropzoneConfigInterface = {
CurriculumRecommendationComponent,
TextualComplexityComponent,
KeywordsComponent,
TextualComplexityComponent,
EssayFeedbackComponent,
IntellitComponent,
SemanticAnnotationComponent,
SelfExplanationComponent,
CsclComponent,
......@@ -107,6 +126,7 @@ const DEFAULT_DROPZONE_CONFIG: DropzoneConfigInterface = {
CommunityComponent,
SemDiffComponent,
DemoServicesComponent,
ExperimentsServicesComponent,
DemoCommonFieldsComponent,
DemoSemDiffCommonFieldsComponent,
ApproximationPipe,
......@@ -125,7 +145,9 @@ const DEFAULT_DROPZONE_CONFIG: DropzoneConfigInterface = {
MultiLevelEdgeBundlingComponent,
ChordComponent,
DocumentAnalysisComponent,
MultiDocumentCohesionGridComponent
MultiDocumentCohesionGridComponent,
ExperimentsComponent,
ExperimentsMenuComponent
],
imports: [
BrowserModule,
......@@ -141,6 +163,8 @@ const DEFAULT_DROPZONE_CONFIG: DropzoneConfigInterface = {
Ng5SliderModule,
UiSwitchModule,
DropzoneModule,
PerfectScrollbarModule,
NgxSpinnerModule
],
exports: [
KeywordsComponent
......@@ -153,9 +177,14 @@ const DEFAULT_DROPZONE_CONFIG: DropzoneConfigInterface = {
provide: DROPZONE_CONFIG,
useValue: DEFAULT_DROPZONE_CONFIG
},
{
provide: PERFECT_SCROLLBAR_CONFIG,
useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG
}
],
bootstrap: [
AppComponent
]
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }
.m-10 {
margin: 10px;
margin-top: 0px;
}
.ml-10 {
margin-left: 10px;;
}
.feedback-element {
border: solid 1px #a4acb3;
padding: 12px;
margin: 8px 0px;
}
.feedback-element:first-of-type {
margin-top: 0px;
}
.feedback-name {
color: #43b9c7;
margin: 0px;
font-weight: bold;
text-transform: uppercase;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
}
.blue {
color: #43b9c7;
}
.feedback-description, .text-area {
margin: 0px;
color: #b8bebf;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
}
<div class="row">
<div class="page-wrapper">
<!-- <search-box></search-box> -->
<div id="page">
<app-header></app-header>
<div class="content-wrapper">
<app-carousel></app-carousel>
<div class="container">
<div class="row top-buffer">
<app-demo-menu></app-demo-menu>
</div>
</div>
<div class="container">
<div class="section-header">
<h1>{{componentTitle}}</h1>
</div>
</div>
<div class="container row-list">
<div class="form-group col-xs-6 col-md-6 col-lg-6">
<div class="row">
<label for="input_text">Text
<span class="required">*</span>
</label>
</div>
<div class="row">
<textarea id="input_text" class="form-control text-area" [(ngModel)]="formData.text" rows="20"></textarea>
</div>
<div class="row top-buffer bottom-buttons" *ngIf="!loading">
<button class="btn theme-btn-1" (click)="process()">
<span class="button">Process</span>
</button>
</div>
</div>
<div id="results" class="col-xs-6 col-md-6 col-lg-6">
<div class="ml-10">
<label for="input_text">Feedback</label>
<label *ngIf="showResults" class="blue ml-10"> {{score}}</label>
</div>
<div *ngIf="loading" class="m-10">
<img src="../../../../assets/img/loading.gif" alt="Loading..." />
</div>
<perfect-scrollbar style="max-height: 400px;" *ngIf="showResults" class="m-10 feedback">
<div class="feedback-element" *ngFor="let feedback of response">
<div class="feedback-name row">{{feedback.name}}</div>
<div class="feedback-description row">{{feedback.description}}</div>
</div>
</perfect-scrollbar>
<div *ngIf="!showResults && !loading">
<div class="feedback-element">
<div class="feedback-name row">Feedback results</div>
<div class="feedback-description row">Please insert a text in the right-side box and press 'PROCESS' to continue.</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EssayFeedbackComponent } from './essay-feedback.component';
describe('EssayFeedbackComponent', () => {
let component: EssayFeedbackComponent;
let fixture: ComponentFixture<EssayFeedbackComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [EssayFeedbackComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EssayFeedbackComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, Input } from '@angular/core';
import { DemoMenuComponent } from '../sections/menu/menu.component';
import { DefaultInputData } from '../demo.component.data';
import { ApiRequestService } from '../api-request.service';
import { DemoComponent } from '../demo.component';
import { ReaderBenchService } from '../../../readerbench.service';
import { EssayFeedbackData } from './essay-feedback.data';
import { Language } from '../languages.data';
@Component({
selector: 'app-demo-essay-feedback',
templateUrl: './essay-feedback.component.html',
styleUrls: ['./essay-feedback.component.css'],
providers: [ApiRequestService, ReaderBenchService]
})
export class EssayFeedbackComponent implements OnInit {
componentTitle: string;
formData: any;
@Input() advanced: boolean;
loading: boolean;
showResults: boolean;
languages: any;
language: any;
response: any;
score = 0;
defaultRoText = "Maturizarea literară a lui Mihail Sadoveanu a determinat îndepărtarea tot mai puternică a scriitorului de planurile concrete ale vieții și apropierea de istorie și natură pentru a găsi datele esențiale ale ființei etnice românești. Autorul permanentizează un spațiu și un timp arhaic nedefinit în care natura, omul și celelalte viețuitoare trăiesc într-o armonie aproape deplină după o înțelepciune primordială. Conflictul din Nopțile de Sânziene se rezumă la încercarea misterioasă de apărare a unei păduri în fața amenințării de a fi tăiată de un străin, putând fi asimilat cu un conflict între natură și antinatură sau mai concret între viață și moarte.";
constructor(private apiRequestService: ApiRequestService, private readerbenchService: ReaderBenchService) {
this.apiRequestService.setApiService(EssayFeedbackData.serviceName);
}
ngOnInit() {
this.componentTitle = EssayFeedbackData.componentTitle;
this.languages = EssayFeedbackData.languages;
this.language = EssayFeedbackData.defaultLanguage;
this.formData = {
'text': this.defaultRoText,
// 'language': DefaultInputData.defaultLanguage()
};
this.advanced = false;
this.loading = false;
this.showResults = false;
}
advancedEmitter($event) {
this.advanced = $event;
}
languageEmitter($event) {
this.language = $event;
}
process() {
this.loading = true;
this.showResults = false;
const data = {
'text': this.formData['text'],
// 'language': this.formData['language'].value
};
const process = this.apiRequestService.process(data);
process.subscribe(response => {
this.loading = false;
if (response.success !== true) {
alert('Server error occured!');
return;
}
this.response = response.data.feedback;
this.score = response.data.score;
this.showResults = true;
});
}
}
import { DefaultInputData } from '../demo.component.data';
export let EssayFeedbackData = {
'serviceName': 'essayFeedback',
'componentTitle': 'Essay Feedback',
'languages': [DefaultInputData.languages[3]],
'defaultLanguage': DefaultInputData.languages[3] // ro
};
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class EssayFeedbackModule { }
......@@ -99,5 +99,13 @@ export let DemoMenuItemsData = [
description: 'Sentiment Analysis',
image: 'assets/images/demo_sentiment_analysis.png',
altText: 'Sentiment Analysis with ReaderBench framework'
}
},
{
name: 'Essay Feedback',
href: 'demo/essay-feedback',
description: 'Essay Feedback',
image: 'assets/images/demo_essay_feedback.png',
altText: 'Essay Feedback with ReaderBench Framework',
language: 'Romanian'
},
];
......@@ -16,7 +16,10 @@
<h3 class="title">
<a href="{{item.href}}">{{item.name}}</a>
</h3>
<ul class="course-meta">
<ul *ngIf="item.language" class="course-meta">
<li><span>Languages</span> {{item.language}}</li>
</ul>
<ul *ngIf="!item.language" class="course-meta">
<li><span>Languages</span> English, French</li>
</ul>
<div class="course-action">
......
import { TestBed, inject } from '@angular/core/testing';
import { ApiRequestService } from './api-request.service';
describe('ApiRequestService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ApiRequestService]
});
});
it('should be created', inject([ApiRequestService], (service: ApiRequestService) => {
expect(service).toBeTruthy();
}));
});
import {Injectable} from '@angular/core';
import {Http, Response, Headers, RequestOptions} from '@angular/http';
import {HttpClientModule, HttpClient, HttpHeaders, HttpErrorResponse} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {catchError, retry, tap} from 'rxjs/operators';
import {ApiResponseModel} from './api-response.model';
import {ConfigService} from '../../config/config.service';
import {ReaderBenchService} from '../../readerbench.service';
import {Config} from '../../config/config.interface';
@Injectable()
export class ApiRequestService {
private endpoint: string;
private config: Config;
private error: string;
private serviceName: string;
private headers: any;
public readonly HEADERS_TYPE_COMMON_REQUEST = 1;
public readonly HEADERS_TYPE_FILE_UPLOAD = 2;
constructor(private http: HttpClient, private configService: ConfigService, private readerBenchService: ReaderBenchService) {
this.readConfig();
}
private readConfig() {
this.config = this.configService.getConfig();
// this.configService.getConfig()
// .subscribe(
// (data: Config) => this.config = {
// apiProtocol: data['apiProtocol'],
// apiServer: data['apiServer'],
// apiPort: data['apiPort'],
// apiPath: data['apiPath'],
// portDelimiter: data['portDelimiter'],
// pathDelimiter: data['pathDelimiter'],
// apiEndpoints: data['apiEndpoints'],
// commonEndpoints: data['commonEndpoints'],
// apiHeaders: data['apiHeaders']
// },
// error => this.error = error // error path
// );
}
public getApiEndpoint(): string {
if (this.config.apiEndpoints[this.serviceName] === undefined) {
return this.getMailServerEndpoint();
}
if (this.serviceName === 'curriculumRecommendation') {
return this.config.apiProtocol + this.config.portDelimiter + this.config.pathDelimiter + this.config.pathDelimiter +
this.config.apiServer +
this.config.pathDelimiter + this.config.apiPath + this.config.pathDelimiter +
this.config.apiEndpoints[this.serviceName];
}
return this.config.apiProtocol + this.config.portDelimiter + this.config.pathDelimiter + this.config.pathDelimiter +
this.config.apiServer +
((this.config.apiPort !== 80) ? (this.config.portDelimiter +
this.config.apiPort) : '') +
this.config.pathDelimiter + this.config.apiPath + this.config.pathDelimiter +
this.config.apiEndpoints[this.serviceName];
}
public getMailServerEndpoint(): string {
return this.config.apiProtocol + this.config.portDelimiter + this.config.pathDelimiter + this.config.pathDelimiter +
this.config.mailServer +
((this.config.mailPort !== 80) ? (this.config.portDelimiter +
this.config.mailPort) : '') +
this.config.pathDelimiter + this.config.mailPath + this.config.pathDelimiter +
this.config.commonEndpoints[this.serviceName];
}
public setApiService(serviceName: string) {
if (!this.config.apiEndpoints.hasOwnProperty(serviceName)) {
this.readerBenchService.logError('Config file does not contain an API endpoint for service ' + serviceName);
return;
}
this.serviceName = serviceName;
}
public setCommonService(serviceName: string) {
if (!this.config.commonEndpoints.hasOwnProperty(serviceName)) {
this.readerBenchService.logError('Config file does not contain a common endpoint for service ' + serviceName);
return;
}
this.serviceName = serviceName;
}
public setHeaders(type: number) {
if (this.config == null) {
this.readerBenchService.logError('Configuration data was not read!');
return;
}
switch (type) {
case this.HEADERS_TYPE_FILE_UPLOAD:
this.headers = this.config.apiHeaders['uploadRequest'];
break;
default:
this.headers = this.config.apiHeaders['commonRequest'];
break;
}
}
public getHeaders() {
return this.headers;
}
public upload(file) {
const formData = new FormData();
formData.append('file', file, file.name);
return this.process(formData);
}
public process(body: Object): Observable<ApiResponseModel> {
if (this.serviceName === '') {
this.readerBenchService.logError('The service name is not set!');
return;
}
if (this.headers === '') {
this.readerBenchService.logError('The service headers were not set!');
return;
}
const httpOptions = {
headers: this.headers
};
console.log(this.getApiEndpoint());
return this.http.post<ApiResponseModel>(this.getApiEndpoint(), body, httpOptions)
.pipe(
tap( // Log the result or error
data => data,
error => catchError(this.handleError) // then handle the error
)
);
}
public downloadFile(fileName) {
this.configService.getFile(fileName)
.subscribe(results => this.readerBenchService.log(results));
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
}
}
export class ApiResponseModel {
constructor(
public data: any,
public success: boolean,
public errorMsg: string
) { }
}
<div class="row">
<div class="page-wrapper">
<!-- <search-box></search-box> -->
<div id="page">
<app-header></app-header>
<!-- Main Content -->
<div class="content-wrapper">
<app-carousel></app-carousel>
<!-- Main Content -->
<div class="container">
<div class="section-header">
<h1>Experiments</h1>
</div>
<!-- <app-demo-menu></app-demo-menu> -->
</div>
<div class="content-wrapper">
<!-- <action-box></action-box> -->