Attempt to resurrect qomet code - need some rewrite
[qomet.git] / public / javascripts / monitor.js
CommitLineData
e5ec7dea
BA
1let socket = null; //monitor answers in real time
2
e5ec7dea
BA
3new Vue({
4 el: "#monitor",
5 data: {
6 password: "", //from password field
a3080c33 7 evaluation: { }, //obtained after authentication
e5ec7dea
BA
8 // Stage 0: unauthenticated (password),
9 // 1: authenticated (password hash validated), start monitoring
10 stage: 0,
f6648c37
BA
11 answers: {
12 displayAll: true,
13 showSolution: true, //TODO: allow to hide, to let teachers search too
14 inputs: [ ],
15 index : -1,
16 },
71d1ca9c 17 students: [ ], //to know their names
a3080c33 18 display: "evaluation", //or student's answers
e5ec7dea 19 },
e5ec7dea 20 methods: {
71d1ca9c
BA
21 // TODO: redundant code, next 4 funcs already exist in course.js
22 toggleDisplay: function(area) {
23 if (this.display == area)
24 this.display = "";
25 else
26 this.display = area;
27 },
28 studentList: function(group) {
29 return this.students
30 .filter( s => { return group==0 || s.group == group; })
31 .map( s => { return Object.assign({}, s); }) //not altering initial array
b3540dbb 32 .sort( (a,b) => { return a.name.localeCompare(b.name); });
71d1ca9c
BA
33 },
34 groupList: function() {
35 let maxGrp = 1;
36 this.students.forEach( s => {
37 if (s.group > maxGrp)
38 maxGrp = s.group;
39 });
40 return _.range(1,maxGrp+1);
41 },
42 groupId: function(group, prefix) {
43 return (prefix || "") + "group" + group;
44 },
f87ac54a
BA
45 togglePresence: function(student) {
46 const sIdx = this.students.findIndex( s => { return s.number == student.number; });
47 Vue.set( this.students, sIdx, Object.assign({},student,{present:!student.present}) );
48 //s.present = !s.present;
25cb8d53
BA
49 },
50 allFinished: function() {
51 for (s of this.students)
52 {
53 if (!s.present)
54 continue;
a3080c33 55 const paperIdx = this.evaluation.papers.findIndex( item => { return item.number == s.number; });
25cb8d53
BA
56 if (paperIdx === -1)
57 return false;
a3080c33
BA
58 const paper = this.evaluation.papers[paperIdx];
59 if (paper.inputs.length < this.evaluation.questions.length)
25cb8d53
BA
60 return false;
61 }
62 return true;
63 },
71d1ca9c
BA
64 getColor: function(number, qIdx) {
65 // For the moment, green if correct and red if wrong; grey if unanswered yet
66 // TODO: in-between color for partially right (especially for multi-questions)
a3080c33 67 const paperIdx = this.evaluation.papers.findIndex( item => { return item.number == number; });
71d1ca9c
BA
68 if (paperIdx === -1)
69 return "grey"; //student didn't start yet
a3080c33 70 const inputIdx = this.evaluation.papers[paperIdx].inputs.findIndex( item => {
71d1ca9c
BA
71 const qNum = parseInt(item.index.split(".")[0]); //indexes separated by dots
72 return qIdx == qNum;
73 });
74 if (inputIdx === -1)
75 return "grey";
a3080c33 76 if (_.isEqual(this.evaluation.papers[paperIdx].inputs[inputIdx].input, this.evaluation.questions[qIdx].answer))
71d1ca9c
BA
77 return "green";
78 return "red";
79 },
80 seeDetails: function(number, i) {
81 // UNIMPLEMENTED: see question details, with current answer(s)
82 },
e5ec7dea
BA
83 // stage 0 --> 1
84 startMonitoring: function() {
a3080c33 85 $.ajax("/evaluations/monitor", {
e5ec7dea
BA
86 method: "GET",
87 data: {
71d1ca9c 88 password: Sha1.Compute(this.password),
e5ec7dea 89 aname: examName,
71d1ca9c 90 ccode: courseCode,
f6648c37 91 initials: initials,
e5ec7dea
BA
92 },
93 dataType: "json",
94 success: s => {
95 if (!!s.errmsg)
71d1ca9c 96 return alert(s.errmsg);
a3080c33
BA
97 this.evaluation = s.evaluation;
98 this.answers.inputs = s.evaluation.questions.map( q => {
fa6abf40
BA
99 let input = _(q.options.length).times( _.constant(false) );
100 q.answer.forEach( idx => { input[idx] = true; });
101 return input;
102 });
71d1ca9c 103 this.students = s.students;
25cb8d53 104 this.students.forEach( s => { s.present = true; }); //a priori...
e5ec7dea 105 this.stage = 1;
f6648c37 106 socket = io.connect("/", {
a3080c33 107 query: "aid=" + this.evaluation._id + "&secret=" + s.secret
f6648c37 108 });
2bada710
BA
109 socket.on(message.studentBlur, m => {
110 const sIdx = this.students.findIndex( item => { return item.number == m.number; });
111 Vue.set(this.students, sIdx, Object.assign({},this.students[sIdx],{blur: true}));
112 //this.students[sIdx].blur = true;
113 });
114 socket.on(message.studentFocus, m => {
115 const sIdx = this.students.findIndex( item => { return item.number == m.number; });
116 this.students[sIdx].blur = false;
117 });
118 socket.on(message.studentResize, m => {
119 const sIdx = this.students.findIndex( item => { return item.number == m.number; });
120 Vue.set(this.students, sIdx, Object.assign({},this.students[sIdx],{resize: true}));
121 //this.students[sIdx].resize = true;
122 });
123 socket.on(message.studentFullscreen, m => {
124 const sIdx = this.students.findIndex( item => { return item.number == m.number; });
125 this.students[sIdx].resize = false;
126 });
127 socket.on(message.studentDisconnect, m => {
128 const sIdx = this.students.findIndex( item => { return item.number == m.number; });
129 Vue.set(this.students, sIdx, Object.assign({},this.students[sIdx],{disco: true}));
130 //this.students[sIdx].disco = true;
131 });
132 socket.on(message.studentConnect, m => {
133 const sIdx = this.students.findIndex( item => { return item.number == m.number; });
134 this.students[sIdx].disco = false;
135 });
f6648c37 136 socket.on(message.newAnswer, m => {
a3080c33 137 let paperIdx = this.evaluation.papers.findIndex( item => {
f6648c37
BA
138 return item.number == m.number;
139 });
71d1ca9c
BA
140 if (paperIdx === -1)
141 {
142 // First answer
a3080c33
BA
143 paperIdx = this.evaluation.papers.length;
144 this.evaluation.papers.push({
71d1ca9c
BA
145 number: m.number,
146 inputs: [ ], //other fields irrelevant here
147 });
148 }
149 // TODO: notations not coherent (input / answer... when, which ?)
a3080c33 150 this.evaluation.papers[paperIdx].inputs.push(JSON.parse(m.answer)); //input+index
e5ec7dea 151 });
e5ec7dea
BA
152 },
153 });
154 },
71d1ca9c
BA
155 endMonitoring: function() {
156 // In the end, send answers to students
2bada710 157 // TODO: disable this button until everyone finished (need ability to mark absents)
71d1ca9c
BA
158 socket.emit(
159 message.allAnswers,
a3080c33 160 { answers: JSON.stringify(this.evaluation.questions.map( q => { return q.answer; })) }
71d1ca9c
BA
161 );
162 },
e5ec7dea
BA
163 },
164});