ExcelWorksheet.ts 3.76 KB
Newer Older
Fullarton's avatar
Fullarton committed
1 2
import * as xlsx from 'excel4node';
import * as MessageFormat from 'messageformat';
3
import MemberDAO from '../db/MemberDAO';
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
4 5 6 7
import { IMemberEntity } from '../interfaces/entities/Member/IMemberEntity';
import { ILeaderBoardItemBase } from '../interfaces/leaderboard/ILeaderBoardItemBase';
import { IQuizEntity } from '../interfaces/quizzes/IQuizEntity';
import { Leaderboard } from '../lib/leaderboard/leaderboard';
8
import { excelDefaultWorksheetOptions } from './lib/excel_default_options';
Fullarton's avatar
Fullarton committed
9

10
import { ExcelTheme } from './lib/excel_default_styles';
Fullarton's avatar
Fullarton committed
11 12

export abstract class ExcelWorksheet {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
13
  get responsesWithConfidenceValue(): Array<IMemberEntity> {
Fullarton's avatar
Fullarton committed
14 15
    return this._responsesWithConfidenceValue;
  }
16

Fullarton's avatar
Fullarton committed
17 18 19
  get columnsToFormat(): number {
    return this._columnsToFormat;
  }
20

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
21
  get quiz(): IQuizEntity {
Fullarton's avatar
Fullarton committed
22 23
    return this._quiz;
  }
24

Fullarton's avatar
Fullarton committed
25 26 27
  get createdAt(): string {
    return this._createdAt;
  }
28

29
  get mf(): MessageFormat.Msg {
Fullarton's avatar
Fullarton committed
30 31
    return this._mf;
  }
32

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
33
  protected _leaderBoardData: Array<ILeaderBoardItemBase>;
34

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

  protected _ws: xlsx.Worksheet;

Fullarton's avatar
Fullarton committed
41 42 43
  get ws(): xlsx.Worksheet {
    return this._ws;
  }
44 45 46 47

  protected _options: Object;
  protected _theme: ExcelTheme;
  protected _translation: string;
48
  private readonly _mf: MessageFormat.Msg;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
49
  private readonly _createdAt: string;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
50
  private readonly _quiz: IQuizEntity;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
51
  private readonly _columnsToFormat: number;
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
52
  private readonly _responsesWithConfidenceValue: Array<IMemberEntity>;
Fullarton's avatar
Fullarton committed
53

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

    this._columnsToFormat = 4;
    if (questionIndex) {
75
      this._responsesWithConfidenceValue = MemberDAO.getMembersOfQuiz(this._quiz.name).filter(nickname => {
Fullarton's avatar
Fullarton committed
76 77 78
        return nickname.responses[questionIndex].confidence > -1;
      });
    } else {
79
      this._responsesWithConfidenceValue = MemberDAO.getMembersOfQuiz(this._quiz.name).filter(nickname => {
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
80
        return nickname.responses.some(responseItem => responseItem.confidence > -1);
Fullarton's avatar
Fullarton committed
81 82 83 84 85
      });
    }
    if (this._responsesWithConfidenceValue.length > 0) {
      this._columnsToFormat++;
    }
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
86
    if (this._quiz.sessionConfig.nicks.restrictToCasLogin) {
Fullarton's avatar
Fullarton committed
87 88 89 90 91 92 93 94 95 96 97 98 99
      this._columnsToFormat += 2;
    }

    this._leaderBoardData = this.getLeaderboardData(questionIndex);
  }

  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')}`;
  }

Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
100
  protected getLeaderboardData(questionIndex: number): Array<ILeaderBoardItemBase> {
Fullarton's avatar
Fullarton committed
101
    const leaderBoard = new Leaderboard();
Christopher Mark Fullarton's avatar
Christopher Mark Fullarton committed
102 103
    const { correctResponses } = leaderBoard.buildLeaderboard(this.quiz);
    return leaderBoard.sortBy(correctResponses, 'score');
Fullarton's avatar
Fullarton committed
104
  }
105 106 107 108

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