Merge branch 'reports-check1' into 'develop'

Review reports 0,1

See merge request !186
parents 744c333c 4b643102
...@@ -147,7 +147,7 @@ epal.ministry.general_report: ...@@ -147,7 +147,7 @@ epal.ministry.general_report:
options: options:
_auth: [ 'basic_auth' ] _auth: [ 'basic_auth' ]
defaults: defaults:
_controller: '\Drupal\epal\Controller\ReportsCreator::makegGeneralReport' _controller: '\Drupal\epal\Controller\ReportsCreator::makeGeneralReport'
requirements: requirements:
_user_is_logged_in: 'TRUE' _user_is_logged_in: 'TRUE'
epal.ministry.report-completeness: epal.ministry.report-completeness:
......
...@@ -60,180 +60,189 @@ class ReportsCreator extends ControllerBase { ...@@ -60,180 +60,189 @@ class ReportsCreator extends ControllerBase {
); );
} }
public function makeReportUsers(Request $request) {
try {
if (!$request->isMethod('GET')) {
return $this->respondWithStatus([
"message" => t("Method Not Allowed")
], Response::HTTP_METHOD_NOT_ALLOWED);
}
public function makeReportUsers(Request $request) { //user validation
$authToken = $request->headers->get('PHP_AUTH_USER');
try { $users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
if (!$request->isMethod('GET')) { $user = reset($users);
return $this->respondWithStatus([ if (!$user) {
"message" => t("Method Not Allowed") return $this->respondWithStatus([
], Response::HTTP_METHOD_NOT_ALLOWED); 'message' => t("User not found"),
} ], Response::HTTP_FORBIDDEN);
}
//user validation
$authToken = $request->headers->get('PHP_AUTH_USER');
$users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
$user = reset($users);
if (!$user) {
return $this->respondWithStatus([
'message' => t("User not found"),
], Response::HTTP_FORBIDDEN);
}
//user role validation
$roles = $user->getRoles();
$validRole = false;
foreach ($roles as $role)
if ($role === "ministry") {
$validRole = true;
break;
}
if (!$validRole) {
return $this->respondWithStatus([
'message' => t("User Invalid Role"),
], Response::HTTP_FORBIDDEN);
}
$list = array();
//υπολογισμός αριθμού αιτήσεων
$sCon = $this->connection->select('epal_student', 'eStudent')
->fields('eStudent', array('id'));
$numApplications = $sCon->countQuery()->execute()->fetchField();
array_push($list,(object) array('name' => "Αριθμός Αιτήσεων (συνολικά)", 'numStudents' => $numApplications));
//υπολογισμός αριθμού αιτήσεων ανά τάξη
for ($i = 1; $i <= 4; $i++) {
$sCon = $this->connection->select('epal_student', 'eStudent')
->fields('eStudent', array('id'))
->condition('eStudent.currentclass', strval($i) , '=');
$numApplications = $sCon->countQuery()->execute()->fetchField();
array_push($list,(object) array('name' => "Αριθμός Αιτήσεων για " . $i . "η Τάξη", 'numStudents' => $numApplications));
}
//υπολογισμός αριθμού αιτήσεων για δεύτερη περίοδο //user role validation
$sCon = $this->connection->select('epal_student', 'eStudent') $roles = $user->getRoles();
->fields('eStudent', array('id')) $validRole = false;
->condition('eStudent.second_period', 1 , '='); foreach ($roles as $role)
$numApplications = $sCon->countQuery()->execute()->fetchField(); if ($role === "ministry") {
array_push($list,(object) array('name' => "Αριθμός Αιτήσεων B' περιόδου", 'numStudents' => $numApplications)); $validRole = true;
break;
//υπολογισμός αριθμού χρηστών
$sCon = $this->connection->select('epal_users', 'eUser')
->fields('eUser', array('id'));
$numUsers = $sCon->countQuery()->execute()->fetchField();
array_push($list,(object) array('name' => "Αριθμός Εγγεγραμένων Χρηστών με ρόλο Αιτούντα", 'numStudents' => $numUsers));
return $this->respondWithStatus(
$list
, Response::HTTP_OK);
} //end try
catch (\Exception $e) {
$this->logger->warning($e->getMessage());
return $this->respondWithStatus([
"message" => t("An unexpected problem occured during makegGeneralReport Method")
], Response::HTTP_INTERNAL_SERVER_ERROR);
} }
if (!$validRole) {
return $this->respondWithStatus([
'message' => t("User Invalid Role"),
], Response::HTTP_FORBIDDEN);
}
$list = array();
//υπολογισμός αριθμού αιτήσεων
$sCon = $this->connection
->select('epal_student', 'eStudent')
->fields('eStudent', array('id'));
$numApplications = $sCon->countQuery()->execute()->fetchField();
array_push($list,(object) array('name' => "Αριθμός Αιτήσεων (συνολικά)", 'numStudents' => $numApplications));
//υπολογισμός αριθμού αιτήσεων ανά τάξη
$classes = [1 => 'Α', 2 => 'Β', 3 => 'Γ', 4 => 'Δ'];
foreach ($classes as $i => $label) {
$sCon = $this->connection
->select('epal_student', 'eStudent')
->fields('eStudent', array('id'))
->condition('eStudent.currentclass', strval($i) , '=');
$numApplications = $sCon->countQuery()->execute()->fetchField();
array_push($list,(object) array('name' => "Αριθμός Αιτήσεων για {$label} Τάξη", 'numStudents' => $numApplications));
} }
//υπολογισμός αριθμού αιτήσεων για δεύτερη περίοδο
$sCon = $this->connection
->select('epal_student', 'eStudent')
->fields('eStudent', array('id'))
->condition('eStudent.second_period', 1 , '=');
$numApplications = $sCon->countQuery()->execute()->fetchField();
array_push($list,(object) array('name' => "Αριθμός Αιτήσεων B' περιόδου", 'numStudents' => $numApplications));
//υπολογισμός αριθμού χρηστών
$sCon = $this->connection
->select('epal_users', 'eUser')
->fields('eUser', array('id'));
$numUsers = $sCon->countQuery()->execute()->fetchField();
array_push($list,(object) array('name' => "Αριθμός Εγγεγραμένων Χρηστών με ρόλο Αιτούντα", 'numStudents' => $numUsers));
return $this->respondWithStatus($list, Response::HTTP_OK);
} //end try
catch (\Exception $e) {
$this->logger->warning($e->getMessage());
return $this->respondWithStatus([
"message" => t("An unexpected problem occured during report")
], Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
public function makegGeneralReport(Request $request) {
try {
if (!$request->isMethod('GET')) {
return $this->respondWithStatus([
"message" => t("Method Not Allowed")
], Response::HTTP_METHOD_NOT_ALLOWED);
}
//user validation public function makeGeneralReport(Request $request) {
$authToken = $request->headers->get('PHP_AUTH_USER');
$users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
$user = reset($users);
if (!$user) {
return $this->respondWithStatus([
'message' => t("User not found"),
], Response::HTTP_FORBIDDEN);
}
//user role validation try {
$roles = $user->getRoles(); if (!$request->isMethod('GET')) {
$validRole = false; return $this->respondWithStatus([
foreach ($roles as $role) "message" => t("Method Not Allowed")
if ($role === "ministry") { ], Response::HTTP_METHOD_NOT_ALLOWED);
$validRole = true; }
break;
}
if (!$validRole) {
return $this->respondWithStatus([
'message' => t("User Invalid Role"),
], Response::HTTP_FORBIDDEN);
}
//υπολογισμός αριθμού δηλώσεων
$sCon = $this->connection->select('epal_student', 'eStudent')
->fields('eStudent', array('id'));
$numTotal = $sCon->countQuery()->execute()->fetchField();
//υπολογισμός αριθμού δηλώσεων που ικανοποιήθηκαν στην i προτίμηση
$numData = array();
for ($i=0; $i < 3; $i++) {
$sCon = $this->connection->select('epal_student_class', 'eStudent')
->fields('eStudent', array('id', 'distribution_id'))
->condition('eStudent.distribution_id', $i+1, '=')
->condition('eStudent.finalized', 1 , '=');
array_push($numData, $sCon->countQuery()->execute()->fetchField());
}
// υπολογισμός αριθμού δηλώσεων που ΔΕΝ ικανοποιήθηκαν
//Σημείωση: υπολογισμός με queries στη βάση
$sCon = $this->connection->select('epal_student_class', 'eStudent')
->fields('eStudent', array('student_id'));
$epalStudents = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
$studentIds = array();
foreach ($epalStudents as $epalStudent)
array_push($studentIds, $epalStudent->student_id);
$sCon = $this->connection->select('epal_student', 'eStudent')
->fields('eStudent', array('id'))
->condition('eStudent.id', $studentIds, 'NOT IN');
$numNoAllocated = $sCon->countQuery()->execute()->fetchField();
//υπολογισμός αριθμού δηλώσεων που τοποθετήθηκαν προσωρινά σε ολιγομελή τμήματα
$numInSmallClasses = 0;
$sCon = $this->connection->select('epal_student_class', 'eStudent')
->fields('eStudent', array('id'))
->condition('eStudent.finalized', 0 , '=');
$numInSmallClasses = $sCon->countQuery()->execute()->fetchField();
$list = array();
array_push($list,(object) array('name' => "Αριθμός Δηλώσεων Προτίμησης", 'numStudents' => $numTotal));
array_push($list,(object) array('name' => "Αριθμός μαθητών που τοποθετήθηκαν στην πρώτη τους προτίμηση", 'numStudents' => $numData[0]));
array_push($list,(object) array('name' => "Αριθμός μαθητών που τοποθετήθηκαν στην δεύτερή τους προτίμηση", 'numStudents' => $numData[1]));
array_push($list,(object) array('name' => "Αριθμός μαθητών που τοποθετήθηκαν στην τρίτη τους προτίμηση", 'numStudents' => $numData[2]));
array_push($list,(object) array('name' => "Αριθμός μαθητών που δεν τοποθετήθηκαν σε καμμία τους προτίμηση", 'numStudents' => $numNoAllocated));
array_push($list,(object) array('name' => "Αριθμός μαθητών που τοποθετήθηκαν προσωρινά σε ολιγομελή τμήματα", 'numStudents' => $numInSmallClasses));
return $this->respondWithStatus( //user validation
$list $authToken = $request->headers->get('PHP_AUTH_USER');
, Response::HTTP_OK); $users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
} //end try $user = reset($users);
if (!$user) {
return $this->respondWithStatus([
'message' => t("User not found"),
], Response::HTTP_FORBIDDEN);
}
catch (\Exception $e) { //user role validation
$this->logger->warning($e->getMessage()); $roles = $user->getRoles();
$validRole = false;
foreach ($roles as $role)
if ($role === "ministry") {
$validRole = true;
break;
}
if (!$validRole) {
return $this->respondWithStatus([ return $this->respondWithStatus([
"message" => t("An unexpected problem occured during makegGeneralReport Method") 'message' => t("User Invalid Role"),
], Response::HTTP_INTERNAL_SERVER_ERROR); ], Response::HTTP_FORBIDDEN);
}
//υπολογισμός αριθμού δηλώσεων
$sCon = $this->connection
->select('epal_student', 'eStudent')
->fields('eStudent', array('id'));
$numTotal = $sCon->countQuery()->execute()->fetchField();
//υπολογισμός αριθμού δηλώσεων που ικανοποιήθηκαν στην i προτίμηση
$numData = array();
for ($i=0; $i < 3; $i++) {
$sCon = $this->connection
->select('epal_student_class', 'eStudent')
->fields('eStudent', array('id', 'distribution_id'))
->condition('eStudent.distribution_id', $i+1, '=')
->condition('eStudent.finalized', 1 , '=');
array_push($numData, $sCon->countQuery()->execute()->fetchField());
} }
// υπολογισμός αριθμού δηλώσεων που ΔΕΝ ικανοποιήθηκαν
/*
$sCon = $this->connection
->select('epal_student_class', 'eStudent')
->fields('eStudent', array('student_id'));
$epalStudents = $sCon->execute()->fetchAll(\PDO::FETCH_OBJ);
$studentIds = array();
foreach ($epalStudents as $epalStudent)
array_push($studentIds, $epalStudent->student_id);
$sCon = $this->connection
->select('epal_student', 'eStudent')
->fields('eStudent', array('id'))
->condition('eStudent.id', $studentIds, 'NOT IN');
$numNoAllocated = $sCon->countQuery()->execute()->fetchField();
*/
$sCon = $this->connection->select('epal_student', 'epalStudent');
$sCon->leftJoin('epal_student_class', 'eStudent', 'eStudent.student_id = epalStudent.id');
$sCon->fields('eStudent', array('student_id'))
->fields('epalStudent', array('id'))
->isNull('eStudent.student_id');
$numNoAllocated = $sCon->countQuery()->execute()->fetchField();
//υπολογισμός αριθμού δηλώσεων που τοποθετήθηκαν προσωρινά σε ολιγομελή τμήματα
$numInSmallClasses = 0;
$sCon = $this->connection
->select('epal_student_class', 'eStudent')
->fields('eStudent', array('id'))
->condition('eStudent.finalized', 0 , '=');
$numInSmallClasses = $sCon->countQuery()->execute()->fetchField();
$list = array(
array('name' => "Αριθμός Δηλώσεων Προτίμησης", 'numStudents' => $numTotal),
array('name' => "Αριθμός μαθητών που τοποθετήθηκαν στην πρώτη τους προτίμηση", 'numStudents' => $numData[0]),
array('name' => "Αριθμός μαθητών που τοποθετήθηκαν στην δεύτερή τους προτίμηση", 'numStudents' => $numData[1]),
array('name' => "Αριθμός μαθητών που τοποθετήθηκαν στην τρίτη τους προτίμηση", 'numStudents' => $numData[2]),
array('name' => "Αριθμός μαθητών που δεν τοποθετήθηκαν σε καμμία τους προτίμηση", 'numStudents' => $numNoAllocated),
array('name' => "Αριθμός μαθητών που τοποθετήθηκαν προσωρινά σε ολιγομελή τμήματα", 'numStudents' => $numInSmallClasses)
);
return $this->respondWithStatus($list, Response::HTTP_OK);
} //end try
catch (\Exception $e) {
$this->logger->warning($e->getMessage());
return $this->respondWithStatus([
"message" => t("An unexpected problem occured during report")
], Response::HTTP_INTERNAL_SERVER_ERROR);
} }
}
public function makeReportCompleteness(Request $request, $regionId, $adminId, $schId) { public function makeReportCompleteness(Request $request, $regionId, $adminId, $schId) {
...@@ -1048,14 +1057,9 @@ class ReportsCreator extends ControllerBase { ...@@ -1048,14 +1057,9 @@ class ReportsCreator extends ControllerBase {
} }
private function respondWithStatus($arr, $s) { private function respondWithStatus($arr, $s) {
$res = new JsonResponse($arr); $res = new JsonResponse($arr);
$res->setStatusCode($s); $res->setStatusCode($s);
return $res; return $res;
} }
} }
import { Component, OnInit, OnDestroy } from "@angular/core"; import { Component, OnInit, OnDestroy } from "@angular/core";
import { Injectable } from "@angular/core"; import { Injectable } from "@angular/core";
import { AppSettings } from '../../app.settings'; import { AppSettings } from "../../app.settings";
import { HelperDataService } from '../../services/helper-data-service'; import { HelperDataService } from "../../services/helper-data-service";
import { Observable} from "rxjs/Observable"; import { Observable} from "rxjs/Observable";
import { Http, Headers, RequestOptions} from '@angular/http'; import { Http, Headers, RequestOptions} from "@angular/http";
import { NgRedux, select } from 'ng2-redux'; import { NgRedux, select } from "ng2-redux";
import { IAppState } from '../../store/store'; import { IAppState } from "../../store/store";
import { Router, ActivatedRoute, Params} from '@angular/router'; import { Router, ActivatedRoute, Params} from "@angular/router";
import { BehaviorSubject, Subscription } from 'rxjs/Rx'; import { BehaviorSubject, Subscription } from "rxjs/Rx";
import { ILoginInfo } from '../../store/logininfo/logininfo.types'; import { ILoginInfo } from "../../store/logininfo/logininfo.types";
import { LOGININFO_INITIAL_STATE } from '../../store/logininfo/logininfo.initial-state'; import { LOGININFO_INITIAL_STATE } from "../../store/logininfo/logininfo.initial-state";
import { MINISTRY_ROLE, PDE_ROLE, DIDE_ROLE } from '../../constants'; import { MINISTRY_ROLE, PDE_ROLE, DIDE_ROLE } from "../../constants";
import { import {
FormBuilder, FormBuilder,
...@@ -18,13 +18,13 @@ import { ...@@ -18,13 +18,13 @@ import {
FormControl, FormControl,
FormArray, FormArray,
Validators, Validators,
} from '@angular/forms'; } from "@angular/forms";
import { API_ENDPOINT } from '../../app.settings'; import { API_ENDPOINT } from "../../app.settings";
@Component({ @Component({
selector: 'minister-reports', selector: "minister-reports",
//encapsulation: ViewEncapsulation.None, // encapsulation: ViewEncapsulation.None,
template: ` template: `
...@@ -35,34 +35,6 @@ import { API_ENDPOINT } from '../../app.settings'; ...@@ -35,34 +35,6 @@ import { API_ENDPOINT } from '../../app.settings';
<div class="col-md-1"> <div class="col-md-1">
<!--
<button type="button" class="btn btn-alert" (click)="nav_to_reportpath(1)" [hidden]="minedu_userName == '' || userRole == 'pde' || userRole == 'dide'" >
<i class="fa fa-file-text"></i>
Κατανομή Μαθητών με Βάση τη Σειρά Προτίμησης
</button>
<br><br>
<button type="button" class="btn btn-alert" (click)="nav_to_reportpath(2)" [hidden]="minedu_userName == ''" >
<i class="fa fa-file-text"></i>
Συνολική Πληρότητα σχολικών μονάδων ΕΠΑΛ ανά τάξη
</button>
<br><br>
<button type="button" class="btn btn-alert" (click)="nav_to_reportpath(3)" [hidden]="minedu_userName == ''" >
<i class="fa fa-file-text"></i>
Αριθμός Μαθητών και Πληρότητα σχολικών μονάδων ΕΠΑΛ
</button>
<br><br>
<button type="button" class="btn btn-alert" (click)="nav_to_reportpath(4)" [hidden]="minedu_userName == '' || userRole == 'pde' || userRole == 'dide' " >
<i class="fa fa-file-text"></i>
Σχολικές μονάδες που δεν έχουν δηλώσει Χωρητικότητα τμημάτων
</button>
<br><br>
<button type="button" class="btn btn-alert" (click)="nav_to_reportpath(5)" [hidden]="minedu_userName == '' || userRole == 'pde' || userRole == 'dide' " >
<i class="fa fa-file-text"></i>
Ολιγομελή τμήματα (Προσωρινά τοποθετημένοι μαθητές)
</button>
<br><br>
</div>
-->
<div *ngIf = "minedu_userName != '' && userRole != 'pde' && userRole != 'dide'"> <div *ngIf = "minedu_userName != '' && userRole != 'pde' && userRole != 'dide'">
<button type="button" class="btn btn-alert" (click)="nav_to_reportpath(0)" > <button type="button" class="btn btn-alert" (click)="nav_to_reportpath(0)" >
<i class="fa fa-file-text"></i> <i class="fa fa-file-text"></i>
...@@ -131,13 +103,13 @@ import { API_ENDPOINT } from '../../app.settings'; ...@@ -131,13 +103,13 @@ import { API_ENDPOINT } from '../../app.settings';
private router: Router) { private router: Router) {
this.formGroup = this.fb.group({ this.formGroup = this.fb.group({
region: ['', []], region: ["", []],
adminarea: ['', []], adminarea: ["", []],
schoollist: ['', []], schoollist: ["", []],
}); });
this.loginInfo$ = new BehaviorSubject(LOGININFO_INITIAL_STATE); this.loginInfo$ = new BehaviorSubject(LOGININFO_INITIAL_STATE);
this.minedu_userName = ''; this.minedu_userName = "";
this.userRole = MINISTRY_ROLE; this.userRole = MINISTRY_ROLE;
} }
...@@ -149,7 +121,7 @@ import { API_ENDPOINT } from '../../app.settings'; ...@@ -149,7 +121,7 @@ import { API_ENDPOINT } from '../../app.settings';
state.loginInfo.reduce(({}, loginInfoToken) => { state.loginInfo.reduce(({}, loginInfoToken) => {
this.minedu_userName = loginInfoToken.minedu_username; this.minedu_userName = loginInfoToken.minedu_username;
this.minedu_userPassword = loginInfoToken.minedu_userpassword; this.minedu_userPassword = loginInfoToken.minedu_userpassword;
if (loginInfoToken.auth_role == PDE_ROLE || loginInfoToken.auth_role == DIDE_ROLE) { if (loginInfoToken.auth_role === PDE_ROLE || loginInfoToken.auth_role === DIDE_ROLE) {
this.userRole = loginInfoToken.auth_role; this.userRole = loginInfoToken.auth_role;
this.minedu_userName = loginInfoToken.auth_token; this.minedu_userName = loginInfoToken.auth_token;
this.minedu_userPassword = loginInfoToken.auth_token; this.minedu_userPassword = loginInfoToken.auth_token;
...@@ -163,25 +135,24 @@ import { API_ENDPOINT } from '../../app.settings'; ...@@ -163,25 +135,24 @@ import { API_ENDPOINT } from '../../app.settings';
} }
ngOnDestroy() { ngOnDestroy() {
if (this.loginInfoSub) {
if (this.loginInfoSub)
this.loginInfoSub.unsubscribe(); this.loginInfoSub.unsubscribe();
if (this.loginInfo$) }
if (this.loginInfo$) {
this.loginInfo$.unsubscribe(); this.loginInfo$.unsubscribe();
}
} }
nav_to_reportpath(repId) { nav_to_reportpath(repId) {
if (repId === 0) {
if (repId == 0) this.router.navigate(["/ministry/report-users", repId]);
this.router.navigate(['/ministry/report-users', repId]); } else if (repId === 1) {
if (repId == 1) this.router.navigate(["/ministry/report-general"]);
this.router.navigate(['/ministry/report-general', repId]); } else if (repId === 2 || repId === 3 || repId === 5) {
else if (repId == 2 || repId == 3 || repId == 5) this.router.navigate(["/ministry/report-all-stat", repId]);
this.router.navigate(['/ministry/report-all-stat', repId]); } else if (repId === 4) {
else if (repId == 4) this.router.navigate(["/ministry/report-no-capacity", repId]);
this.router.navigate(['/ministry/report-no-capacity', repId]); }
} }
} }
import { Component, OnInit, OnDestroy, ElementRef, ViewChild, Input } from "@angular/core"; import { Component, OnInit, OnDestroy, ElementRef, ViewChild, Input } from "@angular/core";
import { Injectable } from "@angular/core"; import { Injectable } from "@angular/core";
import { AppSettings } from '../../app.settings'; import { AppSettings } from "../../app.settings";
import { HelperDataService } from '../../services/helper-data-service'; import { HelperDataService } from "../../services/helper-data-service";
import { Observable} from "rxjs/Observable"; import { Observable } from "rxjs/Observable";
import { Http, Headers, RequestOptions} from '@angular/http'; import { Http, Headers, RequestOptions } from "@angular/http";
import { NgRedux, select } from 'ng2-redux'; import { NgRedux, select } from "ng2-redux";
import { IAppState } from '../../store/store'; import { IAppState } from "../../store/store";
import { Router, ActivatedRoute, Params} from '@angular/router'; import { Router, ActivatedRoute, Params } from "@angular/router";
import { BehaviorSubject, Subscription } from 'rxjs/Rx'; import { BehaviorSubject, Subscription } from "rxjs/Rx";
import { ILoginInfo } from '../../store/logininfo/logininfo.types'; import { ILoginInfo } from "../../store/logininfo/logininfo.types";
import { Ng2SmartTableModule, LocalDataSource } from 'ng2-smart-table'; import { Ng2SmartTableModule, LocalDataSource } from "ng2-smart-table";
import {reportsSchema, TableColumn} from './reports-schema'; import { reportsSchema, TableColumn } from "./reports-schema";
import { LOGININFO_INITIAL_STATE } from '../../store/logininfo/logininfo.initial-state'; import { LOGININFO_INITIAL_STATE } from "../../store/logininfo/logininfo.initial-state";
import {csvCreator} from './csv-creator'; import { csvCreator } from "./csv-creator";
import {chartCreator} from './chart-creator'; import { chartCreator } from "./chart-creator";
import {