ExcelWorksheet.ts 3.85 KB
Newer Older
Fullarton's avatar
Fullarton committed
1 2
import * as xlsx from 'excel4node';
import * as MessageFormat from 'messageformat';
3
import { Document } from 'mongoose';
4
import MemberDAO from '../db/MemberDAO';
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
5
import { ILeaderBoardItemBase } from '../interfaces/leaderboard/ILeaderBoardItemBase';
6
import { IQuizBase } from '../interfaces/quizzes/IQuizEntity';
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
7
import { Leaderboard } from '../lib/leaderboard/leaderboard';
8
import { MemberModelItem } from '../models/member/MemberModel';
9
import { excelDefaultWorksheetOptions } from './lib/excel_default_options';
Fullarton's avatar
Fullarton committed
10

11
import { ExcelTheme } from './lib/excel_default_styles';
Fullarton's avatar
Fullarton committed
12 13 14 15 16

export abstract class ExcelWorksheet {
  get columnsToFormat(): number {
    return this._columnsToFormat;
  }
17

18
  get quiz(): IQuizBase {
Fullarton's avatar
Fullarton committed
19 20
    return this._quiz;
  }
21

Fullarton's avatar
Fullarton committed
22 23 24
  get createdAt(): string {
    return this._createdAt;
  }
25

26
  get mf(): MessageFormat.Msg {
Fullarton's avatar
Fullarton committed
27 28
    return this._mf;
  }
29

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
30
  protected _leaderBoardData: Array<ILeaderBoardItemBase>;
31

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
32
  get leaderBoardData(): Array<ILeaderBoardItemBase> {
33 34 35 36 37
    return this._leaderBoardData;
  }

  protected _ws: xlsx.Worksheet;

Fullarton's avatar
Fullarton committed
38 39 40
  get ws(): xlsx.Worksheet {
    return this._ws;
  }
41

42 43 44 45 46 47
  private _responsesWithConfidenceValue: Array<Document & MemberModelItem>;

  get responsesWithConfidenceValue(): Array<Document & MemberModelItem> {
    return this._responsesWithConfidenceValue;
  }

48 49 50
  protected _options: Object;
  protected _theme: ExcelTheme;
  protected _translation: string;
51
  private readonly _mf: MessageFormat.Msg;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
52
  private readonly _createdAt: string;
53 54
  private readonly _quiz: IQuizBase;
  private _columnsToFormat: number;
Fullarton's avatar
Fullarton committed
55

56
  protected constructor({ theme, translation, quiz, mf, questionIndex }) {
Fullarton's avatar
Fullarton committed
57 58 59 60 61 62 63
    this._theme = theme;
    this._translation = translation;
    this._quiz = quiz;
    this._mf = mf;
    this._createdAt = this.generateCreatedAtString();
    this._options = Object.assign({}, excelDefaultWorksheetOptions, {
      headerFooter: {
64
        firstHeader: mf('export.page_header', { createdAt: this._createdAt }),
Fullarton's avatar
Fullarton committed
65
        firstFooter: mf('export.page_footer'),
66
        evenHeader: mf('export.page_header', { createdAt: this._createdAt }),
Fullarton's avatar
Fullarton committed
67
        evenFooter: mf('export.page_footer'),
68
        oddHeader: mf('export.page_header', { createdAt: this._createdAt }),
Fullarton's avatar
Fullarton committed
69 70
        oddFooter: mf('export.page_footer'),
        alignWithMargins: true,
71 72
        scaleWithDoc: false,
      },
Fullarton's avatar
Fullarton committed
73 74 75
    });

    this._columnsToFormat = 4;
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

    MemberDAO.getMembersOfQuiz(this._quiz.name).then(members => {
      if (questionIndex) {
        this._responsesWithConfidenceValue = members.filter(nickname => {
          return nickname.responses[questionIndex].confidence > -1;
        });
      } else {
        this._responsesWithConfidenceValue = members.filter(nickname => {
          return nickname.responses.some(responseItem => responseItem.confidence > -1);
        });
      }

      if (this._responsesWithConfidenceValue.length > 0) {
        this._columnsToFormat++;
      }
    });

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
93
    if (this._quiz.sessionConfig.nicks.restrictToCasLogin) {
Fullarton's avatar
Fullarton committed
94 95 96
      this._columnsToFormat += 2;
    }

97
    this.getLeaderboardData(questionIndex).then(data => this._leaderBoardData = data);
Fullarton's avatar
Fullarton committed
98 99 100 101 102 103 104 105 106
  }

  protected generateCreatedAtString(): string {
    const date = new Date();
    const dateYMD = `${this.prefixNumberWithZero(date.getDate())}.${this.prefixNumberWithZero(date.getMonth() + 1)}.${date.getFullYear()}`;
    const dateHM = `${this.prefixNumberWithZero(date.getHours())}:${this.prefixNumberWithZero(date.getMinutes())}`;
    return `${dateYMD} ${this._mf('export.exported_at')} ${dateHM} ${this._mf('export.exported_at_time')}`;
  }

107
  protected async getLeaderboardData(questionIndex: number): Promise<Array<ILeaderBoardItemBase>> {
Fullarton's avatar
Fullarton committed
108
    const leaderBoard = new Leaderboard();
109
    const { correctResponses } = await leaderBoard.buildLeaderboard(this.quiz);
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
110
    return leaderBoard.sortBy(correctResponses, 'score');
Fullarton's avatar
Fullarton committed
111
  }
112 113 114 115

  private prefixNumberWithZero(num: number): string {
    return `${num < 10 ? '0' : ''}${num}`;
  }
Fullarton's avatar
Fullarton committed
116
}