Skip to content
Snippets Groups Projects
results.component.ts 11.2 KiB
Newer Older
import { LogData } from '../workspace.interfaces';
import { WorkspaceDataService } from '../workspacedata.service';
paf's avatar
paf committed
import { ConfirmDialogComponent, ConfirmDialogData } from 'iqb-components';
mechtelm's avatar
mechtelm committed
import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core';
import { BackendService } from '../backend.service';
paf's avatar
paf committed
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { SelectionModel } from '@angular/cdk/collections';
Martin Mechtel's avatar
Martin Mechtel committed
import { saveAs } from 'file-saver';
Martin Mechtel's avatar
Martin Mechtel committed
import { ResultData, UnitResponse, ReviewData } from '../workspace.interfaces';
mechtelm's avatar
mechtelm committed
import { Subscription } from 'rxjs';

@Component({
  templateUrl: './results.component.html',
  styleUrls: ['./results.component.css']
})
mechtelm's avatar
mechtelm committed
export class ResultsComponent implements OnInit, OnDestroy {
  displayedColumns: string[] = ['selectCheckbox', 'groupname', 'bookletsStarted', 'num_units_min', 'num_units_max', 'num_units_mean', 'lastchange'];
mechtelm's avatar
mechtelm committed
  public resultDataSource = new MatTableDataSource<ResultData>([]);
Martin Mechtel's avatar
Martin Mechtel committed
  // prepared for selection if needed sometime
mechtelm's avatar
mechtelm committed
  public tableselectionCheckbox = new SelectionModel<ResultData>(true, []);
  public dataLoading = false;
mechtelm's avatar
mechtelm committed
  private workspaceIdSubscription: Subscription = null;
paf's avatar
paf committed
  @ViewChild(MatSort, { static: true }) sort: MatSort;
mechtelm's avatar
mechtelm committed
    public wds: WorkspaceDataService,
    private deleteConfirmDialog: MatDialog,
Martin Mechtel's avatar
Martin Mechtel committed
  ) { }
    this.workspaceIdSubscription = this.wds.workspaceId$.subscribe(() => {
mechtelm's avatar
mechtelm committed
      this.updateTable();
    });
Martin Mechtel's avatar
Martin Mechtel committed
  updateTable() {
    this.tableselectionCheckbox.clear();
mechtelm's avatar
mechtelm committed
    if (this.wds.wsRole === 'MO') {
      this.resultDataSource = new MatTableDataSource<ResultData>([]);
    } else {
      this.dataLoading = true;
      this.bs.getResultData(this.wds.ws).subscribe(
mechtelm's avatar
mechtelm committed
        (resultData: ResultData[]) => {
          this.dataLoading = false;
          this.resultDataSource = new MatTableDataSource<ResultData>(resultData);
          this.resultDataSource.sort = this.sort;
        }
paf's avatar
paf committed
      );
mechtelm's avatar
mechtelm committed
    }
  isAllSelected() {
    const numSelected = this.tableselectionCheckbox.selected.length;
Martin Mechtel's avatar
Martin Mechtel committed
    const numRows = this.resultDataSource.data.length;
    return numSelected === numRows;
  }

  masterToggle() {
    this.isAllSelected() ?
        this.tableselectionCheckbox.clear() :
Martin Mechtel's avatar
Martin Mechtel committed
        this.resultDataSource.data.forEach(row => this.tableselectionCheckbox.select(row));
Martin Mechtel's avatar
Martin Mechtel committed
  // 444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
  downloadResponsesCSV() {
    if (this.tableselectionCheckbox.selected.length > 0) {
      this.dataLoading = true;
      const selectedGroups: string[] = [];
      this.tableselectionCheckbox.selected.forEach(element => {
        selectedGroups.push(element.groupname);
      });
      this.bs.getResponses(this.wds.ws, selectedGroups).subscribe(
Martin Mechtel's avatar
Martin Mechtel committed
      (responseData: UnitResponse[]) => {
        if (responseData.length > 0) {
          const columnDelimiter = ';';
          const lineDelimiter = '\n';
paf's avatar
paf committed
          let myCsvData = 'groupname' + columnDelimiter
              + 'loginname' + columnDelimiter
              + 'code' + columnDelimiter
              + 'bookletname' + columnDelimiter
              + 'unitname' + columnDelimiter
              + 'responses' + columnDelimiter
              + 'restorePoint' + columnDelimiter
              + 'responseType' + columnDelimiter
              + 'response-ts' + columnDelimiter
              + 'restorePoint-ts' + columnDelimiter
              + 'laststate' + lineDelimiter;
Martin Mechtel's avatar
Martin Mechtel committed
          responseData.forEach((resp: UnitResponse) => {
paf's avatar
paf committed
            myCsvData += '"' + resp.groupname + '"' + columnDelimiter
                + '"' + resp.loginname + '"' + columnDelimiter
                + '"' + resp.code + '"' + columnDelimiter
                + '"' + resp.bookletname + '"' + columnDelimiter
                + '"' + resp.unitname + '"' + columnDelimiter;
Martin Mechtel's avatar
Martin Mechtel committed
            if ((resp.responses !== null) && (resp.responses.length > 0)) {
Martin Mechtel's avatar
Martin Mechtel committed
              myCsvData += resp.responses.replace(/\\"/g, '""') + columnDelimiter;
            } else {
              myCsvData += columnDelimiter;
            }
            if ((resp.restorepoint !== null) && (resp.restorepoint.length > 0)) {
              myCsvData += resp.restorepoint.replace(/\\"/g, '""') + columnDelimiter;
            } else {
              myCsvData += columnDelimiter;
            }
            if ((resp.responsetype !== null) && (resp.responsetype.length > 0)) {
              myCsvData += '"' + resp.responsetype + '"' + columnDelimiter;
            } else {
              myCsvData += columnDelimiter;
            }
            myCsvData += resp.responses_ts + columnDelimiter + resp.restorepoint_ts + columnDelimiter;
            if ((resp.laststate !== null) && (resp.laststate.length > 0)) {
              myCsvData += '"' + resp.laststate + '"' + lineDelimiter;
Martin Mechtel's avatar
Martin Mechtel committed
            } else {
              myCsvData += lineDelimiter;
Martin Mechtel's avatar
Martin Mechtel committed
            }
          });
paf's avatar
paf committed
          const blob = new Blob([myCsvData], {type: 'text/csv;charset=utf-8'});
          saveAs(blob, 'iqb-testcenter-responses.csv');
Martin Mechtel's avatar
Martin Mechtel committed
        } else {
          this.snackBar.open('Keine Daten verfügbar.', 'Fehler', {duration: 3000});
        }
        this.tableselectionCheckbox.clear();
        this.dataLoading = false;
paf's avatar
paf committed
    });
Martin Mechtel's avatar
Martin Mechtel committed
    }
  }
Martin Mechtel's avatar
Martin Mechtel committed
  // 444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
  downloadReviewsCSV() {
    if (this.tableselectionCheckbox.selected.length > 0) {
      this.dataLoading = true;
      const selectedGroups: string[] = [];
      this.tableselectionCheckbox.selected.forEach(element => {
        selectedGroups.push(element.groupname);
      });
      this.bs.getReviews(this.wds.ws, selectedGroups).subscribe(
Martin Mechtel's avatar
Martin Mechtel committed
      (responseData: ReviewData[]) => {
        if (responseData.length > 0) {
          // collect categories
          const allCategories: string[] = [];
          responseData.forEach((resp: ReviewData) => {
            resp.categories.split(' ').forEach(s => {
              const s_trimmed = s.trim();
              if (s_trimmed.length > 0) {
                if (!allCategories.includes(s_trimmed)) {
                  allCategories.push(s_trimmed);
                }
              }
paf's avatar
paf committed
            });
Martin Mechtel's avatar
Martin Mechtel committed
          });

          const columnDelimiter = ';';
          const lineDelimiter = '\n';
          let myCsvData = 'groupname' + columnDelimiter + 'loginname' + columnDelimiter + 'code' + columnDelimiter +
              'bookletname' + columnDelimiter + 'unitname' + columnDelimiter +
              'priority' + columnDelimiter;
          allCategories.forEach(s => {
            myCsvData += 'category: ' + s + columnDelimiter;
          });
          myCsvData += 'reviewtime' + columnDelimiter + 'entry' + lineDelimiter;

          responseData.forEach((resp: ReviewData) => {
            if ((resp.entry !== null) && (resp.entry.length > 0)) {
              myCsvData += '"' + resp.groupname + '"' + columnDelimiter + '"' + resp.loginname + '"' +
                columnDelimiter + '"' + resp.code + '"' + columnDelimiter + '"' + resp.bookletname + '"' +
                columnDelimiter + '"' + resp.unitname + '"' + columnDelimiter  + '"' +
                resp.priority  + '"' + columnDelimiter;
Martin Mechtel's avatar
Martin Mechtel committed
              const resp_categories = resp.categories.split(' ');
              allCategories.forEach(s => {
                if (resp_categories.includes(s)) {
                  myCsvData += '"X"' + columnDelimiter;
                } else {
                  myCsvData += columnDelimiter;
                }
              });
              myCsvData += '"' + resp.reviewtime + '"' + columnDelimiter  + '"' +  resp.entry  + '"' + lineDelimiter;
            }
          });
paf's avatar
paf committed
          const blob = new Blob([myCsvData], {type: 'text/csv;charset=utf-8'});
          saveAs(blob, 'iqb-testcenter-reviews.csv');
Martin Mechtel's avatar
Martin Mechtel committed
        } else {
          this.snackBar.open('Keine Daten verfügbar.', 'Fehler', {duration: 3000});
        }
        this.tableselectionCheckbox.clear();
        this.dataLoading = false;
paf's avatar
paf committed
      });
Martin Mechtel's avatar
Martin Mechtel committed
    }
Martin Mechtel's avatar
Martin Mechtel committed
  // 444444444444444444444444444444444444444444444444444444444444444444444444444444444444444
  downloadLogsCSV() {
    if (this.tableselectionCheckbox.selected.length > 0) {
      this.dataLoading = true;
      const selectedGroups: string[] = [];
      this.tableselectionCheckbox.selected.forEach(element => {
        selectedGroups.push(element.groupname);
      });
      this.bs.getLogs(this.wds.ws, selectedGroups).subscribe(
Martin Mechtel's avatar
Martin Mechtel committed
      (responseData: LogData[]) => {
        if (responseData.length > 0) {
          const columnDelimiter = ';';
          const lineDelimiter = '\n';
          let myCsvData = 'groupname' + columnDelimiter + 'loginname' + columnDelimiter + 'code' + columnDelimiter +
              'bookletname' + columnDelimiter + 'unitname' + columnDelimiter +
              'timestamp' + columnDelimiter + 'logentry' + lineDelimiter;
Martin Mechtel's avatar
Martin Mechtel committed
          responseData.forEach((resp: LogData) => {
            if ((resp.logentry !== null) && (resp.logentry.length > 0)) {
             myCsvData += '"' + resp.groupname + '"' + columnDelimiter + '"' + resp.loginname + '"' + columnDelimiter + '"' + resp.code + '"' + columnDelimiter +
              '"' + resp.bookletname + '"' + columnDelimiter + '"' + resp.unitname + '"' + columnDelimiter  + '"' +
              resp.timestamp.toString() + '"' + columnDelimiter  + resp.logentry.replace(/\\"/g, '""')  + lineDelimiter;
Martin Mechtel's avatar
Martin Mechtel committed
            }
          });
paf's avatar
paf committed
          const blob = new Blob([myCsvData], {type: 'text/csv;charset=utf-8'});
          saveAs(blob, 'iqb-testcenter-logs.csv');
Martin Mechtel's avatar
Martin Mechtel committed
        } else {
          this.snackBar.open('Keine Daten verfügbar.', 'Fehler', {duration: 3000});
        }
        this.tableselectionCheckbox.clear();
        this.dataLoading = false;
paf's avatar
paf committed
      });
Martin Mechtel's avatar
Martin Mechtel committed
    }
  }

  deleteData() {
    if (this.tableselectionCheckbox.selected.length > 0) {
      const selectedGroups: string[] = [];
      this.tableselectionCheckbox.selected.forEach(element => {
        selectedGroups.push(element.groupname);
      });

      let prompt = 'Es werden alle Antwort- und Logdaten in der Datenbank für diese ';
      if (selectedGroups.length > 1) {
        prompt = prompt + selectedGroups.length + ' Gruppen ';
      } else {
        prompt = prompt + ' Gruppe "' + selectedGroups[0] + '" ';
      }

      const dialogRef = this.deleteConfirmDialog.open(ConfirmDialogComponent, {
        width: '400px',
        data: <ConfirmDialogData>{
          title: 'Löschen von Gruppendaten',
          content: prompt + 'gelöscht. Fortsetzen?',
          confirmbuttonlabel: 'Gruppendaten löschen',
          showcancel: true
        }
      });

      dialogRef.afterClosed().subscribe(result => {
        if (result !== false) {
          // =========================================================
          this.dataLoading = true;
          this.bs.deleteData(this.wds.ws, selectedGroups).subscribe(() => {
              this.tableselectionCheckbox.clear();
              this.dataLoading = false;
              // TODO refresh list!
            });
mechtelm's avatar
mechtelm committed

  // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
  ngOnDestroy() {
    if (this.workspaceIdSubscription !== null) {
      this.workspaceIdSubscription.unsubscribe();
    }
  }