@clickview/lite 0.57.3-rc.0 → 0.57.3-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles.json +1 -1
- package/dist/scripts/2615-27b126b1ab-lite.chunk.js +3 -0
- package/dist/scripts/2615-27b126b1ab-lite.chunk.js.map +1 -0
- package/dist/scripts/{2978-b7bcc3eac4-lite.chunk.js → 2978-e4a60f90a5-lite.chunk.js} +2 -2
- package/dist/scripts/2978-e4a60f90a5-lite.chunk.js.map +1 -0
- package/dist/scripts/{8095-afb976fac0-lite.chunk.js → 8095-7236697220-lite.chunk.js} +2 -2
- package/dist/scripts/8095-7236697220-lite.chunk.js.map +1 -0
- package/dist/scripts/8849-7d50f76777-lite.chunk.js +2 -0
- package/dist/scripts/8849-7d50f76777-lite.chunk.js.map +1 -0
- package/dist/scripts/{bundle-b25c09d3e8.min.js → bundle-b2d61cbf69.min.js} +3 -3
- package/dist/scripts/{bundle-b25c09d3e8.min.js.map → bundle-b2d61cbf69.min.js.map} +1 -1
- package/package.json +1 -1
- package/dist/scripts/2615-e9b2938c18-lite.chunk.js +0 -3
- package/dist/scripts/2615-e9b2938c18-lite.chunk.js.map +0 -1
- package/dist/scripts/2978-b7bcc3eac4-lite.chunk.js.map +0 -1
- package/dist/scripts/8095-afb976fac0-lite.chunk.js.map +0 -1
- package/dist/scripts/8849-020bfd8cdd-lite.chunk.js +0 -2
- package/dist/scripts/8849-020bfd8cdd-lite.chunk.js.map +0 -1
- /package/dist/scripts/{2615-e9b2938c18-lite.chunk.js.LICENSE.txt → 2615-27b126b1ab-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{bundle-b25c09d3e8.min.js.LICENSE.txt → bundle-b2d61cbf69.min.js.LICENSE.txt} +0 -0
package/dist/bundles.json
CHANGED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/*! For license information please see 2615-27b126b1ab-lite.chunk.js.LICENSE.txt */
|
|
2
|
+
"use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[2615],{39157:(t,e,r)=>{r.d(e,{HI:()=>h,R6:()=>s,Rt:()=>p,UU:()=>f,Zs:()=>l,nq:()=>d});var n=r(75896),o=r(94892),i=r(28972),a=r(8246),c=r(83140),u=r(80845);function s(t,e,r){var i={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},a=(0,u.Q)(t).length;e.students.forEach((function(e){var c=Object.assign(Object.assign({},e),{summary:p(t,e)});c.summary.awaitingMarking?i.markingRequired.push(c):n.m.last(e.results).attempts.length===a?(i.completed.push(c),c.summary.percentCorrect>=((null==r?void 0:r.HIGH)||o.i.HIGH)&&i.highScore.push(c),c.summary.percentCorrect<((null==r?void 0:r.MODERATE)||o.i.MODERATE)&&i.lowScore.push(c)):i.notCompleted.push(c)}));var c=n.m.sortBy(i.lowScore,(function(t){return t.summary.percentCorrect})),s=n.m.sortBy(i.highScore,(function(t){return-t.summary.percentCorrect}));return Object.assign(Object.assign({},i),{lowScore:c,highScore:s})}function l(t,e){return(0,u.Wn)(t).find((function(t){return t.id.toString()===e.toString()}))}function f(t){return"".concat(t.questionId,":").concat(t.resultId)}function h(t,e,r){var n=(0,u.j_)(e),o=(0,u.f6)(t,n);return(null==o?void 0:o.answers.every((function(t){var e;return(null===(e=r[f(t)])||void 0===e?void 0:e.status)===a.N.Correct})))?a.N.Correct:(null==o?void 0:o.answers.every((function(t){var e;return(null===(e=r[f(t)])||void 0===e?void 0:e.status)===a.N.Incorrect})))?a.N.Incorrect:void 0}function d(t,e){var r=e.students.length,n=0,o=0,a=0,s=0,l=0;return e.students.forEach((function(e){var r=(0,u.j_)(e);if(r){l+=e.results.length;var f=c.A.isInteractionCorrect(t,r);f===i.w.Correct&&n++,f===i.w.UnAnswered&&a++,f===i.w.AwaitingMarking&&s++,f!==i.w.UnAnswered&&o++}})),{percentCorrect:r>0?n/r:0,correct:n,answered:o,unanswered:a,awaitingMarking:s,attempts:l}}function p(t,e){var r=(0,u.j_)(e),n=(0,u.Q)(t),o=n.length,a=0,s=0;n.forEach((function(t){var e=c.A.isInteractionCorrect(t,r);e===i.w.Correct&&a++,e===i.w.AwaitingMarking&&s++}));var l=o>0?a/o:0,f=new Set(n.map((function(t){return t.id}))),h=r.attempts.filter((function(t){var e;return!!f.has(null===(e=null==t?void 0:t.answers[0])||void 0===e?void 0:e.questionId)})).length;return{answered:r.attempts.length,attempts:e.results.length,unanswered:o-h,percentCorrect:l,correct:a,awaitingMarking:s}}},32615:(t,e,r)=>{r.r(e),r.d(e,{InteractiveEditSuggestedResponse:()=>E});var n=r(32735),o=r(23481),i=r(44704),a=r(20354),c=r(39157),u=r(86572),s=r(9111),l=r(13876),f=r(83345),h=r(20768),d=r(69883);function p(t){return p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p(t)}function v(){v=function(){return e};var t,e={},r=Object.prototype,n=r.hasOwnProperty,o=Object.defineProperty||function(t,e,r){t[e]=r.value},i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",c=i.asyncIterator||"@@asyncIterator",u=i.toStringTag||"@@toStringTag";function s(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{s({},"")}catch(t){s=function(t,e,r){return t[e]=r}}function l(t,e,r,n){var i=e&&e.prototype instanceof w?e:w,a=Object.create(i.prototype),c=new N(n||[]);return o(a,"_invoke",{value:j(t,r,c)}),a}function f(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(t){return{type:"throw",arg:t}}}e.wrap=l;var h="suspendedStart",d="suspendedYield",y="executing",m="completed",g={};function w(){}function b(){}function E(){}var I={};s(I,a,(function(){return this}));var S=Object.getPrototypeOf,A=S&&S(S(M([])));A&&A!==r&&n.call(A,a)&&(I=A);var C=E.prototype=w.prototype=Object.create(I);function x(t){["next","throw","return"].forEach((function(e){s(t,e,(function(t){return this._invoke(e,t)}))}))}function k(t,e){function r(o,i,a,c){var u=f(t[o],t,i);if("throw"!==u.type){var s=u.arg,l=s.value;return l&&"object"==p(l)&&n.call(l,"__await")?e.resolve(l.__await).then((function(t){r("next",t,a,c)}),(function(t){r("throw",t,a,c)})):e.resolve(l).then((function(t){s.value=t,a(s)}),(function(t){return r("throw",t,a,c)}))}c(u.arg)}var i;o(this,"_invoke",{value:function(t,n){function o(){return new e((function(e,o){r(t,n,e,o)}))}return i=i?i.then(o,o):o()}})}function j(e,r,n){var o=h;return function(i,a){if(o===y)throw Error("Generator is already running");if(o===m){if("throw"===i)throw a;return{value:t,done:!0}}for(n.method=i,n.arg=a;;){var c=n.delegate;if(c){var u=L(c,n);if(u){if(u===g)continue;return u}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===h)throw o=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=y;var s=f(e,r,n);if("normal"===s.type){if(o=n.done?m:d,s.arg===g)continue;return{value:s.arg,done:n.done}}"throw"===s.type&&(o=m,n.method="throw",n.arg=s.arg)}}}function L(e,r){var n=r.method,o=e.iterator[n];if(o===t)return r.delegate=null,"throw"===n&&e.iterator.return&&(r.method="return",r.arg=t,L(e,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),g;var i=f(o,e.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,g;var a=i.arg;return a?a.done?(r[e.resultName]=a.value,r.next=e.nextLoc,"return"!==r.method&&(r.method="next",r.arg=t),r.delegate=null,g):a:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,g)}function O(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function _(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function N(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(O,this),this.reset(!0)}function M(e){if(e||""===e){var r=e[a];if(r)return r.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,i=function r(){for(;++o<e.length;)if(n.call(e,o))return r.value=e[o],r.done=!1,r;return r.value=t,r.done=!0,r};return i.next=i}}throw new TypeError(p(e)+" is not iterable")}return b.prototype=E,o(C,"constructor",{value:E,configurable:!0}),o(E,"constructor",{value:b,configurable:!0}),b.displayName=s(E,u,"GeneratorFunction"),e.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===b||"GeneratorFunction"===(e.displayName||e.name))},e.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,E):(t.__proto__=E,s(t,u,"GeneratorFunction")),t.prototype=Object.create(C),t},e.awrap=function(t){return{__await:t}},x(k.prototype),s(k.prototype,c,(function(){return this})),e.AsyncIterator=k,e.async=function(t,r,n,o,i){void 0===i&&(i=Promise);var a=new k(l(t,r,n,o),i);return e.isGeneratorFunction(r)?a:a.next().then((function(t){return t.done?t.value:a.next()}))},x(C),s(C,u,"Generator"),s(C,a,(function(){return this})),s(C,"toString",(function(){return"[object Generator]"})),e.keys=function(t){var e=Object(t),r=[];for(var n in e)r.push(n);return r.reverse(),function t(){for(;r.length;){var n=r.pop();if(n in e)return t.value=n,t.done=!1,t}return t.done=!0,t}},e.values=M,N.prototype={constructor:N,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=t,this.done=!1,this.delegate=null,this.method="next",this.arg=t,this.tryEntries.forEach(_),!e)for(var r in this)"t"===r.charAt(0)&&n.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=t)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var r=this;function o(n,o){return c.type="throw",c.arg=e,r.next=n,o&&(r.method="next",r.arg=t),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],c=a.completion;if("root"===a.tryLoc)return o("end");if(a.tryLoc<=this.prev){var u=n.call(a,"catchLoc"),s=n.call(a,"finallyLoc");if(u&&s){if(this.prev<a.catchLoc)return o(a.catchLoc,!0);if(this.prev<a.finallyLoc)return o(a.finallyLoc)}else if(u){if(this.prev<a.catchLoc)return o(a.catchLoc,!0)}else{if(!s)throw Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return o(a.finallyLoc)}}}},abrupt:function(t,e){for(var r=this.tryEntries.length-1;r>=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=e&&e<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=t,a.arg=e,i?(this.method="next",this.next=i.finallyLoc,g):this.complete(a)},complete:function(t,e){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&e&&(this.next=e),g},finish:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),_(r),g}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;_(r)}return o}}throw Error("illegal catch attempt")},delegateYield:function(e,r,n){return this.delegate={iterator:M(e),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=t),g}},e}function y(t,e){return function(t){if(Array.isArray(t))return t}(t)||function(t,e){var r=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=r){var n,o,i,a,c=[],u=!0,s=!1;try{if(i=(r=r.call(t)).next,0===e){if(Object(r)!==r)return;u=!1}else for(;!(u=(n=i.call(r)).done)&&(c.push(n.value),c.length!==e);u=!0);}catch(t){s=!0,o=t}finally{try{if(!u&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(s)throw o}}return c}}(t,e)||function(t,e){if(t){if("string"==typeof t)return m(t,e);var r={}.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?m(t,e):void 0}}(t,e)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function m(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=Array(e);r<e;r++)n[r]=t[r];return n}var g=function(t,e,r,n){return new(r||(r=Promise))((function(o,i){function a(t){try{u(n.next(t))}catch(t){i(t)}}function c(t){try{u(n.throw(t))}catch(t){i(t)}}function u(t){var e;t.done?o(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e)}))).then(a,c)}u((n=n.apply(t,e||[])).next())}))},w="shared.interactiveEditSuggestedResponse",b=o.T.encloseNamespace(w);function E(t){var e,r,o=(0,d.Z)(),p=(0,i.useGetFetchAsync)(),m=y(n.useState(!1),2),E=m[0],I=m[1],S=a.a.useBasicFetch(h.b.interactiveMetadata(t.interactiveId)),A=a.a.useBasicFetch((null===(e=S.data)||void 0===e?void 0:e.interactiveId)&&h.b.interactive(S.data.interactiveId)),C=A.data&&(0,c.Zs)(A.data,t.interactionId),x=y(n.useState(null===(r=C.data)||void 0===r?void 0:r.suggestedResponse),2),k=x[0],j=x[1];return n.createElement(s.G,{title:b(k?"edit":"create"),closePopup:t.closePopup},n.createElement("div",{className:"mb-3"},n.createElement(u.y,{interaction:C})),n.createElement("label",{htmlFor:"suggestedResponse",className:"form-label"},n.createElement(f.x,{namespace:w,phrase:"label"}),":"),n.createElement("textarea",{id:"suggestedResponse",className:"form-control w-100 mb-3",placeholder:b("placeholder"),onChange:function(t){return j(t.target.value)},value:k,rows:4}),n.createElement(l.u,null,n.createElement(l.u.Cancel,{onClick:t.closePopup}),n.createElement(l.u.Submit,{variant:"dark",text:b("save"),onClick:function(){return g(this,void 0,void 0,v().mark((function e(){var r;return v().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return r=Object.assign(Object.assign({},C),{actionableItems:[{name:"Answer"}],data:{suggestedResponse:k}}),I(!0),e.prev=2,e.next=5,p(h.b.updateInteraction(r));case 5:o.success(b("suggestedResponseSuccess")),t.closePopup(),e.next=12;break;case 9:e.prev=9,e.t0=e.catch(2),o.error(b("suggestedResponseError"));case 12:return e.prev=12,I(!1),e.finish(12);case 15:case"end":return e.stop()}}),e,null,[[2,9,12,15]])})))},showSpinner:E})))}},94892:(t,e,r)=>{r.d(e,{T:()=>o,i:()=>n});var n={HIGH:.75,MODERATE:.5},o={HIGH:.7,MODERATE:.7}},28972:(t,e,r)=>{var n;r.d(e,{w:()=>n}),function(t){t[t.Correct=0]="Correct",t[t.Incorrect=1]="Incorrect",t[t.AwaitingMarking=2]="AwaitingMarking",t[t.Answered=3]="Answered",t[t.UnAnswered=4]="UnAnswered",t[t.NotApplicable=5]="NotApplicable"}(n||(n={}))},8246:(t,e,r)=>{var n;r.d(e,{N:()=>n}),function(t){t[t.Incorrect=0]="Incorrect",t[t.Correct=1]="Correct",t[t.PendingReview=2]="PendingReview"}(n||(n={}))},83140:(t,e,r)=>{r.d(e,{A:()=>v});var n=r(28972),o=r(8246),i=r(40424);function a(t){return a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},a(t)}function c(t,e,r){return(e=function(t){var e=function(t,e){if("object"!=a(t)||!t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var n=r.call(t,"string");if("object"!=a(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t);return"symbol"==a(e)?e:e+""}(e))in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function u(){return n.w.NotApplicable}function s(t,e){var r=t.actionableItems.filter((function(t){return t.isCorrect}));return r.every((function(t){return!e(t.id)}))?n.w.UnAnswered:r.every((function(t){var r;return t.name.trim().toLowerCase()===(null===(r=e(t.id))||void 0===r?void 0:r.trim().toLowerCase())}))?n.w.Correct:n.w.Incorrect}function l(t,e){return t.actionableItems.every((function(t){return!e(t.id)}))?n.w.UnAnswered:t.actionableItems.filter((function(t){return t.isCorrect})).every((function(t){var r,n=e(t.id);return(null==n?void 0:n.toString())===(null===(r=t.id)||void 0===r?void 0:r.toString())||n===t.name}))?n.w.Correct:n.w.Incorrect}function f(t,e){return function(r){var n=e.attempts.find((function(e){return e.id===t.id}));return null==n?void 0:n.answers.find((function(t){return t.id===r}))}}function h(t,e){var r=f(t,e);return l(t,(function(t){var e=r(t);return null==e?void 0:e.text}))}function d(t,e){return function(t,e){var r;return t.actionableItems.forEach((function(t){var i=e(t.id);r=i?i.status!==o.N.Correct?i.status!==o.N.Incorrect?n.w.AwaitingMarking:n.w.Incorrect:n.w.Correct:n.w.UnAnswered})),r}(t,f(t,e))}var p=c(c(c(c(c(c(c({},i.Z9.Annotation,u),i.Z9.Image,u),i.Z9.MissingWord,(function(t,e){var r=f(t,e);return s(t,(function(t){var e=r(t);return null==e?void 0:e.text}))})),i.Z9.MultipleChoice,h),i.Z9.ShortAnswer,d),i.Z9.TrueOrFalse,h),i.Z9.Illustration,d),v={notApplicable:u,awaitingMarking:function(){return n.w.AwaitingMarking},isMissingWordCorrect:s,isMultipleChoiceCorrect:l,isInteractionCorrect:function(t,e){return(0,p[t.typeId])(t,e)}}},80845:(t,e,r)=>{r.d(e,{Q:()=>s,Wn:()=>a,f6:()=>u,j_:()=>c});var n=r(75896),o=r(40424);function i(t){return t.typeId!==o.Z9.Annotation&&t.typeId!==o.Z9.Image}function a(t){return n.m.flatten(t.timepoints.map((function(t){return t.interactions})))}function c(t){return n.m.last(t.results)}function u(t,e){return n.m.findWhere(null==e?void 0:e.attempts,{id:t})}function s(t){return a(t).filter(i)}}}]);
|
|
3
|
+
//# sourceMappingURL=2615-27b126b1ab-lite.chunk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scripts/2615-27b126b1ab-lite.chunk.js","mappings":";uPAqBM,SAAUA,EACdC,EACAC,EACAC,GAEA,IAAMC,EAAwB,CAC5BC,gBAAiB,GACjBC,SAAU,GACVC,UAAW,GACXC,UAAW,GACXC,aAAc,IAKVC,GAFe,OAAgBT,GAEAU,OAErCT,EAAQU,SAASC,SAAQ,SAAAC,GACvB,IAAMC,EAAc,OAAH,wBACZD,GAAC,CACJE,QAASC,EAAyBhB,EAAaa,KAG7CC,EAAYC,QAAQE,gBACtBd,EAAOC,gBAAgBc,KAAKJ,GAI1B,SAAiBD,EAAEZ,SAASkB,SAAST,SAAWD,GAClDN,EAAOI,UAAUW,KAAKJ,GAMpBA,EAAYC,QAAQK,kBAAmBlB,aAAc,EAAdA,EAAgBmB,OAAQ,WACjElB,EAAOG,UAAUY,KAAKJ,GAEpBA,EAAYC,QAAQK,iBAAkBlB,aAAc,EAAdA,EAAgBoB,WAAY,eACpEnB,EAAOE,SAASa,KAAKJ,IARrBX,EAAOK,aAAaU,KAAKJ,EAS7B,IAEA,IAAMS,EAAiB,WAAmBpB,EAAOE,UAAU,SAAAQ,GAAC,OAAIA,EAAEE,QAAQK,cAAc,IAClFI,EAAkB,WAAmBrB,EAAOG,WAAW,SAAAO,GAAC,OAAKA,EAAEE,QAAQK,cAAc,IAE3F,OAAO,OAAP,wBACKjB,GAAM,CACTE,SAAUkB,EACVjB,UAAWkB,GAEf,CAEM,SAAUC,EAAmBzB,EAA0B0B,GAE3D,OAD8B,QAAoB1B,GACrB2B,MAAK,SAAAC,GAAC,OAAIA,EAAEC,GAAGC,aAAeJ,EAAcI,UAAU,GACrF,CAOM,SAAUC,EAAkBC,GAChC,MAAO,GAAP,OAAUA,EAAOC,WAAU,YAAID,EAAOE,SACxC,CAEM,SAAUC,EACdT,EACAU,EACAC,GAEA,IAAMC,GAAS,QAAiBF,GAC1BG,GAAkB,QAAkBb,EAAeY,GAMzD,OAJwBC,aAAe,EAAfA,EAAiBC,QAAQC,OAAM,SAAAC,SACrD,OAA0C,QAAnC,EAAAL,EAAcN,EAAkBW,WAAG,eAAEC,UAAW,WACzD,KAGS,aAEiBJ,aAAe,EAAfA,EAAiBC,QAAQC,OAAM,SAAAC,SACvD,OAA0C,QAAnC,EAAAL,EAAcN,EAAkBW,WAAG,eAAEC,UAAW,aACzD,KAGS,mBADT,CAEF,CAEM,SAAUC,EACdC,EACA5C,GAEA,IAAM6C,EAAc7C,EAAQU,SAASD,OACjCqC,EAAa,EACbC,EAAW,EACXC,EAAa,EACbhC,EAAkB,EAClBE,EAAW,EA8Bf,OA5BAlB,EAAQU,SAASC,SAAQ,SAAAC,GACvB,IAAMyB,GAAS,QAAiBzB,GAEhC,GAAKyB,EAAL,CAGAnB,GAAsBN,EAAEZ,QAAQS,OAEhC,IAAMwC,EAAc,yBAAkDL,EAAaP,GAE/EY,IAAgB,aAClBH,IAEEG,IAAgB,gBAClBD,IAEEC,IAAgB,qBAClBjC,IAEEiC,IAAgB,gBAClBF,GAhBM,CAiBV,IAOO,CACL5B,eALqB0B,EAAc,EACjCC,EAAaD,EACb,EAIFK,QAASJ,EACTC,SAAAA,EACAC,WAAAA,EACAhC,gBAAAA,EACAE,SAAAA,EAEJ,CAEM,SAAUH,EAAyBhB,EAA0BoC,GACjE,IAAME,GAAS,QAAiBF,GAE1BgB,GAAe,OAAgBpD,GAE/BS,EAAkB2C,EAAa1C,OAEjCqC,EAAa,EACb9B,EAAkB,EAEtBmC,EAAaxC,SAAQ,SAAAgB,GACnB,IAAMsB,EAAc,yBAAkDtB,EAAGU,GAErEY,IAAgB,aAClBH,IAEEG,IAAgB,qBAClBjC,GACJ,IAEA,IAAMG,EAAiBX,EAAkB,EAAIsC,EAAatC,EAAkB,EAQtE4C,EAAiB,IAAIC,IAAIF,EAAaG,KAAI,SAAA3B,GAAC,OAAIA,EAAEC,EAAE,KACnD2B,EAAuBlB,EAAOnB,SAASsC,QAAO,SAAAf,GAAI,MAAC,QAAEW,EAAeK,IAAiB,QAAb,EAAAhB,aAAC,EAADA,EAAGF,QAAQ,UAAE,eAAEP,WAAW,IAAEvB,OAE1G,MAAO,CACLsC,SAAUV,EAAOnB,SAAST,OAC1BS,SAAUiB,EAAenC,QAAQS,OACjCuC,WAAYxC,EAAkB+C,EAC9BpC,eAAAA,EACA+B,QAASJ,EACT9B,gBAAAA,EAEJ,ojQCvLM0C,EAAY,0CACZC,EAAY,qBAAiCD,GAO7C,SAAUE,EAAiCC,WACzCC,GAAQ,SACRC,GAAa,IAAAC,oBAE0C,IAArB,YAAe,GAAM,GAArDC,EAAW,KAAEC,EAAc,KAE7BC,EAAsB,kBAC1B,wBAAwCN,EAAMO,gBAE1CrE,EAAc,mBAA0D,QAAxB,EAAAoE,EAAoBE,YAAI,eAAED,gBAC9E,gBAAgCD,EAAoBE,KAAKD,gBAErDxB,EAAc7C,EAAYsE,OAAQ,QAAmBtE,EAAYsE,KAAMR,EAAMpC,eAEoB,IAAnD,WAA+B,QAAhB,EAAAmB,EAAYyB,YAAI,eAAEC,mBAAkB,GAA/FA,EAAiB,KAAEC,EAAoB,KAwB/C,OACE,gBAAC,IAAK,CACJC,MAAOb,EAAWW,EAA+B,OAAX,UACtCG,WAAYZ,EAAMY,YAElB,uBAAKC,UAAU,QACb,gBAAC,IAAgB,CAAC9B,YAAaA,KAGjC,yBAAO+B,QAAQ,oBAAoBD,UAAU,cAC3C,gBAAC,IAAI,CAAChB,UAAWA,EAAWkB,OAAO,UAAU,KAG/C,4BACEhD,GAAG,oBACH8C,UAAU,0BACVG,YAAalB,EAAU,eACvBmB,SAAU,SAAAC,GAAC,OAAIR,EAAqBQ,EAAEC,OAAOC,MAAM,EACnDA,MAAOX,EACPY,KAAM,IAGR,gBAAC,IAAY,KACX,gBAAC,WAAmB,CAACC,QAAStB,EAAMY,aACpC,gBAAC,WAAmB,CAClBW,QAAQ,OACRC,KAAM1B,EAAU,QAChBwB,QAjDR,qIAUI,OATId,EAAI,+BACLzB,GAAW,CACd0C,gBAAiB,CAAC,CAAEC,KAAM,WAC1BlB,KAAM,CAAEC,kBAAAA,KAGVJ,GAAe,GAAM,kBAGbH,EAAW,sBAAsCM,IAAM,OAE7DP,EAAM0B,QAAQ7B,EAAU,6BAExBE,EAAMY,aAAa,gDAEnBX,EAAM2B,MAAM9B,EAAU,2BAA2B,QAE3B,OAF2B,UAEjDO,GAAe,GAAO,2EAEzB,EA8BOD,YAAaA,KAKvB,4CCzFO,IAAMyB,EAA0C,CACrDtE,KAAM,IACNC,SAAU,IAGCsE,EAA0C,CACrDvE,KAAM,GACNC,SAAU,qBCZZ,IAAYuE,mBAAZ,SAAYA,GACV,yBACA,6BACA,yCAEA,2BACA,+BACA,oCACD,CARD,CAAYA,IAAAA,EAAsB,qBCAlC,IAAYC,mBAAZ,SAAYA,GACV,6BACA,yBACA,oCACD,CAJD,CAAYA,IAAAA,EAAuB,gsBCMnC,SAASC,IACP,OAAO,iBACT,CAMA,SAASC,EACPnD,EACAoD,GAEA,IAAMC,EAAQrD,EAAY0C,gBAAgB9B,QAAO,SAAAf,GAAC,OAAIA,EACnDyD,SAAS,IAEZ,OAAID,EAAMzD,OAAM,SAAAC,GAAC,OAAKuD,EAAiBvD,EAAEb,GAAG,IACnC,eAEOqE,EAAMzD,OAAM,SAAAC,GAAI,MAAC,OAAAA,EAAE8C,KAAKY,OAAOC,iBAAwC,QAAtB,EAAAJ,EAAiBvD,EAAEb,WAAG,eAAEuE,OAAOC,cAAa,IAC5F,YAAiC,aACpD,CAEA,SAASC,EACPzD,EACAoD,GAEA,OAAIpD,EAAY0C,gBAAgB9C,OAAM,SAAAC,GAAC,OAAKuD,EAAiBvD,EAAEb,GAAG,IACzD,eAEYgB,EAAY0C,gBAAgB9B,QAAO,SAAAf,GAAC,OAAIA,EAAEyD,SAAS,IAE3C1D,OAAM,SAAAC,SAC3B6D,EAAgBN,EAAiBvD,EAAEb,IAOzC,OAAO0E,aAAa,EAAbA,EAAezE,eAAmB,QAAJ,EAAAY,EAAEb,UAAE,eAAEC,aAAcyE,IAAkB7D,EAAE8C,IAC/E,IACiB,YAAiC,aACpD,CAmCA,SAASgB,EAAoB3D,EAA0BP,GACrD,OAAO,SAACT,GACN,IAAM4E,EAAUnE,EAAOnB,SAASQ,MAAK,SAAAe,GAAC,OAAIA,EAAEb,KAAOgB,EAAYhB,EAAE,IACjE,OAAO4E,aAAO,EAAPA,EAASjE,QAAQb,MAAK,SAAAd,GAAC,OAAIA,EAAEgB,KAAOA,CAAE,GAC/C,CACF,CAWA,SAAS6E,EAA4B7D,EAA0BP,GAC7D,IAAM2D,EAAmBO,EAAoB3D,EAAaP,GAE1D,OAAOgE,EAAwBzD,GAAa,SAAChB,GAC3C,IAAMG,EAASiE,EAAiBpE,GAChC,OAAOG,aAAM,EAANA,EAAQsD,IACjB,GACF,CAEA,SAASqB,EACP9D,EACAP,GAGA,OA/DF,SACEO,EACAoD,GAEA,IAAI/C,EAwBJ,OArBAL,EAAY0C,gBAAgB3E,SAAQ,SAAAgG,GAClC,IAAML,EAAgBN,EAAiBW,EAAK/E,IAiB5CqB,EAfKqD,EAKDA,EAAc5D,SAAW,YAKzB4D,EAAc5D,SAAW,cAKf,oBAJE,cALA,YALA,cAelB,IAEOO,CACT,CAkCS2D,CAA8BhE,EADZ2D,EAAoB3D,EAAaP,GAE5D,CAEA,IAAMwE,EAAe,iBAClB,gBAA+Bf,GAC/B,WAA0BA,GAC1B,kBA7BH,SAAkClD,EAA0BP,GAC1D,IAAM2D,EAAmBO,EAAoB3D,EAAaP,GAE1D,OAAO0D,EAAqBnD,GAAa,SAAChB,GACxC,IAAMG,EAASiE,EAAiBpE,GAChC,OAAOG,aAAM,EAANA,EAAQsD,IACjB,GACF,IAuBG,oBAAmCoB,GACnC,iBAAgCC,GAChC,iBAAgCD,GAChC,kBAAiCC,GASvBI,EAA+B,CAC1ChB,cAAAA,EACA9E,gBA5HF,WACE,OAAO,mBACT,EA2HE+E,qBAAAA,EACAM,wBAAAA,EACAU,qBAXF,SAA8BnE,EAA0BP,GAGtD,OAAO2E,EAFaH,EAAgBjE,EAAYqE,SAE7BrE,EAAaP,EAClC,0FCvHA,SAAS6E,EAA0BtE,GACjC,OAAOA,EAAYqE,SAAW,iBAAgCrE,EAAYqE,SAAW,UACvF,CAEM,SAAUE,EAAoBpH,GAClC,OAAO,YAAoBA,EAAYqH,WAAW9D,KAAI,SAAA3B,GAAC,OAAIA,EAAEwB,YAAY,IAC3E,CAKM,SAAUkE,EAAiBlF,GAC/B,OAAO,SAAiBA,EAAenC,QACzC,CAEM,SAAUsH,EAAkB7F,EAAuBY,GACvD,OAAO,cAAsBA,aAAM,EAANA,EAAQnB,SAAU,CAAEU,GAAIH,GACvD,CAMM,SAAU8F,EAAgBxH,GAC9B,OAAOoH,EAAoBpH,GAAayD,OAAO0D,EACjD","sources":["file:///app/packages/libs/shared/src/apps/analytics/utils/InteractiveUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/views/interactive-edit-suggested-response/InteractiveEditSuggestedResponse.tsx","file:///app/packages/libs/shared/src/constants/ScoreThresholds.ts","file:///app/packages/libs/shared/src/enums/InteractionCorrectness.ts","file:///app/packages/libs/shared/src/enums/InteractiveAnswerStatus.ts","file:///app/packages/libs/shared/src/utils/InteractiveCorrectnessHelper.ts","file:///app/packages/libs/shared/src/utils/InteractiveHelper.ts"],"sourcesContent":["import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { Interactive, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { flattenInteractions, getInteractions, getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\ninterface StudentGroups {\n markingRequired: StudentResultsWithSummary[];\n lowScore: StudentResultsWithSummary[];\n highScore: StudentResultsWithSummary[];\n completed: StudentResultsWithSummary[];\n notCompleted: StudentResultsWithSummary[];\n}\n\nexport function groupStudents(\n interactive: Interactive,\n results: InteractiveResultSet,\n scoreThreshold?: ScoreThresholds\n): StudentGroups {\n const groups: StudentGroups = {\n markingRequired: [],\n lowScore: [],\n highScore: [],\n completed: [],\n notCompleted: []\n };\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n \n results.students.forEach(s => {\n const withSummary = {\n ...s,\n summary: getStudentResultsSummary(interactive, s)\n };\n \n if (withSummary.summary.awaitingMarking) {\n groups.markingRequired.push(withSummary);\n return;\n }\n\n if (ArrayHelper.last(s.results).attempts.length === numInteractions) {\n groups.completed.push(withSummary);\n } else {\n groups.notCompleted.push(withSummary);\n return;\n }\n \n if (withSummary.summary.percentCorrect >= (scoreThreshold?.HIGH || ScoreThresholdDefaults.HIGH))\n groups.highScore.push(withSummary);\n \n if (withSummary.summary.percentCorrect < (scoreThreshold?.MODERATE || ScoreThresholdDefaults.MODERATE))\n groups.lowScore.push(withSummary);\n });\n \n const sortedLowScore = ArrayHelper.sortBy(groups.lowScore, s => s.summary.percentCorrect);\n const sortedHighScore = ArrayHelper.sortBy(groups.highScore, s => -s.summary.percentCorrect);\n \n return {\n ...groups,\n lowScore: sortedLowScore,\n highScore: sortedHighScore\n };\n}\n\nexport function getInteractionById(interactive: Interactive, interactionId: string): Interaction {\n const flattenedInteractions = flattenInteractions(interactive);\n return flattenedInteractions.find(i => i.id.toString() === interactionId.toString());\n}\n\n/**\n * We need to use the question and result ids as a list of one student's responses\n * to multiple questions will all have the same result id and a list of multiple\n * students responses to one question will all have the same questionId.\n */\nexport function getMarkedAnswerId(answer: StudentAnswer): string {\n return `${answer.questionId}:${answer.resultId}`;\n}\n\nexport function getMarkedStatus(\n interactionId: string,\n studentResults: StudentResults,\n markedAnswers: MarkedAnswerHash\n): InteractiveAnswerStatus {\n const result = getStudentResult(studentResults);\n const studentResponse = getStudentAttempt(interactionId, result);\n\n const isMarkedCorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Correct;\n });\n\n if (isMarkedCorrect)\n return InteractiveAnswerStatus.Correct;\n\n const isMarkedIncorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Incorrect;\n });\n\n if (isMarkedIncorrect)\n return InteractiveAnswerStatus.Incorrect;\n}\n\nexport function getInteractionResultsSummary(\n interaction: Interaction,\n results: InteractiveResultSet\n): ResultsSummary {\n const numStudents = results.students.length;\n let numCorrect = 0;\n let answered = 0;\n let unanswered = 0;\n let awaitingMarking = 0;\n let attempts = 0;\n\n results.students.forEach(s => {\n const result = getStudentResult(s);\n\n if (!result)\n return;\n\n attempts = attempts + s.results.length;\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(interaction, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.UnAnswered)\n unanswered++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n\n if (correctness !== InteractionCorrectness.UnAnswered)\n answered++;\n });\n\n\n const percentCorrect = numStudents > 0\n ? numCorrect / numStudents\n : 0;\n\n return {\n percentCorrect,\n correct: numCorrect,\n answered,\n unanswered,\n awaitingMarking,\n attempts\n };\n}\n\nexport function getStudentResultsSummary(interactive: Interactive, studentResults: StudentResults): ResultsSummary {\n const result = getStudentResult(studentResults);\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n\n let numCorrect = 0;\n let awaitingMarking = 0;\n\n interactions.forEach(i => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(i, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n });\n\n const percentCorrect = numInteractions > 0 ? numCorrect / numInteractions : 0;\n\n /**\n * Our interactions list has images and annotations filtered out.\n * We built a map of valid questions, so that we can calculate the unswered accurately.\n * We're doing this because of a bug that caused annotations and images to record answers in the player.\n * - Sha\n */\n const interactionIds = new Set(interactions.map(i => i.id));\n const answeredInteractions = result.attempts.filter(a => !!interactionIds.has(a?.answers[0]?.questionId)).length;\n\n return {\n answered: result.attempts.length,\n attempts: studentResults.results.length,\n unanswered: numInteractions - answeredInteractions,\n percentCorrect,\n correct: numCorrect,\n awaitingMarking\n };\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { useGetFetchAsync } from 'libs/common/react/flight';\nimport { Flight } from 'libs/common/react/index';\n\nimport { getInteractionById } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { Popup, PopupProps } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { InteractiveRequests } from 'libs/shared/flight-requests/InteractiveRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { Interaction, Interactive, InteractiveMetadata } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.interactiveEditSuggestedResponse';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InteractiveEditSuggestedResponseProps extends PopupProps {\n interactiveId: string;\n interactionId: string;\n}\n\nexport function InteractiveEditSuggestedResponse(props: InteractiveEditSuggestedResponseProps) {\n const alert = useAlerts();\n const fetchAsync = useGetFetchAsync();\n\n const [ showSpinner, setShowSpinner ] = React.useState(false);\n\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(\n InteractiveRequests.interactiveMetadata(props.interactiveId)\n );\n const interactive = Flight.useBasicFetch<Interactive>(interactiveMetadata.data?.interactiveId &&\n InteractiveRequests.interactive(interactiveMetadata.data.interactiveId));\n\n const interaction = interactive.data && getInteractionById(interactive.data, props.interactionId);\n \n const [ suggestedResponse, setSuggestedResponse ] = React.useState(interaction.data?.suggestedResponse);\n\n async function submitSuggestedResponse() {\n const data: Interaction = {\n ...interaction,\n actionableItems: [{ name: 'Answer' }],\n data: { suggestedResponse }\n };\n\n setShowSpinner(true);\n\n try {\n await fetchAsync(InteractiveRequests.updateInteraction(data));\n\n alert.success(getPhrase('suggestedResponseSuccess'));\n\n props.closePopup();\n } catch {\n alert.error(getPhrase('suggestedResponseError'));\n } finally {\n setShowSpinner(false);\n }\n }\n\n return (\n <Popup\n title={getPhrase(!suggestedResponse ? 'create' : 'edit')}\n closePopup={props.closePopup}\n >\n <div className='mb-3'>\n <InteractionLabel interaction={interaction} />\n </div>\n\n <label htmlFor='suggestedResponse' className='form-label'>\n <Text namespace={namespace} phrase='label' />:\n </label>\n\n <textarea\n id='suggestedResponse'\n className='form-control w-100 mb-3'\n placeholder={getPhrase('placeholder')}\n onChange={e => setSuggestedResponse(e.target.value)}\n value={suggestedResponse}\n rows={4}\n />\n\n <PopupButtons>\n <PopupButtons.Cancel onClick={props.closePopup} />\n <PopupButtons.Submit\n variant='dark'\n text={getPhrase('save')}\n onClick={submitSuggestedResponse}\n showSpinner={showSpinner}\n />\n </PopupButtons>\n </Popup>\n );\n}","export interface ScoreThresholds {\n HIGH: number;\n MODERATE: number;\n}\n\nexport const ScoreThresholdDefaults: ScoreThresholds = {\n HIGH: 0.75,\n MODERATE: 0.5\n};\n\nexport const ScoreThresholdInsights: ScoreThresholds = {\n HIGH: 0.7,\n MODERATE: 0.7\n};","export enum InteractionCorrectness {\n Correct,\n Incorrect,\n AwaitingMarking,\n \n Answered,\n UnAnswered,\n NotApplicable\n}","export enum InteractiveAnswerStatus {\n Incorrect = 0,\n Correct = 1,\n PendingReview = 2\n}","import { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, InteractionTypeId, InteractiveResult, StudentAnswer } from 'libs/shared/interfaces';\n\ntype GetStudentAnswerByActionableItemId = (id: string) => string;\n\nfunction notApplicable(): InteractionCorrectness {\n return InteractionCorrectness.NotApplicable;\n}\n\nfunction awaitingMarking(): InteractionCorrectness {\n return InteractionCorrectness.AwaitingMarking;\n}\n\nfunction isMissingWordCorrect(\n interaction: Interaction,\n getStudentAnswer: GetStudentAnswerByActionableItemId\n): InteractionCorrectness {\n const items = interaction.actionableItems.filter(a => a\n .isCorrect);\n\n if (items.every(a => !getStudentAnswer(a.id)))\n return InteractionCorrectness.UnAnswered;\n\n const correct = items.every(a => a.name.trim().toLowerCase() === getStudentAnswer(a.id)?.trim().toLowerCase());\n return correct ? InteractionCorrectness.Correct : InteractionCorrectness.Incorrect;\n}\n\nfunction isMultipleChoiceCorrect(\n interaction: Interaction,\n getStudentAnswer: GetStudentAnswerByActionableItemId\n): InteractionCorrectness {\n if (interaction.actionableItems.every(a => !getStudentAnswer(a.id)))\n return InteractionCorrectness.UnAnswered;\n \n const correctItems = interaction.actionableItems.filter(a => a.isCorrect);\n\n const correct = correctItems.every(a => {\n const studentAnswer = getStudentAnswer(a.id);\n\n /**\n * In the past we've only ever checked the answer name. But since we introduced the ability to have image interactions\n * with no question text, we've need to swap to saving the id. But past submissions still have the name\n * - Sha\n */\n return studentAnswer?.toString() === a.id?.toString() || studentAnswer === a.name;\n });\n return correct ? InteractionCorrectness.Correct : InteractionCorrectness.Incorrect;\n}\n\nfunction isMarkableAnswerMarkedCorrect(\n interaction: Interaction,\n getStudentAnswer: (id: string) => StudentAnswer\n): InteractionCorrectness {\n let correctness: InteractionCorrectness;\n\n // There should only be one actionableItem\n interaction.actionableItems.forEach(item => {\n const studentAnswer = getStudentAnswer(item.id);\n\n if (!studentAnswer) {\n correctness = InteractionCorrectness.UnAnswered;\n return;\n }\n\n if (studentAnswer.status === InteractiveAnswerStatus.Correct) {\n correctness = InteractionCorrectness.Correct;\n return;\n }\n\n if (studentAnswer.status === InteractiveAnswerStatus.Incorrect) {\n correctness = InteractionCorrectness.Incorrect;\n return;\n }\n\n correctness = InteractionCorrectness.AwaitingMarking;\n });\n\n return correctness;\n}\n\ntype IsCorrectFunction = (interaction: Interaction, result: InteractiveResult) => InteractionCorrectness;\n\nfunction getGetStudentAnswer(interaction: Interaction, result: InteractiveResult): (id: string) => StudentAnswer {\n return (id: string) => {\n const attempt = result.attempts.find(a => a.id === interaction.id);\n return attempt?.answers.find(s => s.id === id);\n };\n}\n\nfunction wrapIsMissingWordCorrect(interaction: Interaction, result: InteractiveResult): InteractionCorrectness {\n const getStudentAnswer = getGetStudentAnswer(interaction, result);\n\n return isMissingWordCorrect(interaction, (id: string) => {\n const answer = getStudentAnswer(id);\n return answer?.text;\n });\n}\n\nfunction wrapIsMultipleChoiceCorrect(interaction: Interaction, result: InteractiveResult): InteractionCorrectness {\n const getStudentAnswer = getGetStudentAnswer(interaction, result);\n\n return isMultipleChoiceCorrect(interaction, (id: string) => {\n const answer = getStudentAnswer(id);\n return answer?.text;\n });\n}\n\nfunction wrapIsMarkableAnswerMarkedCorrect(\n interaction: Interaction,\n result: InteractiveResult\n): InteractionCorrectness {\n const getStudentAnswer = getGetStudentAnswer(interaction, result);\n return isMarkableAnswerMarkedCorrect(interaction, getStudentAnswer);\n}\n\nconst IsCorrectLookup: {[typeId: number]: IsCorrectFunction} = {\n [InteractionTypeId.Annotation]: notApplicable,\n [InteractionTypeId.Image]: notApplicable,\n [InteractionTypeId.MissingWord]: wrapIsMissingWordCorrect,\n [InteractionTypeId.MultipleChoice]: wrapIsMultipleChoiceCorrect,\n [InteractionTypeId.ShortAnswer]: wrapIsMarkableAnswerMarkedCorrect,\n [InteractionTypeId.TrueOrFalse]: wrapIsMultipleChoiceCorrect,\n [InteractionTypeId.Illustration]: wrapIsMarkableAnswerMarkedCorrect\n};\n\nfunction isInteractionCorrect(interaction: Interaction, result: InteractiveResult): InteractionCorrectness {\n const isCorrectFn = IsCorrectLookup[interaction.typeId];\n\n return isCorrectFn(interaction, result);\n}\n\nexport const InteractiveCorrectnessHelper = {\n notApplicable,\n awaitingMarking,\n isMissingWordCorrect,\n isMultipleChoiceCorrect,\n isInteractionCorrect\n};\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport {\n Interaction,\n InteractionTypeId,\n Interactive,\n InteractiveResult,\n StudentAttempt,\n StudentResults\n} from 'libs/shared/interfaces';\n\nfunction interactionRequiresAnswer(interaction: Interaction): boolean {\n return interaction.typeId !== InteractionTypeId.Annotation && interaction.typeId !== InteractionTypeId.Image;\n}\n\nexport function flattenInteractions(interactive: Interactive): Interaction[] {\n return ArrayHelper.flatten(interactive.timepoints.map(i => i.interactions));\n}\n\n/**\n * Centralised logic for using the most recent student result.\n */\nexport function getStudentResult(studentResults: StudentResults): InteractiveResult {\n return ArrayHelper.last(studentResults.results);\n}\n\nexport function getStudentAttempt(interactionId: string, result: InteractiveResult): StudentAttempt {\n return ArrayHelper.findWhere(result?.attempts, { id: interactionId });\n}\n\n/**\n * Returns a flat list of interactions on an interactive and filters out\n * those that don't require an answer (annotations and images).\n */\nexport function getInteractions(interactive: Interactive): Interaction [] {\n return flattenInteractions(interactive).filter(interactionRequiresAnswer);\n}"],"names":["groupStudents","interactive","results","scoreThreshold","groups","markingRequired","lowScore","highScore","completed","notCompleted","numInteractions","length","students","forEach","s","withSummary","summary","getStudentResultsSummary","awaitingMarking","push","attempts","percentCorrect","HIGH","MODERATE","sortedLowScore","sortedHighScore","getInteractionById","interactionId","find","i","id","toString","getMarkedAnswerId","answer","questionId","resultId","getMarkedStatus","studentResults","markedAnswers","result","studentResponse","answers","every","a","status","getInteractionResultsSummary","interaction","numStudents","numCorrect","answered","unanswered","correctness","correct","interactions","interactionIds","Set","map","answeredInteractions","filter","has","namespace","getPhrase","InteractiveEditSuggestedResponse","props","alert","fetchAsync","useGetFetchAsync","showSpinner","setShowSpinner","interactiveMetadata","interactiveId","data","suggestedResponse","setSuggestedResponse","title","closePopup","className","htmlFor","phrase","placeholder","onChange","e","target","value","rows","onClick","variant","text","actionableItems","name","success","error","ScoreThresholdDefaults","ScoreThresholdInsights","InteractionCorrectness","InteractiveAnswerStatus","notApplicable","isMissingWordCorrect","getStudentAnswer","items","isCorrect","trim","toLowerCase","isMultipleChoiceCorrect","studentAnswer","getGetStudentAnswer","attempt","wrapIsMultipleChoiceCorrect","wrapIsMarkableAnswerMarkedCorrect","item","isMarkableAnswerMarkedCorrect","IsCorrectLookup","InteractiveCorrectnessHelper","isInteractionCorrect","isCorrectFn","typeId","interactionRequiresAnswer","flattenInteractions","timepoints","getStudentResult","getStudentAttempt","getInteractions"],"sourceRoot":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[2978],{9570:(e,t,r)=>{r.d(t,{d:()=>C});var n=r(32735),a=r(40424),s=r(23481),i=r(75896),o=r(83914),c=r(8246),u=r(35223);function l(e){var t=e.answer;return n.createElement("div",{key:t.id,className:"".concat(function(e){switch(e){case c.N.Correct:return"bg-light-green";case c.N.Incorrect:return"bg-light-red";case c.N.PendingReview:return"bg-light-blue"}}(t.status)," rounded p-2 mb-2")},n.createElement("div",{className:"d-flex align-items-center gap-2"},t.status===c.N.Correct&&n.createElement(o.x,{svgName:u.vn.Check,className:"svg-container flex-shrink-0 text-success"}),t.status===c.N.Incorrect&&n.createElement(o.x,{svgName:u.vn.Close,className:"svg-container flex-shrink-0 text-danger"}),!e.customAnswer&&n.createElement("span",{className:e.textClassName},t.text)),e.children)}var m=s.T.encloseNamespace("shared.interactionResponses");function d(e){return d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},d(e)}function v(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=d(e)||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,"string");if("object"!=d(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==d(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var f=function(){return n.createElement(n.Fragment,null)},g=v(v(v(v(v(v(v({},a.Z9.Annotation,f),a.Z9.Image,f),a.Z9.MissingWord,(function(e){return e.answers.length?n.createElement("ul",{className:"list-unstyled"},e.answers.map((function(e){return n.createElement(l,{key:e.id,answer:e,textClassName:"bg-white p-1 border border-gray-300 rounded"})}))):n.createElement(n.Fragment,null)})),a.Z9.MultipleChoice,(function(e){return e.answers.length?n.createElement("ul",{className:"list-unstyled"},e.answers.map((function(e){return n.createElement("li",{key:e.id},n.createElement(l,{answer:e}))}))):n.createElement(n.Fragment,null)})),a.Z9.TrueOrFalse,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t}):n.createElement(n.Fragment,null)})),a.Z9.ShortAnswer,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t},e.children):n.createElement(n.Fragment,null)})),a.Z9.Illustration,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t,customAnswer:!0},n.createElement("div",{className:"ratio ratio-16x9"},n.createElement("img",{className:"img-fluid bg-white border rounded h-100 w-100",src:t.text,alt:"".concat(m("illustrationAlt"),": ").concat(e.interaction.name)})),e.children):n.createElement(n.Fragment,null)})),y=r(20789),p=r(44526),w=r(56151),h=r(3894),b=r(69737),E=r(83140),S=r(80845),k=r(64818);const I={avatarContainer:"O7oaA"};function C(e){var t,r,a,s,i,o=g[e.interaction.typeId];if(!o)return n.createElement(n.Fragment,null);var c=(0,S.j_)(e.studentResults),u=(0,S.f6)(e.interaction.id,c),l=E.A.isInteractionCorrect(e.interaction,c);return n.createElement("div",{className:"rounded ".concat(null!==(t=e.className)&&void 0!==t?t:"")},n.createElement("div",{className:"d-flex"},!!e.showStudentDetails&&n.createElement("div",{className:"me-2"},n.createElement("div",{className:I.avatarContainer},n.createElement(y.q,{imageCdnUrl:e.imageCdnUrl,initials:e.anonymisedUserName?k.l.getInitialsFromFullName(e.anonymisedUserName):k.l.getInitials(null===(r=e.studentResults.user)||void 0===r?void 0:r.name,null===(a=e.studentResults.user)||void 0===a?void 0:a.surname),imageUrl:e.anonymisedUserName?null:null===(i=null===(s=e.studentResults.user)||void 0===s?void 0:s.avatar)||void 0===i?void 0:i.url}))),n.createElement("div",{className:"flex-grow-1"},!!e.showStudentDetails&&n.createElement(w.U,{studentResults:e.studentResults,correctness:l,anonymisedUserName:e.anonymisedUserName}),n.createElement("div",{className:"d-flex justify-content-between"},n.createElement("div",{className:"flex-grow-1 mb-2 ".concat(e.responseComponentClass?e.responseComponentClass:"")},u?n.createElement(o,{interaction:e.interaction,answers:u.answers,imageCdnUrl:e.imageCdnUrl,user:e.studentResults.user,showFeedback:e.showFeedback,showAvatar:e.showAvatar},n.createElement(h.Z,{studentAttempt:u,correctness:l,markInteraction:e.markInteraction,markedStatus:e.markedStatus})):n.createElement(b.R,null)),!e.showStudentDetails&&n.createElement(p.Y,{correctness:l})))))}},71553:(e,t,r)=>{r.d(t,{I:()=>i});var n=r(99940),a=r(62875);function s(e,t){return{currentUserId:e.id,currentCustomerId:e.customerId,dateRange:{start:t.start,end:t.end},userIds:t.userId,classroomsAndGroups:t.groupId}}var i={interactiveResultSet:function(e,t,r,i,o,c,u){return{url:"/api/domain/v2/analytics/interactives/".concat(e,"/metadata/").concat(t),key:(0,a.H)("interactive:result:set:".concat(e,":").concat(t),i),data:s(r,i),type:n.k.POST,normalize:!1,success:o,error:c,always:u}},mark:function(e,t,r,a,s,i,o){return{url:"/api/domain/v1/analytics/answers/".concat(r),key:"mark:answer:".concat(r,":").concat(a.resultId),type:n.k.PUT,data:a,normalize:!1,invalidationKeys:"interactive:result:set:".concat(e,":").concat(t),success:s,error:i,always:o}},pendingReviews:function(e){return{url:"/api/domain/v1/analytics/interactives/pending-reviews/summary",key:"interactives:pending:reviews",type:n.k.POST,data:e}},interactiveResultsReport:function(e){return{url:"{gateway}/v2/analytics/interactives/report",key:"interactive:results:report",data:e,type:n.k.POST,normalize:!1}}}},41196:(e,t,r)=>{r.d(t,{W:()=>o});var n=r(20354),a=r(71553),s=r(20768),i=r(31949);function o(e,t){var r,o=n.a.useBasicFetch(i.N.currentUser()),c=n.a.useBasicFetch(!!e&&s.b.interactiveMetadata(e)),u=n.a.useBasicFetch(!!(null===(r=c.data)||void 0===r?void 0:r.interactiveId)&&s.b.interactive(c.data.interactiveId)),l=!!o.data&&!!u.data&&!!t;return n.a.useBasicFetch(l&&a.I.interactiveResultSet(c.data.interactiveId,c.data.id,o.data,t))}},9193:(e,t,r)=>{r.d(t,{D:()=>v});var n=r(32735),a=r(70680),s=r(23481),i=r(20354),o=r(71553),c=r(39157),u=r(69883);function l(e){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},l(e)}function m(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var d=s.T.encloseNamespace("reportsShared.dataHooks"),v=function(e,t,r){var s,v,f=(s=(0,n.useState)({}),v=2,function(e){if(Array.isArray(e))return e}(s)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,s,i,o=[],c=!0,u=!1;try{if(s=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=s.call(r)).done)&&(o.push(n.value),o.length!==t);c=!0);}catch(e){u=!0,a=e}finally{try{if(!c&&null!=r.return&&(i=r.return(),Object(i)!==i))return}finally{if(u)throw a}}return o}}(s,v)||function(e,t){if(e){if("string"==typeof e)return m(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?m(e,t):void 0}}(s,v)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),g=f[0],y=f[1],p=(0,a.I0)(),w=(0,u.Z)();return{markedAnswers:g,addMarkedAnswers:function(e,t){e.forEach((function(e){y((function(r){return Object.assign(Object.assign({},r),function(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=l(e)||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,"string");if("object"!=l(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==l(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}({},(0,c.UU)(e),Object.assign(Object.assign({},e),{status:t})))}))}))},submitMarkedAnswers:function(){var n=Object.keys(g).map((function(e){return g[e]}));if(n.length){var a=0,s=0;n.forEach((function(r){var n=r.id,a=r.resultId,s=r.questionId,l=r.status;i.a.fetch(p,o.I.mark(e,t,n,{id:n,resultId:a,questionId:s,status:l},c,null,u))}))}function c(){s++}function u(){var e,t;++a===n.length&&(e="",t=!1,0===s&&(e=d("error",{smartCount:n.length}),t=!0),s<a&&(e=d("success",{smartCount:s})+" ".concat(d("partialError",{smartCount:a-s}))),s===a&&(e=d("success",{smartCount:s})),t?w.error(e):w.success(e),y({}),r&&r())}}}}},39157:(e,t,r)=>{r.d(t,{HI:()=>d,R6:()=>u,Rt:()=>f,UU:()=>m,Zs:()=>l,nq:()=>v});var n=r(75896),a=r(94892),s=r(28972),i=r(8246),o=r(83140),c=r(80845);function u(e,t,r){var s={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},i=(0,c.Q)(e).length;t.students.forEach((function(t){var o=Object.assign(Object.assign({},t),{summary:f(e,t)});o.summary.awaitingMarking?s.markingRequired.push(o):n.m.last(t.results).attempts.length===i?(s.completed.push(o),o.summary.percentCorrect>=(r.HIGH||a.i.HIGH)&&s.highScore.push(o),o.summary.percentCorrect<(r.MODERATE||a.i.MODERATE)&&s.lowScore.push(o)):s.notCompleted.push(o)}));var o=n.m.sortBy(s.lowScore,(function(e){return e.summary.percentCorrect})),u=n.m.sortBy(s.highScore,(function(e){return-e.summary.percentCorrect}));return Object.assign(Object.assign({},s),{lowScore:o,highScore:u})}function l(e,t){return(0,c.Wn)(e).find((function(e){return e.id.toString()===t.toString()}))}function m(e){return"".concat(e.questionId,":").concat(e.resultId)}function d(e,t,r){var n=(0,c.j_)(t),a=(0,c.f6)(e,n);return(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=r[m(e)])||void 0===t?void 0:t.status)===i.N.Correct})))?i.N.Correct:(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=r[m(e)])||void 0===t?void 0:t.status)===i.N.Incorrect})))?i.N.Incorrect:void 0}function v(e,t){var r=t.students.length,n=0,a=0,i=0,u=0,l=0;return t.students.forEach((function(t){var r=(0,c.j_)(t);if(r){l+=t.results.length;var m=o.A.isInteractionCorrect(e,r);m===s.w.Correct&&n++,m===s.w.UnAnswered&&i++,m===s.w.AwaitingMarking&&u++,m!==s.w.UnAnswered&&a++}})),{percentCorrect:r>0?n/r:0,correct:n,answered:a,unanswered:i,awaitingMarking:u,attempts:l}}function f(e,t){var r=(0,c.j_)(t),n=(0,c.Q)(e),a=n.length,i=0,u=0;n.forEach((function(e){var t=o.A.isInteractionCorrect(e,r);t===s.w.Correct&&i++,t===s.w.AwaitingMarking&&u++}));var l=a>0?i/a:0,m=new Set(n.map((function(e){return e.id}))),d=r.attempts.filter((function(e){var t;return!!m.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)})).length;return{answered:r.attempts.length,attempts:t.results.length,unanswered:a-d,percentCorrect:l,correct:i,awaitingMarking:u}}}}]);
|
|
2
|
-
//# sourceMappingURL=2978-
|
|
1
|
+
"use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[2978],{9570:(e,t,r)=>{r.d(t,{d:()=>C});var n=r(32735),a=r(40424),s=r(23481),i=r(75896),o=r(83914),c=r(8246),u=r(35223);function l(e){var t=e.answer;return n.createElement("div",{key:t.id,className:"".concat(function(e){switch(e){case c.N.Correct:return"bg-light-green";case c.N.Incorrect:return"bg-light-red";case c.N.PendingReview:return"bg-light-blue"}}(t.status)," rounded p-2 mb-2")},n.createElement("div",{className:"d-flex align-items-center gap-2"},t.status===c.N.Correct&&n.createElement(o.x,{svgName:u.vn.Check,className:"svg-container flex-shrink-0 text-success"}),t.status===c.N.Incorrect&&n.createElement(o.x,{svgName:u.vn.Close,className:"svg-container flex-shrink-0 text-danger"}),!e.customAnswer&&n.createElement("span",{className:e.textClassName},t.text)),e.children)}var m=s.T.encloseNamespace("shared.interactionResponses");function d(e){return d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},d(e)}function v(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=d(e)||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,"string");if("object"!=d(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==d(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var f=function(){return n.createElement(n.Fragment,null)},g=v(v(v(v(v(v(v({},a.Z9.Annotation,f),a.Z9.Image,f),a.Z9.MissingWord,(function(e){return e.answers.length?n.createElement("ul",{className:"list-unstyled"},e.answers.map((function(e){return n.createElement(l,{key:e.id,answer:e,textClassName:"bg-white p-1 border border-gray-300 rounded"})}))):n.createElement(n.Fragment,null)})),a.Z9.MultipleChoice,(function(e){return e.answers.length?n.createElement("ul",{className:"list-unstyled"},e.answers.map((function(e){return n.createElement("li",{key:e.id},n.createElement(l,{answer:e}))}))):n.createElement(n.Fragment,null)})),a.Z9.TrueOrFalse,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t}):n.createElement(n.Fragment,null)})),a.Z9.ShortAnswer,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t},e.children):n.createElement(n.Fragment,null)})),a.Z9.Illustration,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t,customAnswer:!0},n.createElement("div",{className:"ratio ratio-16x9"},n.createElement("img",{className:"img-fluid bg-white border rounded h-100 w-100",src:t.text,alt:"".concat(m("illustrationAlt"),": ").concat(e.interaction.name)})),e.children):n.createElement(n.Fragment,null)})),y=r(20789),p=r(44526),w=r(56151),h=r(3894),b=r(69737),E=r(83140),S=r(80845),k=r(64818);const I={avatarContainer:"O7oaA"};function C(e){var t,r,a,s,i,o=g[e.interaction.typeId];if(!o)return n.createElement(n.Fragment,null);var c=(0,S.j_)(e.studentResults),u=(0,S.f6)(e.interaction.id,c),l=E.A.isInteractionCorrect(e.interaction,c);return n.createElement("div",{className:"rounded ".concat(null!==(t=e.className)&&void 0!==t?t:"")},n.createElement("div",{className:"d-flex"},!!e.showStudentDetails&&n.createElement("div",{className:"me-2"},n.createElement("div",{className:I.avatarContainer},n.createElement(y.q,{imageCdnUrl:e.imageCdnUrl,initials:e.anonymisedUserName?k.l.getInitialsFromFullName(e.anonymisedUserName):k.l.getInitials(null===(r=e.studentResults.user)||void 0===r?void 0:r.name,null===(a=e.studentResults.user)||void 0===a?void 0:a.surname),imageUrl:e.anonymisedUserName?null:null===(i=null===(s=e.studentResults.user)||void 0===s?void 0:s.avatar)||void 0===i?void 0:i.url}))),n.createElement("div",{className:"flex-grow-1"},!!e.showStudentDetails&&n.createElement(w.U,{studentResults:e.studentResults,correctness:l,anonymisedUserName:e.anonymisedUserName}),n.createElement("div",{className:"d-flex justify-content-between"},n.createElement("div",{className:"flex-grow-1 mb-2 ".concat(e.responseComponentClass?e.responseComponentClass:"")},u?n.createElement(o,{interaction:e.interaction,answers:u.answers,imageCdnUrl:e.imageCdnUrl,user:e.studentResults.user,showFeedback:e.showFeedback,showAvatar:e.showAvatar},n.createElement(h.Z,{studentAttempt:u,correctness:l,markInteraction:e.markInteraction,markedStatus:e.markedStatus})):n.createElement(b.R,null)),!e.showStudentDetails&&n.createElement(p.Y,{correctness:l})))))}},71553:(e,t,r)=>{r.d(t,{I:()=>i});var n=r(99940),a=r(62875);function s(e,t){return{currentUserId:e.id,currentCustomerId:e.customerId,dateRange:{start:t.start,end:t.end},userIds:t.userId,classroomsAndGroups:t.groupId}}var i={interactiveResultSet:function(e,t,r,i,o,c,u){return{url:"/api/domain/v2/analytics/interactives/".concat(e,"/metadata/").concat(t),key:(0,a.H)("interactive:result:set:".concat(e,":").concat(t),i),data:s(r,i),type:n.k.POST,normalize:!1,success:o,error:c,always:u}},mark:function(e,t,r,a,s,i,o){return{url:"/api/domain/v1/analytics/answers/".concat(r),key:"mark:answer:".concat(r,":").concat(a.resultId),type:n.k.PUT,data:a,normalize:!1,invalidationKeys:"interactive:result:set:".concat(e,":").concat(t),success:s,error:i,always:o}},pendingReviews:function(e){return{url:"/api/domain/v1/analytics/interactives/pending-reviews/summary",key:"interactives:pending:reviews",type:n.k.POST,data:e}},interactiveResultsReport:function(e){return{url:"{gateway}/v2/analytics/interactives/report",key:"interactive:results:report",data:e,type:n.k.POST,normalize:!1}}}},41196:(e,t,r)=>{r.d(t,{W:()=>o});var n=r(20354),a=r(71553),s=r(20768),i=r(31949);function o(e,t){var r,o=n.a.useBasicFetch(i.N.currentUser()),c=n.a.useBasicFetch(!!e&&s.b.interactiveMetadata(e)),u=n.a.useBasicFetch(!!(null===(r=c.data)||void 0===r?void 0:r.interactiveId)&&s.b.interactive(c.data.interactiveId)),l=!!o.data&&!!u.data&&!!t;return n.a.useBasicFetch(l&&a.I.interactiveResultSet(c.data.interactiveId,c.data.id,o.data,t))}},9193:(e,t,r)=>{r.d(t,{D:()=>v});var n=r(32735),a=r(70680),s=r(23481),i=r(20354),o=r(71553),c=r(39157),u=r(69883);function l(e){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},l(e)}function m(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var d=s.T.encloseNamespace("reportsShared.dataHooks"),v=function(e,t,r){var s,v,f=(s=(0,n.useState)({}),v=2,function(e){if(Array.isArray(e))return e}(s)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,s,i,o=[],c=!0,u=!1;try{if(s=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=s.call(r)).done)&&(o.push(n.value),o.length!==t);c=!0);}catch(e){u=!0,a=e}finally{try{if(!c&&null!=r.return&&(i=r.return(),Object(i)!==i))return}finally{if(u)throw a}}return o}}(s,v)||function(e,t){if(e){if("string"==typeof e)return m(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?m(e,t):void 0}}(s,v)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),g=f[0],y=f[1],p=(0,a.I0)(),w=(0,u.Z)();return{markedAnswers:g,addMarkedAnswers:function(e,t){e.forEach((function(e){y((function(r){return Object.assign(Object.assign({},r),function(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=l(e)||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,"string");if("object"!=l(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==l(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}({},(0,c.UU)(e),Object.assign(Object.assign({},e),{status:t})))}))}))},submitMarkedAnswers:function(){var n=Object.keys(g).map((function(e){return g[e]}));if(n.length){var a=0,s=0;n.forEach((function(r){var n=r.id,a=r.resultId,s=r.questionId,l=r.status;i.a.fetch(p,o.I.mark(e,t,n,{id:n,resultId:a,questionId:s,status:l},c,null,u))}))}function c(){s++}function u(){var e,t;++a===n.length&&(e="",t=!1,0===s&&(e=d("error",{smartCount:n.length}),t=!0),s<a&&(e=d("success",{smartCount:s})+" ".concat(d("partialError",{smartCount:a-s}))),s===a&&(e=d("success",{smartCount:s})),t?w.error(e):w.success(e),y({}),r&&r())}}}}},39157:(e,t,r)=>{r.d(t,{HI:()=>d,R6:()=>u,Rt:()=>f,UU:()=>m,Zs:()=>l,nq:()=>v});var n=r(75896),a=r(94892),s=r(28972),i=r(8246),o=r(83140),c=r(80845);function u(e,t,r){var s={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},i=(0,c.Q)(e).length;t.students.forEach((function(t){var o=Object.assign(Object.assign({},t),{summary:f(e,t)});o.summary.awaitingMarking?s.markingRequired.push(o):n.m.last(t.results).attempts.length===i?(s.completed.push(o),o.summary.percentCorrect>=((null==r?void 0:r.HIGH)||a.i.HIGH)&&s.highScore.push(o),o.summary.percentCorrect<((null==r?void 0:r.MODERATE)||a.i.MODERATE)&&s.lowScore.push(o)):s.notCompleted.push(o)}));var o=n.m.sortBy(s.lowScore,(function(e){return e.summary.percentCorrect})),u=n.m.sortBy(s.highScore,(function(e){return-e.summary.percentCorrect}));return Object.assign(Object.assign({},s),{lowScore:o,highScore:u})}function l(e,t){return(0,c.Wn)(e).find((function(e){return e.id.toString()===t.toString()}))}function m(e){return"".concat(e.questionId,":").concat(e.resultId)}function d(e,t,r){var n=(0,c.j_)(t),a=(0,c.f6)(e,n);return(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=r[m(e)])||void 0===t?void 0:t.status)===i.N.Correct})))?i.N.Correct:(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=r[m(e)])||void 0===t?void 0:t.status)===i.N.Incorrect})))?i.N.Incorrect:void 0}function v(e,t){var r=t.students.length,n=0,a=0,i=0,u=0,l=0;return t.students.forEach((function(t){var r=(0,c.j_)(t);if(r){l+=t.results.length;var m=o.A.isInteractionCorrect(e,r);m===s.w.Correct&&n++,m===s.w.UnAnswered&&i++,m===s.w.AwaitingMarking&&u++,m!==s.w.UnAnswered&&a++}})),{percentCorrect:r>0?n/r:0,correct:n,answered:a,unanswered:i,awaitingMarking:u,attempts:l}}function f(e,t){var r=(0,c.j_)(t),n=(0,c.Q)(e),a=n.length,i=0,u=0;n.forEach((function(e){var t=o.A.isInteractionCorrect(e,r);t===s.w.Correct&&i++,t===s.w.AwaitingMarking&&u++}));var l=a>0?i/a:0,m=new Set(n.map((function(e){return e.id}))),d=r.attempts.filter((function(e){var t;return!!m.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)})).length;return{answered:r.attempts.length,attempts:t.results.length,unanswered:a-d,percentCorrect:l,correct:i,awaitingMarking:u}}}}]);
|
|
2
|
+
//# sourceMappingURL=2978-e4a60f90a5-lite.chunk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scripts/2978-e4a60f90a5-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/IllustrationResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/MissingWordResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/MultipleChoiceResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/TrueOrFalseResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/ShortAnswerResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/interaction-response-item.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/InteractionResponseItem.tsx","file:///app/packages/libs/shared/src/apps/analytics/flight-requests/InteractiveResultsRequests.ts","file:///app/packages/libs/shared/src/apps/analytics/hooks/UseFetchInteractiveResults.ts","file:///app/packages/libs/shared/src/apps/analytics/hooks/UseMarkAnswers.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/InteractiveUtils.ts"],"sourcesContent":["import React from 'react';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { StudentAnswer } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\ninterface AnswerContainerProps extends React.PropsWithChildren {\n answer: StudentAnswer;\n textClassName?: string;\n customAnswer?: boolean;\n}\n\nexport function AnswerContainer(props: AnswerContainerProps) {\n const { answer } = props;\n\n function getBgColour(status: InteractiveAnswerStatus) {\n switch (status) {\n case InteractiveAnswerStatus.Correct: return 'bg-light-green';\n case InteractiveAnswerStatus.Incorrect: return 'bg-light-red';\n case InteractiveAnswerStatus.PendingReview: return 'bg-light-blue';\n }\n }\n\n return (\n <div key={answer.id} className={`${getBgColour(answer.status)} rounded p-2 mb-2`}>\n <div className='d-flex align-items-center gap-2'>\n {answer.status === InteractiveAnswerStatus.Correct && <SvgContainer svgName={cvSvgLibrary.Check} className='svg-container flex-shrink-0 text-success' />}\n {answer.status === InteractiveAnswerStatus.Incorrect && <SvgContainer svgName={cvSvgLibrary.Close} className='svg-container flex-shrink-0 text-danger' />}\n {!props.customAnswer && <span className={props.textClassName}>{answer.text}</span>}\n </div>\n {props.children}\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nconst namespace = 'shared.interactionResponses';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function IllustrationResponse(props: ResponseItemComponentProps): JSX.Element {\n const answer = ArrayHelper.first(props.answers);\n\n if (!answer)\n return <></>;\n\n return (\n <AnswerContainer answer={answer} customAnswer>\n <div className='ratio ratio-16x9'>\n <img\n className='img-fluid bg-white border rounded h-100 w-100'\n src={answer.text}\n alt={`${getPhrase('illustrationAlt')}: ${props.interaction.name}`}\n />\n </div>\n {props.children}\n </AnswerContainer>\n );\n}","import React from 'react';\n\nimport { Interaction, InteractionTypeId, StudentAnswer, User } from 'libs/shared/interfaces';\n\nimport { IllustrationResponse } from './components/IllustrationResponse';\nimport { MissingWordResponse } from './components/MissingWordResponse';\nimport { MultipleChoiceResponse } from './components/MultipleChoiceResponse';\nimport { ShortAnswerResponse } from './components/ShortAnswerResponse';\nimport { TrueOrFalseResponse } from './components/TrueOrFalseResponse';\n\nexport interface ResponseItemComponentProps extends React.PropsWithChildren {\n interaction: Interaction;\n answers: StudentAnswer[];\n imageCdnUrl: string;\n user: User;\n showFeedback?: boolean;\n showAvatar?: boolean;\n anonymisedUserName?: string;\n}\nconst NoResponseRequired = () => <></>;\n\nexport const ResponseItemComponentLookup: {\n [typeId: number]: (props: ResponseItemComponentProps) => JSX.Element\n} = {\n [InteractionTypeId.Annotation]: NoResponseRequired,\n [InteractionTypeId.Image]: NoResponseRequired,\n [InteractionTypeId.MissingWord]: MissingWordResponse,\n [InteractionTypeId.MultipleChoice]: MultipleChoiceResponse,\n [InteractionTypeId.TrueOrFalse]: TrueOrFalseResponse,\n [InteractionTypeId.ShortAnswer]: ShortAnswerResponse,\n [InteractionTypeId.Illustration]: IllustrationResponse\n};","import React from 'react';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\n\nexport function MissingWordResponse(props: ResponseItemComponentProps) {\n if (!props.answers.length) return <></>;\n\n return (\n <ul className='list-unstyled'>\n {props.answers.map(answer => (\n <AnswerContainer\n key={answer.id}\n answer={answer}\n textClassName='bg-white p-1 border border-gray-300 rounded'\n />\n ))}\n </ul>\n );\n}","import React from 'react';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function MultipleChoiceResponse(props: ResponseItemComponentProps) {\n if (!props.answers.length) return <></>;\n\n return (\n <ul className='list-unstyled'>\n {props.answers.map(answer => (\n <li key={answer.id}>\n <AnswerContainer answer={answer} />\n </li>\n ))}\n </ul>\n );\n}","import React from 'react';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function TrueOrFalseResponse(props: ResponseItemComponentProps) {\n const answer = ArrayHelper.first(props.answers);\n\n if (!answer)\n return <></>;\n\n return (\n <AnswerContainer answer={answer} />\n );\n}","import React from 'react';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function ShortAnswerResponse(props: ResponseItemComponentProps): JSX.Element {\n const answer = ArrayHelper.first(props.answers);\n\n if (!answer)\n return <></>;\n\n return (\n <AnswerContainer answer={answer}>\n {props.children}\n </AnswerContainer>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"avatarContainer\":\"O7oaA\"};","import React from 'react';\n\nimport { ResponseItemComponentLookup } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { InteractionResponseCorrectness } from 'libs/shared/components/interaction-response/InteractionResponseCorrectness';\nimport { InteractionStudentDetailsHeader } from 'libs/shared/components/interaction-response/InteractionStudentDetailsHeader';\nimport { MarkResponse } from 'libs/shared/components/interaction-response/MarkResponse';\nimport { NoResponse } from 'libs/shared/components/interaction-response/response-types/NoResponse';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from './interaction-response-item.scss';\n\ninterface InteractionResponseProps {\n interaction: Interaction;\n studentResults: StudentResults;\n imageCdnUrl: string;\n markInteraction: (answers: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n markedStatus?: InteractiveAnswerStatus;\n showStudentDetails?: boolean;\n className?: string;\n showFeedback?: boolean;\n showAvatar?: boolean;\n anonymisedUserName?: string;\n responseComponentClass?: string;\n}\n\nexport function InteractionResponseItem(props: InteractionResponseProps): JSX.Element {\n const ResponseItemComponent = ResponseItemComponentLookup[props.interaction.typeId];\n\n if (!ResponseItemComponent)\n return <></>;\n\n const result = getStudentResult(props.studentResults);\n\n const studentAttempt = getStudentAttempt(props.interaction.id, result);\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(props.interaction, result);\n\n return (\n <div className={`rounded ${props.className ?? ''}`}>\n <div className='d-flex'>\n {!!props.showStudentDetails &&\n <div className='me-2'>\n <div className={styles.avatarContainer}>\n <Avatar\n imageCdnUrl={props.imageCdnUrl}\n initials={props.anonymisedUserName\n ? UserHelper.getInitialsFromFullName(props.anonymisedUserName)\n : UserHelper.getInitials(props.studentResults.user?.name, props.studentResults.user?.surname)\n }\n imageUrl={props.anonymisedUserName ? null : props.studentResults.user?.avatar?.url}\n />\n </div>\n </div>\n }\n <div className='flex-grow-1'>\n {!!props.showStudentDetails &&\n <InteractionStudentDetailsHeader\n studentResults={props.studentResults}\n correctness={correctness}\n anonymisedUserName={props.anonymisedUserName}\n />\n }\n <div className='d-flex justify-content-between'>\n <div className={`flex-grow-1 mb-2 ${props.responseComponentClass ? props.responseComponentClass : ''}`}>\n {studentAttempt\n ? <ResponseItemComponent\n interaction={props.interaction}\n answers={studentAttempt.answers}\n imageCdnUrl={props.imageCdnUrl}\n user={props.studentResults.user}\n showFeedback={props.showFeedback}\n showAvatar={props.showAvatar}\n >\n <MarkResponse\n studentAttempt={studentAttempt}\n correctness={correctness}\n markInteraction={props.markInteraction}\n markedStatus={props.markedStatus}\n />\n </ResponseItemComponent>\n : <NoResponse />\n }\n </div>\n {!props.showStudentDetails &&\n <InteractionResponseCorrectness correctness={correctness} />\n }\n </div>\n </div>\n </div>\n </div>\n );\n}","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Flight } from 'libs/common/react/index';\n\nimport { MarkInteractiveAnswer } from 'libs/shared/apps/analytics/interfaces/MarkInteractiveAnswer';\nimport { InteractiveResultsReport } from 'libs/shared/apps/analytics/interfaces/requests/InteractiveResultsReport';\nimport { InteractivesPendingReviewsRequest } from 'libs/shared/apps/analytics/interfaces/requests/InteractivesPendingReviewsRequest';\nimport { AnalyticsRequestFilter, CurrentUser, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getAnalyticsRequestKey } from 'libs/shared/utils/AnalyticsRequestUtils';\n\ninterface InteractiveResultFilters {\n currentUserId: string;\n currentCustomerId: string;\n dateRange?: { start: string, end: string }\n userIds?: string | string[];\n classroomsAndGroups?: string | string[];\n}\n\nfunction getInteractiveResultFilters(\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter\n): InteractiveResultFilters {\n return {\n currentUserId: currentUser.id,\n currentCustomerId: currentUser.customerId,\n dateRange: { start: filter.start, end: filter.end },\n userIds: filter.userId,\n classroomsAndGroups: filter.groupId\n };\n}\n\nexport const InteractiveResultsRequests = {\n /** \n * This endpoint returns data with a lot of duplicated ids,\n * e.g. student answers to the same question will have the same id.\n * Because of that, we don't normalize.\n */\n interactiveResultSet(\n interactiveId: string,\n interactiveMetadataId: string,\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter,\n success?: (data: InteractiveResultSet) => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v2/analytics/interactives/${interactiveId}/metadata/${interactiveMetadataId}`,\n key: getAnalyticsRequestKey(`interactive:result:set:${interactiveId}:${interactiveMetadataId}`, filter),\n data: getInteractiveResultFilters(currentUser, filter),\n type: HttpVerbs.POST,\n normalize: false,\n success,\n error,\n always\n };\n },\n \n /**\n * As the response from `interactiveResultSet` isn't normalised, we need to invalidate the cache\n * to update the results data.\n */\n mark(\n interactiveId: string,\n interactiveMetadataId: string,\n answerId: string,\n data: MarkInteractiveAnswer,\n success?: () => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v1/analytics/answers/${answerId}`,\n key: `mark:answer:${answerId}:${data.resultId}`,\n type: HttpVerbs.PUT,\n data,\n normalize: false,\n invalidationKeys: `interactive:result:set:${interactiveId}:${interactiveMetadataId}`,\n success,\n error,\n always\n };\n },\n\n pendingReviews(data: InteractivesPendingReviewsRequest): Flight.Request {\n return {\n url: `/api/domain/v1/analytics/interactives/pending-reviews/summary`,\n key: `interactives:pending:reviews`,\n type: HttpVerbs.POST,\n data\n };\n },\n\n interactiveResultsReport(data: InteractiveResultsReport): Flight.Request {\n return {\n url: '{gateway}/v2/analytics/interactives/report',\n key: 'interactive:results:report',\n data,\n type: HttpVerbs.POST,\n normalize: false\n };\n }\n};","import { Flight } from 'libs/common/flight';\n\nimport { InteractiveResultsRequests } from 'libs/shared/apps/analytics/flight-requests/InteractiveResultsRequests';\nimport { InteractiveRequests } from 'libs/shared/flight-requests/InteractiveRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { AnalyticsRequestFilter, CurrentUser, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nexport function useFetchInteractiveResults(\n interactiveMetadataId: string,\n requestFilter: AnalyticsRequestFilter\n): Flight.Response<InteractiveResultSet> {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(!!interactiveMetadataId &&\n InteractiveRequests.interactiveMetadata(interactiveMetadataId));\n\n const interactive = Flight.useBasicFetch<Interactive>(!!interactiveMetadata.data?.interactiveId &&\n InteractiveRequests.interactive(interactiveMetadata.data.interactiveId));\n\n const shouldFetchResults = !!currentUser.data && !!interactive.data && (!!requestFilter);\n\n return Flight.useBasicFetch<InteractiveResultSet>(shouldFetchResults &&\n InteractiveResultsRequests.interactiveResultSet(\n interactiveMetadata.data.interactiveId,\n interactiveMetadata.data.id,\n currentUser.data,\n requestFilter\n ));\n}","import { useState } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { InteractiveResultsRequests } from 'libs/shared/apps/analytics/flight-requests/InteractiveResultsRequests';\nimport { getMarkedAnswerId } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { StudentAnswer } from 'libs/shared/interfaces';\n\nconst getPhrase = LanguageService.encloseNamespace('reportsShared.dataHooks');\n\nexport type MarkedAnswerHash = { [id: string]: StudentAnswer };\n\n/**\n * This hook manages the storing of a marked answer hash in state and then the submitting\n * of those answers via an api call.\n */\nexport const useMarkAnswers = (interactiveId: string, interactiveMetadataId: string, onDone?: () => void) => {\n const [ markedAnswers, setMarkedAnswers ] = useState<MarkedAnswerHash>({});\n\n const dispatch = useDispatch();\n const alerts = useAlerts();\n\n function addMarkedAnswers(answers: StudentAnswer[], status: InteractiveAnswerStatus): void {\n answers.forEach(a => {\n setMarkedAnswers(m => ({ ...m, [getMarkedAnswerId(a)]: { ...a, status } }));\n });\n }\n\n function submitMarkedAnswers(): void {\n const answers = Object.keys(markedAnswers).map(key => markedAnswers[key]);\n\n if (!answers.length)\n return;\n\n let completeCount = 0;\n let successCount = 0;\n\n function onSuccess(): void {\n successCount++;\n }\n\n function onAlways(): void {\n completeCount++;\n\n if (completeCount === answers.length)\n onComplete();\n }\n\n function onComplete(): void {\n let alertMessage = '';\n let useErrorAlert = false;\n\n if (successCount === 0) {\n alertMessage = getPhrase('error', { smartCount: answers.length });\n useErrorAlert = true;\n }\n\n if (successCount < completeCount) {\n alertMessage = getPhrase('success', { smartCount: successCount })\n + ` ${getPhrase('partialError', { smartCount: completeCount - successCount })}`;\n }\n\n if (successCount === completeCount) {\n alertMessage = getPhrase('success', { smartCount: successCount });\n }\n\n useErrorAlert\n ? alerts.error(alertMessage)\n : alerts.success(alertMessage);\n\n setMarkedAnswers({});\n\n onDone && onDone();\n }\n\n answers.forEach(({ id, resultId, questionId, status }) => {\n Flight.fetch(dispatch, InteractiveResultsRequests.mark(\n interactiveId,\n interactiveMetadataId,\n id,\n { id, resultId, questionId, status },\n onSuccess,\n null,\n onAlways\n ));\n });\n }\n\n return {\n markedAnswers,\n addMarkedAnswers,\n submitMarkedAnswers\n };\n};","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { Interactive, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { flattenInteractions, getInteractions, getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\ninterface StudentGroups {\n markingRequired: StudentResultsWithSummary[];\n lowScore: StudentResultsWithSummary[];\n highScore: StudentResultsWithSummary[];\n completed: StudentResultsWithSummary[];\n notCompleted: StudentResultsWithSummary[];\n}\n\nexport function groupStudents(\n interactive: Interactive,\n results: InteractiveResultSet,\n scoreThreshold?: ScoreThresholds\n): StudentGroups {\n const groups: StudentGroups = {\n markingRequired: [],\n lowScore: [],\n highScore: [],\n completed: [],\n notCompleted: []\n };\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n \n results.students.forEach(s => {\n const withSummary = {\n ...s,\n summary: getStudentResultsSummary(interactive, s)\n };\n \n if (withSummary.summary.awaitingMarking) {\n groups.markingRequired.push(withSummary);\n return;\n }\n\n if (ArrayHelper.last(s.results).attempts.length === numInteractions) {\n groups.completed.push(withSummary);\n } else {\n groups.notCompleted.push(withSummary);\n return;\n }\n \n if (withSummary.summary.percentCorrect >= (scoreThreshold?.HIGH || ScoreThresholdDefaults.HIGH))\n groups.highScore.push(withSummary);\n \n if (withSummary.summary.percentCorrect < (scoreThreshold?.MODERATE || ScoreThresholdDefaults.MODERATE))\n groups.lowScore.push(withSummary);\n });\n \n const sortedLowScore = ArrayHelper.sortBy(groups.lowScore, s => s.summary.percentCorrect);\n const sortedHighScore = ArrayHelper.sortBy(groups.highScore, s => -s.summary.percentCorrect);\n \n return {\n ...groups,\n lowScore: sortedLowScore,\n highScore: sortedHighScore\n };\n}\n\nexport function getInteractionById(interactive: Interactive, interactionId: string): Interaction {\n const flattenedInteractions = flattenInteractions(interactive);\n return flattenedInteractions.find(i => i.id.toString() === interactionId.toString());\n}\n\n/**\n * We need to use the question and result ids as a list of one student's responses\n * to multiple questions will all have the same result id and a list of multiple\n * students responses to one question will all have the same questionId.\n */\nexport function getMarkedAnswerId(answer: StudentAnswer): string {\n return `${answer.questionId}:${answer.resultId}`;\n}\n\nexport function getMarkedStatus(\n interactionId: string,\n studentResults: StudentResults,\n markedAnswers: MarkedAnswerHash\n): InteractiveAnswerStatus {\n const result = getStudentResult(studentResults);\n const studentResponse = getStudentAttempt(interactionId, result);\n\n const isMarkedCorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Correct;\n });\n\n if (isMarkedCorrect)\n return InteractiveAnswerStatus.Correct;\n\n const isMarkedIncorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Incorrect;\n });\n\n if (isMarkedIncorrect)\n return InteractiveAnswerStatus.Incorrect;\n}\n\nexport function getInteractionResultsSummary(\n interaction: Interaction,\n results: InteractiveResultSet\n): ResultsSummary {\n const numStudents = results.students.length;\n let numCorrect = 0;\n let answered = 0;\n let unanswered = 0;\n let awaitingMarking = 0;\n let attempts = 0;\n\n results.students.forEach(s => {\n const result = getStudentResult(s);\n\n if (!result)\n return;\n\n attempts = attempts + s.results.length;\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(interaction, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.UnAnswered)\n unanswered++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n\n if (correctness !== InteractionCorrectness.UnAnswered)\n answered++;\n });\n\n\n const percentCorrect = numStudents > 0\n ? numCorrect / numStudents\n : 0;\n\n return {\n percentCorrect,\n correct: numCorrect,\n answered,\n unanswered,\n awaitingMarking,\n attempts\n };\n}\n\nexport function getStudentResultsSummary(interactive: Interactive, studentResults: StudentResults): ResultsSummary {\n const result = getStudentResult(studentResults);\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n\n let numCorrect = 0;\n let awaitingMarking = 0;\n\n interactions.forEach(i => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(i, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n });\n\n const percentCorrect = numInteractions > 0 ? numCorrect / numInteractions : 0;\n\n /**\n * Our interactions list has images and annotations filtered out.\n * We built a map of valid questions, so that we can calculate the unswered accurately.\n * We're doing this because of a bug that caused annotations and images to record answers in the player.\n * - Sha\n */\n const interactionIds = new Set(interactions.map(i => i.id));\n const answeredInteractions = result.attempts.filter(a => !!interactionIds.has(a?.answers[0]?.questionId)).length;\n\n return {\n answered: result.attempts.length,\n attempts: studentResults.results.length,\n unanswered: numInteractions - answeredInteractions,\n percentCorrect,\n correct: numCorrect,\n awaitingMarking\n };\n}"],"names":["AnswerContainer","props","answer","key","id","className","status","InteractiveAnswerStatus","getBgColour","SvgContainer","svgName","customAnswer","textClassName","text","children","getPhrase","LanguageService","NoResponseRequired","ResponseItemComponentLookup","answers","length","map","ArrayHelper","src","alt","interaction","name","InteractionResponseItem","ResponseItemComponent","typeId","result","studentResults","studentAttempt","correctness","InteractiveCorrectnessHelper","showStudentDetails","Avatar","imageCdnUrl","initials","anonymisedUserName","UserHelper","user","surname","imageUrl","avatar","url","InteractionStudentDetailsHeader","responseComponentClass","showFeedback","showAvatar","MarkResponse","markInteraction","markedStatus","NoResponse","InteractionResponseCorrectness","getInteractiveResultFilters","currentUser","filter","currentUserId","currentCustomerId","customerId","dateRange","start","end","userIds","userId","classroomsAndGroups","groupId","InteractiveResultsRequests","interactiveResultSet","interactiveId","interactiveMetadataId","success","error","always","data","type","normalize","mark","answerId","resultId","invalidationKeys","pendingReviews","interactiveResultsReport","useFetchInteractiveResults","requestFilter","interactiveMetadata","interactive","shouldFetchResults","I","useMarkAnswers","onDone","useState","markedAnswers","setMarkedAnswers","dispatch","alerts","addMarkedAnswers","forEach","a","m","submitMarkedAnswers","Object","keys","completeCount","successCount","questionId","onSuccess","onAlways","alertMessage","useErrorAlert","smartCount","groupStudents","results","scoreThreshold","groups","markingRequired","lowScore","highScore","completed","notCompleted","numInteractions","students","s","withSummary","summary","getStudentResultsSummary","awaitingMarking","push","attempts","percentCorrect","HIGH","MODERATE","sortedLowScore","sortedHighScore","getInteractionById","interactionId","find","i","toString","getMarkedAnswerId","getMarkedStatus","studentResponse","every","getInteractionResultsSummary","numStudents","numCorrect","answered","unanswered","correct","interactions","interactionIds","Set","answeredInteractions","has"],"sourceRoot":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[8095],{34079:(e,t,n)=>{n.d(t,{O:()=>l});var r=n(32735),a=n(23481),i=n(40782),c=n(36532),o=a.T.encloseNamespace("interactives.pendingIndicator");function s(e){var t="d-flex align-items-center h-100";return t+=e.showLabel?" justify-content-between":" justify-content-center",e.className&&(t+=" ".concat(e.className)),t}function l(e){var t=function(){return r.createElement("div",{className:s(e)},!!e.showLabel&&r.createElement("em",null,o("pending")),r.createElement(i.O,null))};return e.title?r.createElement(c.u,{title:e.title,spanHack:!0,spanHackClassName:e.tooltipClassName||"h-100 w-100 d-flex align-items-center"},r.createElement(t,null)):r.createElement(t,null)}},48258:(e,t,n)=>{n.d(t,{Ju:()=>O,bB:()=>L,l8:()=>_,R7:()=>j,lE:()=>B,Fx:()=>T});var r=n(32735),a=n(23481),i=n(75896),c=n(34079),o=n(26136),s=n(39157),l=n(40782),u=n(80845),d=n(9601),m=n(71151),v=n(93264),f=n(84120);const g={container:"Wf1bl",interaction:"Fpm49"};function w(e){return e.duration?r.createElement(r.Fragment,null,e.interactive.timepoints.map((function(t,n){if(!t.interactions.length)return r.createElement(r.Fragment,null);var a,i,c=(a=t,i=e.selectedInteraction,a.interactions.find((function(e){return e.id===i.id}))||a.interactions[0]),o=c.id===e.selectedInteraction.id,s=o?f.w.getTypeInfo(c.typeId).bgClassName:"bg-gray-500",l=t.visibleAt/1e3/e.duration*100;return r.createElement("div",{key:n,className:"".concat(g.container," text-center"),style:{left:"".concat(l,"%")}},r.createElement("div",{className:"".concat(g.interaction," ").concat(s)}),!!o&&r.createElement("div",null,v.T.ToDisplayDuration(t.visibleAt)))}))):r.createElement(r.Fragment,null)}var p=n(86572);var y=a.T.encloseNamespace("shared.interactionResultsSummary");function h(e){var t,n=r.useMemo((function(){return(0,s.nq)(e.interaction,e.results)}),[e.interaction,e.results]);return r.createElement("div",{className:"px-1 pt-1"},r.createElement("div",{className:"d-flex"},r.createElement(p.y,{interaction:e.interaction,iconClassName:"flex-shrink-0"})),r.createElement("div",{className:"my-4 ".concat("FCXQd")},r.createElement(w,{interactive:e.interactive,duration:(t=e.interactiveMetadata,t._parentClip?t._parentClip.endTime-t._parentClip.startTime:t._parentVideo.duration?t._parentVideo.duration/1e3:0),selectedInteraction:e.interaction})),r.createElement("div",{className:"row pt-1 pb-2"},r.createElement("div",{className:"col-6 pe-1"},r.createElement("div",{className:"bg-light rounded p-2 h-100"},!n.awaitingMarking&&r.createElement("div",{className:"d-flex align-items-center justify-content-between"},r.createElement("strong",null,y("correctlyAnswered")),r.createElement(l.O,{percentage:n.percentCorrect,layout:l.I.LabelOnly})),!!n.awaitingMarking&&r.createElement("div",{className:"d-flex align-items-center justify-content-center"},r.createElement("strong",null,r.createElement("em",null,y("pending")))))),r.createElement("div",{className:"col-6 ps-1"},r.createElement("div",{className:"bg-light rounded h-100 p-2 d-flex align-items-center justify-content-between"},r.createElement("strong",null,y("unanswered")),r.createElement("span",null,n.unanswered)))))}var E=r.forwardRef((function(e,t){var n=e.interaction,a=e.interactive,i=e.interactiveMetadata,c=e.results,o=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(r=Object.getOwnPropertySymbols(e);a<r.length;a++)t.indexOf(r[a])<0&&Object.prototype.propertyIsEnumerable.call(e,r[a])&&(n[r[a]]=e[r[a]])}return n}(e,["interaction","interactive","interactiveMetadata","results"]);return r.createElement("div",{className:"popover-lg"},r.createElement(m.Z,Object.assign({id:"interaction-results-summary-".concat(n.id),ref:t},o),r.createElement(m.Z.Body,null,r.createElement(h,{interaction:n,interactive:a,interactiveMetadata:i,results:c}))))})),b=n(22517);function C(e){var t;return r.createElement(d.Z,{trigger:(null===(t=e.results.students)||void 0===t?void 0:t.length)?"click":null,placement:"bottom",overlay:r.createElement(E,{interaction:e.interaction,interactive:e.interactive,interactiveMetadata:e.interactiveMetadata,results:e.results}),rootClose:!0},r.createElement("div",{className:"text-center h-100\n d-flex align-items-center justify-content-center\n ".concat(b.Z.interactionHeaderCellInner),onMouseEnter:e.onMouseEnter,onMouseLeave:e.onMouseLeave},r.createElement("div",{className:"p-1 position-relative"},e.interactionNumber)))}var I=n(83914),N=n(28972),k=n(83140),M=n(35223);function A(e){var t="".concat(b.Z.resultsCellInner," h-100 position-relative");return e===N.w.Correct&&(t+=" ".concat(b.Z.correct)),e===N.w.Incorrect&&(t+=" ".concat(b.Z.incorrect," text-danger")),e===N.w.AwaitingMarking&&(t+=" ".concat(b.Z.awaitingMarking)),e===N.w.UnAnswered&&(t+=" ".concat(b.Z.unanswered," text-warning")),t}function S(e){var t=k.A.isInteractionCorrect(e.interaction,(0,u.j_)(e.studentResults)),n=function(e){return e===N.w.Correct?M.vn.Check:e===N.w.Incorrect?M.vn.Close:e===N.w.UnAnswered?M.vn.Minus:void 0}(t);return r.createElement("div",{className:A(t)},!!n&&r.createElement(I.x,{svgName:n}),t===N.w.AwaitingMarking&&r.createElement(c.O,null))}var R=a.T.encloseNamespace("shared.studentResultsTable"),O=60;function x(e){var t;return r.createElement("div",{className:"d-flex align-items-center p-2 h-100 ".concat(null!==(t=e.className)&&void 0!==t?t:"")},e.children)}function Z(e){return r.createElement(x,{className:e.column.isSorted&&"fw-bold"},R(e.phraseKey))}function j(e,t){var n,a=!!(null===(n=e.students)||void 0===n?void 0:n.length);return r.useMemo((function(){return[{Header:function(e){var t=e.column;return r.createElement(Z,{column:t,phraseKey:"name"})},accessor:"user",Cell:function(e){var n=e.value;return r.createElement(x,null,r.createElement("span",{className:"text-truncate"},(0,o.B)(n,t)))},disableSortBy:!a},{Header:function(e){var t=e.column;return r.createElement(Z,{column:t,phraseKey:"unanswered"})},accessor:"summary.unanswered",sortType:"basic",sortDescFirst:!0,disableSortBy:!a,Cell:function(e){var t=e.value;return r.createElement(x,null,t)}},{Header:function(e){var t=e.column;return r.createElement(Z,{column:t,phraseKey:"score"})},accessor:"summary",id:"score",Cell:function(e){var t=e.value;return t.awaitingMarking?r.createElement(x,null,r.createElement(c.O,{title:R("markingRequired"),className:"flex-grow-1",showLabel:!0})):r.createElement(x,null,"".concat(t.correct,"/").concat(t.answered+t.unanswered))},width:125,sortDescFirst:!0,disableSortBy:!a},{Header:function(e){var t=e.column;return r.createElement(Z,{column:t,phraseKey:"percentage"})},accessor:"summary",id:"percentage",Cell:function(e){var t=e.value;return t.awaitingMarking?r.createElement(x,null,r.createElement(c.O,{title:R("markingRequired"),className:"flex-grow-1",showLabel:!0})):r.createElement(x,null,r.createElement(l.O,{percentage:t.percentCorrect,layout:l.I.LabelBefore,className:"flex-grow-1"}))},width:125,sortDescFirst:!0,disableSortBy:!a}]}),[t,a])}function B(e,t,n,a,i){return r.useMemo((function(){return(0,u.Q)(e).map((function(i,c){return{Header:function(){return r.createElement(C,{interaction:i,results:n,interactive:e,interactiveMetadata:t,interactionNumber:c+1,onMouseEnter:function(){return a(c)},onMouseLeave:function(){return a(null)}})},accessor:"results",id:i.id,disableSortBy:!0,width:O,Cell:function(e){var t=e.row.original;return r.createElement(S,{interaction:i,studentResults:t})}}}))}),[i])}function T(e,t,n,a,c){return r.useMemo((function(){var n=[];if(t.students.forEach((function(t){n.push(Object.assign(Object.assign({},t),{summary:(0,s.Rt)(e,t)}))})),"user"===(null==c?void 0:c.id)){var r=i.m.sortBy(n,(function(e){return(0,o.B)(e.user,a)}));return c.desc?r.reverse():r}if("summary.unanswered"===(null==c?void 0:c.id)){var l=i.m.sortBy(n,(function(e){return e.summary.unanswered}));return c.desc?l.reverse():l}if("score"===(null==c?void 0:c.id)||"percentage"===(null==c?void 0:c.id)){var u=i.m.sortBy(n,(function(e){return e.summary.awaitingMarking?-1:e.summary.percentCorrect}));return c.desc?u.reverse():u}return n}),[n,c,a])}function L(e,t){if(e){var n=e.querySelectorAll(".".concat(b.Z.resultsRow));null==n||n.forEach((function(e){e.childNodes.forEach((function(e,n){e.classList.remove(b.Z.highlightColumn),n===t&&e.classList.add(b.Z.highlightColumn)}))}))}}function _(e,t){if(e){var n=e.querySelectorAll(".".concat(b.Z.resultsRow));null==n||n.forEach((function(e,n){e.classList.remove(b.Z.highlightResultsRow),n===t&&e.classList.add(b.Z.highlightResultsRow)}))}}},71553:(e,t,n)=>{n.d(t,{I:()=>c});var r=n(99940),a=n(62875);function i(e,t){return{currentUserId:e.id,currentCustomerId:e.customerId,dateRange:{start:t.start,end:t.end},userIds:t.userId,classroomsAndGroups:t.groupId}}var c={interactiveResultSet:function(e,t,n,c,o,s,l){return{url:"/api/domain/v2/analytics/interactives/".concat(e,"/metadata/").concat(t),key:(0,a.H)("interactive:result:set:".concat(e,":").concat(t),c),data:i(n,c),type:r.k.POST,normalize:!1,success:o,error:s,always:l}},mark:function(e,t,n,a,i,c,o){return{url:"/api/domain/v1/analytics/answers/".concat(n),key:"mark:answer:".concat(n,":").concat(a.resultId),type:r.k.PUT,data:a,normalize:!1,invalidationKeys:"interactive:result:set:".concat(e,":").concat(t),success:i,error:c,always:o}},pendingReviews:function(e){return{url:"/api/domain/v1/analytics/interactives/pending-reviews/summary",key:"interactives:pending:reviews",type:r.k.POST,data:e}},interactiveResultsReport:function(e){return{url:"{gateway}/v2/analytics/interactives/report",key:"interactive:results:report",data:e,type:r.k.POST,normalize:!1}}}},41196:(e,t,n)=>{n.d(t,{W:()=>o});var r=n(20354),a=n(71553),i=n(20768),c=n(31949);function o(e,t){var n,o=r.a.useBasicFetch(c.N.currentUser()),s=r.a.useBasicFetch(!!e&&i.b.interactiveMetadata(e)),l=r.a.useBasicFetch(!!(null===(n=s.data)||void 0===n?void 0:n.interactiveId)&&i.b.interactive(s.data.interactiveId)),u=!!o.data&&!!l.data&&!!t;return r.a.useBasicFetch(u&&a.I.interactiveResultSet(s.data.interactiveId,s.data.id,o.data,t))}},39157:(e,t,n)=>{n.d(t,{HI:()=>m,R6:()=>l,Rt:()=>f,UU:()=>d,Zs:()=>u,nq:()=>v});var r=n(75896),a=n(94892),i=n(28972),c=n(8246),o=n(83140),s=n(80845);function l(e,t,n){var i={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},c=(0,s.Q)(e).length;t.students.forEach((function(t){var o=Object.assign(Object.assign({},t),{summary:f(e,t)});o.summary.awaitingMarking?i.markingRequired.push(o):r.m.last(t.results).attempts.length===c?(i.completed.push(o),o.summary.percentCorrect>=(n.HIGH||a.i.HIGH)&&i.highScore.push(o),o.summary.percentCorrect<(n.MODERATE||a.i.MODERATE)&&i.lowScore.push(o)):i.notCompleted.push(o)}));var o=r.m.sortBy(i.lowScore,(function(e){return e.summary.percentCorrect})),l=r.m.sortBy(i.highScore,(function(e){return-e.summary.percentCorrect}));return Object.assign(Object.assign({},i),{lowScore:o,highScore:l})}function u(e,t){return(0,s.Wn)(e).find((function(e){return e.id.toString()===t.toString()}))}function d(e){return"".concat(e.questionId,":").concat(e.resultId)}function m(e,t,n){var r=(0,s.j_)(t),a=(0,s.f6)(e,r);return(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=n[d(e)])||void 0===t?void 0:t.status)===c.N.Correct})))?c.N.Correct:(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=n[d(e)])||void 0===t?void 0:t.status)===c.N.Incorrect})))?c.N.Incorrect:void 0}function v(e,t){var n=t.students.length,r=0,a=0,c=0,l=0,u=0;return t.students.forEach((function(t){var n=(0,s.j_)(t);if(n){u+=t.results.length;var d=o.A.isInteractionCorrect(e,n);d===i.w.Correct&&r++,d===i.w.UnAnswered&&c++,d===i.w.AwaitingMarking&&l++,d!==i.w.UnAnswered&&a++}})),{percentCorrect:n>0?r/n:0,correct:r,answered:a,unanswered:c,awaitingMarking:l,attempts:u}}function f(e,t){var n=(0,s.j_)(t),r=(0,s.Q)(e),a=r.length,c=0,l=0;r.forEach((function(e){var t=o.A.isInteractionCorrect(e,n);t===i.w.Correct&&c++,t===i.w.AwaitingMarking&&l++}));var u=a>0?c/a:0,d=new Set(r.map((function(e){return e.id}))),m=n.attempts.filter((function(e){var t;return!!d.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)})).length;return{answered:n.attempts.length,attempts:t.results.length,unanswered:a-m,percentCorrect:u,correct:c,awaitingMarking:l}}},28972:(e,t,n)=>{var r;n.d(t,{w:()=>r}),function(e){e[e.Correct=0]="Correct",e[e.Incorrect=1]="Incorrect",e[e.AwaitingMarking=2]="AwaitingMarking",e[e.Answered=3]="Answered",e[e.UnAnswered=4]="UnAnswered",e[e.NotApplicable=5]="NotApplicable"}(r||(r={}))},8246:(e,t,n)=>{var r;n.d(t,{N:()=>r}),function(e){e[e.Incorrect=0]="Incorrect",e[e.Correct=1]="Correct",e[e.PendingReview=2]="PendingReview"}(r||(r={}))},83140:(e,t,n)=>{n.d(t,{A:()=>g});var r=n(28972),a=n(8246),i=n(40424);function c(e){return c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c(e)}function o(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=c(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=c(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==c(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(){return r.w.NotApplicable}function l(e,t){var n=e.actionableItems.filter((function(e){return e.isCorrect}));return n.every((function(e){return!t(e.id)}))?r.w.UnAnswered:n.every((function(e){var n;return e.name.trim().toLowerCase()===(null===(n=t(e.id))||void 0===n?void 0:n.trim().toLowerCase())}))?r.w.Correct:r.w.Incorrect}function u(e,t){return e.actionableItems.every((function(e){return!t(e.id)}))?r.w.UnAnswered:e.actionableItems.filter((function(e){return e.isCorrect})).every((function(e){var n,r=t(e.id);return(null==r?void 0:r.toString())===(null===(n=e.id)||void 0===n?void 0:n.toString())||r===e.name}))?r.w.Correct:r.w.Incorrect}function d(e,t){return function(n){var r=t.attempts.find((function(t){return t.id===e.id}));return null==r?void 0:r.answers.find((function(e){return e.id===n}))}}function m(e,t){var n=d(e,t);return u(e,(function(e){var t=n(e);return null==t?void 0:t.text}))}function v(e,t){return function(e,t){var n;return e.actionableItems.forEach((function(e){var i=t(e.id);n=i?i.status!==a.N.Correct?i.status!==a.N.Incorrect?r.w.AwaitingMarking:r.w.Incorrect:r.w.Correct:r.w.UnAnswered})),n}(e,d(e,t))}var f=o(o(o(o(o(o(o({},i.Z9.Annotation,s),i.Z9.Image,s),i.Z9.MissingWord,(function(e,t){var n=d(e,t);return l(e,(function(e){var t=n(e);return null==t?void 0:t.text}))})),i.Z9.MultipleChoice,m),i.Z9.ShortAnswer,v),i.Z9.TrueOrFalse,m),i.Z9.Illustration,v),g={notApplicable:s,awaitingMarking:function(){return r.w.AwaitingMarking},isMissingWordCorrect:l,isMultipleChoiceCorrect:u,isInteractionCorrect:function(e,t){return(0,f[e.typeId])(e,t)}}},80845:(e,t,n)=>{n.d(t,{Q:()=>l,Wn:()=>c,f6:()=>s,j_:()=>o});var r=n(75896),a=n(40424);function i(e){return e.typeId!==a.Z9.Annotation&&e.typeId!==a.Z9.Image}function c(e){return r.m.flatten(e.timepoints.map((function(e){return e.interactions})))}function o(e){return r.m.last(e.results)}function s(e,t){return r.m.findWhere(null==t?void 0:t.attempts,{id:e})}function l(e){return c(e).filter(i)}},22517:(e,t,n)=>{n.d(t,{Z:()=>r});const r={header:"hnMke",row:"ILLa_",fixedTable:"_fdpt",interactionHeaderCellOuter:"kjXYB",hasResults:"M4qgr",interactionHeaderCellInner:"cnFvB",resultsCellOuter:"bdzRb",correct:"xANR6",incorrect:"_44sb",awaitingMarking:"eQ9sh",unanswered:"xRUK8",highlightColumn:"f9Zqr",resultsCellInner:"LAFwi",highlightResultsRow:"TwwLO",resultsRow:"xZ5iP"}}}]);
|
|
2
|
-
//# sourceMappingURL=8095-
|
|
1
|
+
"use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[8095],{34079:(e,t,n)=>{n.d(t,{O:()=>l});var r=n(32735),a=n(23481),i=n(40782),c=n(36532),o=a.T.encloseNamespace("interactives.pendingIndicator");function s(e){var t="d-flex align-items-center h-100";return t+=e.showLabel?" justify-content-between":" justify-content-center",e.className&&(t+=" ".concat(e.className)),t}function l(e){var t=function(){return r.createElement("div",{className:s(e)},!!e.showLabel&&r.createElement("em",null,o("pending")),r.createElement(i.O,null))};return e.title?r.createElement(c.u,{title:e.title,spanHack:!0,spanHackClassName:e.tooltipClassName||"h-100 w-100 d-flex align-items-center"},r.createElement(t,null)):r.createElement(t,null)}},48258:(e,t,n)=>{n.d(t,{Ju:()=>O,bB:()=>L,l8:()=>_,R7:()=>j,lE:()=>B,Fx:()=>T});var r=n(32735),a=n(23481),i=n(75896),c=n(34079),o=n(26136),s=n(39157),l=n(40782),u=n(80845),d=n(9601),m=n(71151),v=n(93264),f=n(84120);const g={container:"Wf1bl",interaction:"Fpm49"};function w(e){return e.duration?r.createElement(r.Fragment,null,e.interactive.timepoints.map((function(t,n){if(!t.interactions.length)return r.createElement(r.Fragment,null);var a,i,c=(a=t,i=e.selectedInteraction,a.interactions.find((function(e){return e.id===i.id}))||a.interactions[0]),o=c.id===e.selectedInteraction.id,s=o?f.w.getTypeInfo(c.typeId).bgClassName:"bg-gray-500",l=t.visibleAt/1e3/e.duration*100;return r.createElement("div",{key:n,className:"".concat(g.container," text-center"),style:{left:"".concat(l,"%")}},r.createElement("div",{className:"".concat(g.interaction," ").concat(s)}),!!o&&r.createElement("div",null,v.T.ToDisplayDuration(t.visibleAt)))}))):r.createElement(r.Fragment,null)}var p=n(86572);var y=a.T.encloseNamespace("shared.interactionResultsSummary");function h(e){var t,n=r.useMemo((function(){return(0,s.nq)(e.interaction,e.results)}),[e.interaction,e.results]);return r.createElement("div",{className:"px-1 pt-1"},r.createElement("div",{className:"d-flex"},r.createElement(p.y,{interaction:e.interaction,iconClassName:"flex-shrink-0"})),r.createElement("div",{className:"my-4 ".concat("FCXQd")},r.createElement(w,{interactive:e.interactive,duration:(t=e.interactiveMetadata,t._parentClip?t._parentClip.endTime-t._parentClip.startTime:t._parentVideo.duration?t._parentVideo.duration/1e3:0),selectedInteraction:e.interaction})),r.createElement("div",{className:"row pt-1 pb-2"},r.createElement("div",{className:"col-6 pe-1"},r.createElement("div",{className:"bg-light rounded p-2 h-100"},!n.awaitingMarking&&r.createElement("div",{className:"d-flex align-items-center justify-content-between"},r.createElement("strong",null,y("correctlyAnswered")),r.createElement(l.O,{percentage:n.percentCorrect,layout:l.I.LabelOnly})),!!n.awaitingMarking&&r.createElement("div",{className:"d-flex align-items-center justify-content-center"},r.createElement("strong",null,r.createElement("em",null,y("pending")))))),r.createElement("div",{className:"col-6 ps-1"},r.createElement("div",{className:"bg-light rounded h-100 p-2 d-flex align-items-center justify-content-between"},r.createElement("strong",null,y("unanswered")),r.createElement("span",null,n.unanswered)))))}var E=r.forwardRef((function(e,t){var n=e.interaction,a=e.interactive,i=e.interactiveMetadata,c=e.results,o=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(r=Object.getOwnPropertySymbols(e);a<r.length;a++)t.indexOf(r[a])<0&&Object.prototype.propertyIsEnumerable.call(e,r[a])&&(n[r[a]]=e[r[a]])}return n}(e,["interaction","interactive","interactiveMetadata","results"]);return r.createElement("div",{className:"popover-lg"},r.createElement(m.Z,Object.assign({id:"interaction-results-summary-".concat(n.id),ref:t},o),r.createElement(m.Z.Body,null,r.createElement(h,{interaction:n,interactive:a,interactiveMetadata:i,results:c}))))})),b=n(22517);function C(e){var t;return r.createElement(d.Z,{trigger:(null===(t=e.results.students)||void 0===t?void 0:t.length)?"click":null,placement:"bottom",overlay:r.createElement(E,{interaction:e.interaction,interactive:e.interactive,interactiveMetadata:e.interactiveMetadata,results:e.results}),rootClose:!0},r.createElement("div",{className:"text-center h-100\n d-flex align-items-center justify-content-center\n ".concat(b.Z.interactionHeaderCellInner),onMouseEnter:e.onMouseEnter,onMouseLeave:e.onMouseLeave},r.createElement("div",{className:"p-1 position-relative"},e.interactionNumber)))}var I=n(83914),N=n(28972),k=n(83140),M=n(35223);function A(e){var t="".concat(b.Z.resultsCellInner," h-100 position-relative");return e===N.w.Correct&&(t+=" ".concat(b.Z.correct)),e===N.w.Incorrect&&(t+=" ".concat(b.Z.incorrect," text-danger")),e===N.w.AwaitingMarking&&(t+=" ".concat(b.Z.awaitingMarking)),e===N.w.UnAnswered&&(t+=" ".concat(b.Z.unanswered," text-warning")),t}function S(e){var t=k.A.isInteractionCorrect(e.interaction,(0,u.j_)(e.studentResults)),n=function(e){return e===N.w.Correct?M.vn.Check:e===N.w.Incorrect?M.vn.Close:e===N.w.UnAnswered?M.vn.Minus:void 0}(t);return r.createElement("div",{className:A(t)},!!n&&r.createElement(I.x,{svgName:n}),t===N.w.AwaitingMarking&&r.createElement(c.O,null))}var R=a.T.encloseNamespace("shared.studentResultsTable"),O=60;function x(e){var t;return r.createElement("div",{className:"d-flex align-items-center p-2 h-100 ".concat(null!==(t=e.className)&&void 0!==t?t:"")},e.children)}function Z(e){return r.createElement(x,{className:e.column.isSorted&&"fw-bold"},R(e.phraseKey))}function j(e,t){var n,a=!!(null===(n=e.students)||void 0===n?void 0:n.length);return r.useMemo((function(){return[{Header:function(e){var t=e.column;return r.createElement(Z,{column:t,phraseKey:"name"})},accessor:"user",Cell:function(e){var n=e.value;return r.createElement(x,null,r.createElement("span",{className:"text-truncate"},(0,o.B)(n,t)))},disableSortBy:!a},{Header:function(e){var t=e.column;return r.createElement(Z,{column:t,phraseKey:"unanswered"})},accessor:"summary.unanswered",sortType:"basic",sortDescFirst:!0,disableSortBy:!a,Cell:function(e){var t=e.value;return r.createElement(x,null,t)}},{Header:function(e){var t=e.column;return r.createElement(Z,{column:t,phraseKey:"score"})},accessor:"summary",id:"score",Cell:function(e){var t=e.value;return t.awaitingMarking?r.createElement(x,null,r.createElement(c.O,{title:R("markingRequired"),className:"flex-grow-1",showLabel:!0})):r.createElement(x,null,"".concat(t.correct,"/").concat(t.answered+t.unanswered))},width:125,sortDescFirst:!0,disableSortBy:!a},{Header:function(e){var t=e.column;return r.createElement(Z,{column:t,phraseKey:"percentage"})},accessor:"summary",id:"percentage",Cell:function(e){var t=e.value;return t.awaitingMarking?r.createElement(x,null,r.createElement(c.O,{title:R("markingRequired"),className:"flex-grow-1",showLabel:!0})):r.createElement(x,null,r.createElement(l.O,{percentage:t.percentCorrect,layout:l.I.LabelBefore,className:"flex-grow-1"}))},width:125,sortDescFirst:!0,disableSortBy:!a}]}),[t,a])}function B(e,t,n,a,i){return r.useMemo((function(){return(0,u.Q)(e).map((function(i,c){return{Header:function(){return r.createElement(C,{interaction:i,results:n,interactive:e,interactiveMetadata:t,interactionNumber:c+1,onMouseEnter:function(){return a(c)},onMouseLeave:function(){return a(null)}})},accessor:"results",id:i.id,disableSortBy:!0,width:O,Cell:function(e){var t=e.row.original;return r.createElement(S,{interaction:i,studentResults:t})}}}))}),[i])}function T(e,t,n,a,c){return r.useMemo((function(){var n=[];if(t.students.forEach((function(t){n.push(Object.assign(Object.assign({},t),{summary:(0,s.Rt)(e,t)}))})),"user"===(null==c?void 0:c.id)){var r=i.m.sortBy(n,(function(e){return(0,o.B)(e.user,a)}));return c.desc?r.reverse():r}if("summary.unanswered"===(null==c?void 0:c.id)){var l=i.m.sortBy(n,(function(e){return e.summary.unanswered}));return c.desc?l.reverse():l}if("score"===(null==c?void 0:c.id)||"percentage"===(null==c?void 0:c.id)){var u=i.m.sortBy(n,(function(e){return e.summary.awaitingMarking?-1:e.summary.percentCorrect}));return c.desc?u.reverse():u}return n}),[n,c,a])}function L(e,t){if(e){var n=e.querySelectorAll(".".concat(b.Z.resultsRow));null==n||n.forEach((function(e){e.childNodes.forEach((function(e,n){e.classList.remove(b.Z.highlightColumn),n===t&&e.classList.add(b.Z.highlightColumn)}))}))}}function _(e,t){if(e){var n=e.querySelectorAll(".".concat(b.Z.resultsRow));null==n||n.forEach((function(e,n){e.classList.remove(b.Z.highlightResultsRow),n===t&&e.classList.add(b.Z.highlightResultsRow)}))}}},71553:(e,t,n)=>{n.d(t,{I:()=>c});var r=n(99940),a=n(62875);function i(e,t){return{currentUserId:e.id,currentCustomerId:e.customerId,dateRange:{start:t.start,end:t.end},userIds:t.userId,classroomsAndGroups:t.groupId}}var c={interactiveResultSet:function(e,t,n,c,o,s,l){return{url:"/api/domain/v2/analytics/interactives/".concat(e,"/metadata/").concat(t),key:(0,a.H)("interactive:result:set:".concat(e,":").concat(t),c),data:i(n,c),type:r.k.POST,normalize:!1,success:o,error:s,always:l}},mark:function(e,t,n,a,i,c,o){return{url:"/api/domain/v1/analytics/answers/".concat(n),key:"mark:answer:".concat(n,":").concat(a.resultId),type:r.k.PUT,data:a,normalize:!1,invalidationKeys:"interactive:result:set:".concat(e,":").concat(t),success:i,error:c,always:o}},pendingReviews:function(e){return{url:"/api/domain/v1/analytics/interactives/pending-reviews/summary",key:"interactives:pending:reviews",type:r.k.POST,data:e}},interactiveResultsReport:function(e){return{url:"{gateway}/v2/analytics/interactives/report",key:"interactive:results:report",data:e,type:r.k.POST,normalize:!1}}}},41196:(e,t,n)=>{n.d(t,{W:()=>o});var r=n(20354),a=n(71553),i=n(20768),c=n(31949);function o(e,t){var n,o=r.a.useBasicFetch(c.N.currentUser()),s=r.a.useBasicFetch(!!e&&i.b.interactiveMetadata(e)),l=r.a.useBasicFetch(!!(null===(n=s.data)||void 0===n?void 0:n.interactiveId)&&i.b.interactive(s.data.interactiveId)),u=!!o.data&&!!l.data&&!!t;return r.a.useBasicFetch(u&&a.I.interactiveResultSet(s.data.interactiveId,s.data.id,o.data,t))}},39157:(e,t,n)=>{n.d(t,{HI:()=>m,R6:()=>l,Rt:()=>f,UU:()=>d,Zs:()=>u,nq:()=>v});var r=n(75896),a=n(94892),i=n(28972),c=n(8246),o=n(83140),s=n(80845);function l(e,t,n){var i={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},c=(0,s.Q)(e).length;t.students.forEach((function(t){var o=Object.assign(Object.assign({},t),{summary:f(e,t)});o.summary.awaitingMarking?i.markingRequired.push(o):r.m.last(t.results).attempts.length===c?(i.completed.push(o),o.summary.percentCorrect>=((null==n?void 0:n.HIGH)||a.i.HIGH)&&i.highScore.push(o),o.summary.percentCorrect<((null==n?void 0:n.MODERATE)||a.i.MODERATE)&&i.lowScore.push(o)):i.notCompleted.push(o)}));var o=r.m.sortBy(i.lowScore,(function(e){return e.summary.percentCorrect})),l=r.m.sortBy(i.highScore,(function(e){return-e.summary.percentCorrect}));return Object.assign(Object.assign({},i),{lowScore:o,highScore:l})}function u(e,t){return(0,s.Wn)(e).find((function(e){return e.id.toString()===t.toString()}))}function d(e){return"".concat(e.questionId,":").concat(e.resultId)}function m(e,t,n){var r=(0,s.j_)(t),a=(0,s.f6)(e,r);return(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=n[d(e)])||void 0===t?void 0:t.status)===c.N.Correct})))?c.N.Correct:(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=n[d(e)])||void 0===t?void 0:t.status)===c.N.Incorrect})))?c.N.Incorrect:void 0}function v(e,t){var n=t.students.length,r=0,a=0,c=0,l=0,u=0;return t.students.forEach((function(t){var n=(0,s.j_)(t);if(n){u+=t.results.length;var d=o.A.isInteractionCorrect(e,n);d===i.w.Correct&&r++,d===i.w.UnAnswered&&c++,d===i.w.AwaitingMarking&&l++,d!==i.w.UnAnswered&&a++}})),{percentCorrect:n>0?r/n:0,correct:r,answered:a,unanswered:c,awaitingMarking:l,attempts:u}}function f(e,t){var n=(0,s.j_)(t),r=(0,s.Q)(e),a=r.length,c=0,l=0;r.forEach((function(e){var t=o.A.isInteractionCorrect(e,n);t===i.w.Correct&&c++,t===i.w.AwaitingMarking&&l++}));var u=a>0?c/a:0,d=new Set(r.map((function(e){return e.id}))),m=n.attempts.filter((function(e){var t;return!!d.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)})).length;return{answered:n.attempts.length,attempts:t.results.length,unanswered:a-m,percentCorrect:u,correct:c,awaitingMarking:l}}},28972:(e,t,n)=>{var r;n.d(t,{w:()=>r}),function(e){e[e.Correct=0]="Correct",e[e.Incorrect=1]="Incorrect",e[e.AwaitingMarking=2]="AwaitingMarking",e[e.Answered=3]="Answered",e[e.UnAnswered=4]="UnAnswered",e[e.NotApplicable=5]="NotApplicable"}(r||(r={}))},8246:(e,t,n)=>{var r;n.d(t,{N:()=>r}),function(e){e[e.Incorrect=0]="Incorrect",e[e.Correct=1]="Correct",e[e.PendingReview=2]="PendingReview"}(r||(r={}))},83140:(e,t,n)=>{n.d(t,{A:()=>g});var r=n(28972),a=n(8246),i=n(40424);function c(e){return c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},c(e)}function o(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=c(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,"string");if("object"!=c(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==c(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(){return r.w.NotApplicable}function l(e,t){var n=e.actionableItems.filter((function(e){return e.isCorrect}));return n.every((function(e){return!t(e.id)}))?r.w.UnAnswered:n.every((function(e){var n;return e.name.trim().toLowerCase()===(null===(n=t(e.id))||void 0===n?void 0:n.trim().toLowerCase())}))?r.w.Correct:r.w.Incorrect}function u(e,t){return e.actionableItems.every((function(e){return!t(e.id)}))?r.w.UnAnswered:e.actionableItems.filter((function(e){return e.isCorrect})).every((function(e){var n,r=t(e.id);return(null==r?void 0:r.toString())===(null===(n=e.id)||void 0===n?void 0:n.toString())||r===e.name}))?r.w.Correct:r.w.Incorrect}function d(e,t){return function(n){var r=t.attempts.find((function(t){return t.id===e.id}));return null==r?void 0:r.answers.find((function(e){return e.id===n}))}}function m(e,t){var n=d(e,t);return u(e,(function(e){var t=n(e);return null==t?void 0:t.text}))}function v(e,t){return function(e,t){var n;return e.actionableItems.forEach((function(e){var i=t(e.id);n=i?i.status!==a.N.Correct?i.status!==a.N.Incorrect?r.w.AwaitingMarking:r.w.Incorrect:r.w.Correct:r.w.UnAnswered})),n}(e,d(e,t))}var f=o(o(o(o(o(o(o({},i.Z9.Annotation,s),i.Z9.Image,s),i.Z9.MissingWord,(function(e,t){var n=d(e,t);return l(e,(function(e){var t=n(e);return null==t?void 0:t.text}))})),i.Z9.MultipleChoice,m),i.Z9.ShortAnswer,v),i.Z9.TrueOrFalse,m),i.Z9.Illustration,v),g={notApplicable:s,awaitingMarking:function(){return r.w.AwaitingMarking},isMissingWordCorrect:l,isMultipleChoiceCorrect:u,isInteractionCorrect:function(e,t){return(0,f[e.typeId])(e,t)}}},80845:(e,t,n)=>{n.d(t,{Q:()=>l,Wn:()=>c,f6:()=>s,j_:()=>o});var r=n(75896),a=n(40424);function i(e){return e.typeId!==a.Z9.Annotation&&e.typeId!==a.Z9.Image}function c(e){return r.m.flatten(e.timepoints.map((function(e){return e.interactions})))}function o(e){return r.m.last(e.results)}function s(e,t){return r.m.findWhere(null==t?void 0:t.attempts,{id:e})}function l(e){return c(e).filter(i)}},22517:(e,t,n)=>{n.d(t,{Z:()=>r});const r={header:"hnMke",row:"ILLa_",fixedTable:"_fdpt",interactionHeaderCellOuter:"kjXYB",hasResults:"M4qgr",interactionHeaderCellInner:"cnFvB",resultsCellOuter:"bdzRb",correct:"xANR6",incorrect:"_44sb",awaitingMarking:"eQ9sh",unanswered:"xRUK8",highlightColumn:"f9Zqr",resultsCellInner:"LAFwi",highlightResultsRow:"TwwLO",resultsRow:"xZ5iP"}}}]);
|
|
2
|
+
//# sourceMappingURL=8095-7236697220-lite.chunk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scripts/8095-7236697220-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/pending-indicator/PendingIndicator.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/student-results/interactions-bar/interactions-bar.scss","file:///app/packages/libs/shared/src/apps/analytics/components/student-results/interactions-bar/InteractionsBar.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/student-results/interaction-results-summary/InteractionResultsSummary.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/student-results/interaction-results-summary/interaction-results-summary.scss","file:///app/packages/libs/shared/src/apps/analytics/components/student-results/student-results-table/InteractionHeaderCell.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/student-results/student-results-table/StudentResultCell.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/student-results/student-results-table/StudentResultsTableUtils.tsx","file:///app/packages/libs/shared/src/apps/analytics/flight-requests/InteractiveResultsRequests.ts","file:///app/packages/libs/shared/src/apps/analytics/hooks/UseFetchInteractiveResults.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/InteractiveUtils.ts","file:///app/packages/libs/shared/src/enums/InteractionCorrectness.ts","file:///app/packages/libs/shared/src/enums/InteractiveAnswerStatus.ts","file:///app/packages/libs/shared/src/utils/InteractiveCorrectnessHelper.ts","file:///app/packages/libs/shared/src/utils/InteractiveHelper.ts","file:///app/packages/libs/shared/src/apps/analytics/components/student-results/student-results-table/student-results-table.scss"],"sourcesContent":["import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { PercentageIndicator } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\n\nconst namespace = 'interactives.pendingIndicator';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getClassName(props: PendingIndicatorProps): string {\n let className = 'd-flex align-items-center h-100';\n\n className += props.showLabel ? ' justify-content-between' : ' justify-content-center';\n\n if (props.className)\n className += ` ${props.className}`;\n\n return className;\n}\n\ninterface PendingIndicatorProps {\n title?: string;\n className?: string;\n showLabel?: boolean;\n tooltipClassName?: string;\n}\n\nexport function PendingIndicator(props: PendingIndicatorProps): JSX.Element {\n const Indicator = () => (\n <div className={getClassName(props)}>\n {!!props.showLabel &&\n <em>{getPhrase('pending')}</em>\n }\n <PercentageIndicator />\n </div>\n );\n\n if (!props.title)\n return <Indicator />;\n\n return (\n <Tooltip title={props.title} spanHack spanHackClassName={props.tooltipClassName || 'h-100 w-100 d-flex align-items-center'}>\n <Indicator />\n </Tooltip>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"container\":\"Wf1bl\",\"interaction\":\"Fpm49\"};","import React from 'react';\n\nimport { Interaction, Interactive, Timepoint } from 'libs/shared/interfaces';\nimport { DurationHelper } from 'libs/shared/utils/DurationHelper';\nimport { InteractionTypeHelper } from 'libs/shared/utils/interaction-type-helper/InteractionTypeHelper';\n\nimport styles from './interactions-bar.scss';\n\nfunction getInteraction(timepoint: Timepoint, selectedInteraction: Interaction): Interaction {\n return timepoint.interactions.find(i => i.id === selectedInteraction.id) || timepoint.interactions[0];\n}\n\ninterface InteractionBarProps {\n interactive: Interactive;\n duration: number;\n selectedInteraction: Interaction;\n}\n\nexport function InteractionsBar(props: InteractionBarProps): React.ReactElement {\n if (!props.duration)\n return <></>;\n\n return (\n <>\n {props.interactive.timepoints.map((t, i) => {\n if (!t.interactions.length)\n return <></>;\n\n const interaction = getInteraction(t, props.selectedInteraction);\n const isSelected = interaction.id === props.selectedInteraction.id;\n\n const bgClassName = isSelected ? (InteractionTypeHelper.getTypeInfo(interaction.typeId)).bgClassName : 'bg-gray-500';\n\n const left = ((t.visibleAt / 1000) / props.duration) * 100;\n\n return (\n <div\n key={i}\n className={`${styles.container} text-center`}\n style={{ left: `${left}%` }}\n >\n <div className={`${styles.interaction} ${bgClassName}`} />\n {!!isSelected &&\n <div>\n {DurationHelper.ToDisplayDuration(t.visibleAt)}\n </div>\n }\n </div>\n );\n })}\n </>\n );\n}","import React from 'react';\nimport { Popover } from 'react-bootstrap';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InteractionsBar } from 'libs/shared/apps/analytics/components/student-results/interactions-bar/InteractionsBar';\nimport { getInteractionResultsSummary } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { PercentageIndicator, PercentageIndicatorLayout } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Interaction, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nimport styles from './interaction-results-summary.scss';\n\nconst namespace = 'shared.interactionResultsSummary';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getDuration(interactiveMetadata: InteractiveMetadata): number {\n if (interactiveMetadata._parentClip)\n return interactiveMetadata._parentClip.endTime - interactiveMetadata._parentClip.startTime;\n\n if (!interactiveMetadata._parentVideo.duration)\n return 0;\n\n return interactiveMetadata._parentVideo.duration / 1000;\n}\n\ninterface InteractionResultsSummaryProps {\n interaction: Interaction;\n interactive: Interactive;\n interactiveMetadata: InteractiveMetadata;\n results: InteractiveResultSet;\n}\n\nfunction InteractionResultsSummary(props: InteractionResultsSummaryProps): JSX.Element {\n const summary = React.useMemo(\n () => getInteractionResultsSummary(props.interaction, props.results),\n [ props.interaction, props.results ]\n );\n\n return (\n <div className='px-1 pt-1'>\n <div className='d-flex'>\n <InteractionLabel\n interaction={props.interaction}\n iconClassName='flex-shrink-0'\n />\n </div>\n <div className={`my-4 ${styles.bar}`}>\n <InteractionsBar\n interactive={props.interactive}\n duration={getDuration(props.interactiveMetadata)}\n selectedInteraction={props.interaction}\n />\n </div>\n <div className='row pt-1 pb-2'>\n <div className='col-6 pe-1'>\n <div className='bg-light rounded p-2 h-100'>\n {!summary.awaitingMarking &&\n <div className='d-flex align-items-center justify-content-between'>\n <strong>{getPhrase('correctlyAnswered')}</strong>\n <PercentageIndicator\n percentage={summary.percentCorrect}\n layout={PercentageIndicatorLayout.LabelOnly}\n />\n </div>\n }\n {!!summary.awaitingMarking &&\n <div className='d-flex align-items-center justify-content-center'>\n <strong>\n <em>{getPhrase('pending')}</em>\n </strong>\n </div>\n }\n </div>\n </div>\n <div className='col-6 ps-1'>\n <div className='bg-light rounded h-100 p-2 d-flex align-items-center justify-content-between'>\n <strong>{getPhrase('unanswered')}</strong>\n <span>{summary.unanswered}</span>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nconst InteractionResultsSummaryPopover = React.forwardRef((\n { interaction, interactive, interactiveMetadata, results, ...popoverProps }: InteractionResultsSummaryProps,\n ref: React.MutableRefObject<HTMLElement>\n) => {\n return (\n <div className='popover-lg'>\n <Popover\n id={`interaction-results-summary-${interaction.id}`}\n ref={ref as any}\n {...popoverProps}\n >\n <Popover.Body>\n <InteractionResultsSummary\n interaction={interaction}\n interactive={interactive}\n interactiveMetadata={interactiveMetadata}\n results={results}\n />\n </Popover.Body>\n </Popover>\n </div>\n );\n});\n\nexport { InteractionResultsSummaryPopover as InteractionResultsSummary };","// extracted by mini-css-extract-plugin\nexport default {\"bar\":\"FCXQd\"};","import React from 'react';\nimport { OverlayTrigger } from 'react-bootstrap';\n\nimport { InteractionResultsSummary } from 'libs/shared/apps/analytics/components/student-results/interaction-results-summary/InteractionResultsSummary';\nimport { Interaction, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nimport styles from './student-results-table.scss';\n\ninterface InteractionHeaderCellProps {\n interaction: Interaction;\n results: InteractiveResultSet;\n interactionNumber: number;\n interactive: Interactive;\n interactiveMetadata: InteractiveMetadata;\n onMouseEnter?: () => void;\n onMouseLeave?: () => void;\n}\n\nexport function InteractionHeaderCell(props: InteractionHeaderCellProps): JSX.Element {\n return (\n <OverlayTrigger\n trigger={props.results.students?.length ? 'click' : null}\n placement='bottom'\n overlay={\n <InteractionResultsSummary\n interaction={props.interaction}\n interactive={props.interactive}\n interactiveMetadata={props.interactiveMetadata}\n results={props.results}\n />\n }\n rootClose\n >\n <div\n className={\n `text-center h-100\n d-flex align-items-center justify-content-center\n ${styles.interactionHeaderCellInner}`\n }\n onMouseEnter={props.onMouseEnter}\n onMouseLeave={props.onMouseLeave}\n >\n <div className='p-1 position-relative'>\n {props.interactionNumber}\n </div>\n </div>\n </OverlayTrigger>\n );\n}","import React from 'react';\n\nimport { PendingIndicator } from 'libs/shared/apps/analytics/components/pending-indicator/PendingIndicator';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { Interaction, StudentResults } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { getStudentResult } from 'libs/shared/utils/InteractiveHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './student-results-table.scss';\n\nfunction getSvgName(correctness: InteractionCorrectness): string {\n if (correctness === InteractionCorrectness.Correct)\n return cvSvgLibrary.Check;\n\n if (correctness === InteractionCorrectness.Incorrect)\n return cvSvgLibrary.Close;\n\n if (correctness === InteractionCorrectness.UnAnswered)\n return cvSvgLibrary.Minus;\n\n return;\n}\n\nfunction getClassName(correctness: InteractionCorrectness): string {\n let className = `${styles.resultsCellInner} h-100 position-relative`;\n\n if (correctness === InteractionCorrectness.Correct)\n className += ` ${styles.correct}`;\n\n if (correctness === InteractionCorrectness.Incorrect)\n className += ` ${styles.incorrect} text-danger`;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n className += ` ${styles.awaitingMarking}`;\n\n if (correctness === InteractionCorrectness.UnAnswered)\n className += ` ${styles.unanswered} text-warning`;\n\n return className;\n}\n\ninterface StudentResultCellProps {\n interaction: Interaction;\n studentResults: StudentResults;\n}\n\nexport function StudentResultCell(props: StudentResultCellProps): JSX.Element {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(\n props.interaction,\n getStudentResult(props.studentResults)\n );\n\n const svgName = getSvgName(correctness);\n\n return (\n <div className={getClassName(correctness)}>\n {!!svgName && <SvgContainer svgName={svgName} />}\n {correctness === InteractionCorrectness.AwaitingMarking &&\n <PendingIndicator />\n }\n </div>\n );\n}","import React from 'react';\nimport { CellProps, Column, ColumnInstance, SortingRule } from 'react-table';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { PendingIndicator } from 'libs/shared/apps/analytics/components/pending-indicator/PendingIndicator';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { anonymiseUserName } from 'libs/shared/apps/analytics/utils/AnonymiseUserUtils';\nimport { getStudentResultsSummary } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { PercentageIndicator, PercentageIndicatorLayout } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getInteractions } from 'libs/shared/utils/InteractiveHelper';\n\nimport { InteractionHeaderCell } from './InteractionHeaderCell';\nimport { StudentResultCell } from './StudentResultCell';\n\nimport styles from './student-results-table.scss';\n\nconst namespace = 'shared.studentResultsTable';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport const RESULTS_COL_WIDTH = 60;\n\ninterface CellWrapperProps {\n className?: string;\n}\n\nfunction CellWrapper(props: React.PropsWithChildren<CellWrapperProps>): JSX.Element {\n return (\n <div className={`d-flex align-items-center p-2 h-100 ${props.className ?? ''}`}>\n {props.children}\n </div>\n );\n}\n\ninterface HeaderCellProps {\n column: ColumnInstance<StudentResultsWithSummary>;\n phraseKey: string;\n}\n\nfunction HeaderCell(props: HeaderCellProps): JSX.Element {\n return (\n <CellWrapper className={props.column.isSorted && 'fw-bold'}>\n {getPhrase(props.phraseKey)}\n </CellWrapper>\n );\n}\n\nexport function useGetFixedColumns(\n results: InteractiveResultSet,\n anonymiseUsers: boolean\n): Column<StudentResultsWithSummary>[] {\n const hasResults = !!results.students?.length;\n\n return React.useMemo(() => {\n const cols: Column<StudentResultsWithSummary>[] = [\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='name' />,\n accessor: 'user',\n Cell: ({ value }) => (\n <CellWrapper>\n <span className='text-truncate'>{anonymiseUserName(value, anonymiseUsers)}</span>\n </CellWrapper>\n ),\n disableSortBy: !hasResults\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='unanswered' />,\n accessor: 'summary.unanswered' as keyof StudentResultsWithSummary,\n sortType: 'basic', // Default is 'alphanumeric' which would treat the numbers as strings\n sortDescFirst: true,\n disableSortBy: !hasResults,\n Cell: ({ value }: CellProps<StudentResultsWithSummary, any>) => <CellWrapper>{value}</CellWrapper>\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='score' />,\n accessor: 'summary',\n id: 'score',\n Cell: ({ value }) => {\n if (value.awaitingMarking) {\n return (\n <CellWrapper>\n <PendingIndicator\n title={getPhrase('markingRequired')}\n className='flex-grow-1'\n showLabel\n />\n </CellWrapper>\n );\n }\n\n return (\n <CellWrapper>\n {`${value.correct}/${value.answered + value.unanswered}`}\n </CellWrapper>\n );\n },\n width: 125,\n sortDescFirst: true,\n disableSortBy: !hasResults\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='percentage' />,\n accessor: 'summary',\n id: 'percentage',\n Cell: ({ value }) => {\n if (value.awaitingMarking) {\n return (\n <CellWrapper>\n <PendingIndicator\n title={getPhrase('markingRequired')}\n className='flex-grow-1'\n showLabel\n />\n </CellWrapper>\n );\n }\n\n return (\n <CellWrapper>\n <PercentageIndicator\n percentage={value.percentCorrect}\n layout={PercentageIndicatorLayout.LabelBefore}\n className='flex-grow-1'\n />\n </CellWrapper>\n );\n },\n width: 125,\n sortDescFirst: true,\n disableSortBy: !hasResults\n }\n ];\n\n return cols;\n }, [ anonymiseUsers, hasResults ]);\n}\n\n/**\n * Returns memoized table columns. To trigger a recalculation, toggle the value of `refreshData`.\n */\nexport function useGetResultColumns(\n interactive: Interactive,\n interactiveMetadata: InteractiveMetadata,\n results: InteractiveResultSet,\n onColumnHover: (index?: number) => void,\n refreshData: boolean\n): Column<StudentResultsWithSummary>[] {\n return React.useMemo(() => {\n const interactions = getInteractions(interactive);\n\n return interactions.map((interaction, index) => {\n const col: Column<StudentResultsWithSummary> = {\n Header: () => {\n return (\n <InteractionHeaderCell\n interaction={interaction}\n results={results}\n interactive={interactive}\n interactiveMetadata={interactiveMetadata}\n interactionNumber={index + 1}\n onMouseEnter={() => onColumnHover(index)}\n onMouseLeave={() => onColumnHover(null)}\n />\n );\n },\n accessor: 'results',\n /**\n * `onSelectStudentResponse` in `StudentResultsTable` expects the column id to the interaction id\n */\n id: interaction.id,\n disableSortBy: true,\n width: RESULTS_COL_WIDTH,\n Cell: ({ row: { original: studentResults } }) => (\n <StudentResultCell interaction={interaction} studentResults={studentResults} />\n )\n };\n return col;\n });\n }, [refreshData]);\n}\n\n/**\n * Returns memoized table data. To trigger a recalculation, toggle the value of `refreshData`.\n */\nexport function useGetResultsTableData(\n interactive: Interactive,\n results: InteractiveResultSet,\n refreshData: boolean,\n anonymiseUsers: boolean,\n sortBy?: SortingRule<StudentResultsWithSummary>\n): StudentResultsWithSummary[] {\n return React.useMemo(() => {\n const students: StudentResultsWithSummary[] = [];\n\n results.students.forEach(s => {\n students.push(({ ...s, summary: getStudentResultsSummary(interactive, s) }));\n });\n\n if (sortBy?.id === 'user') {\n const sorted = ArrayHelper.sortBy(students, student => anonymiseUserName(student.user, anonymiseUsers));\n\n return sortBy.desc ? sorted.reverse() : sorted;\n }\n\n if (sortBy?.id === 'summary.unanswered') {\n const sorted = ArrayHelper.sortBy(students, student => student.summary.unanswered);\n\n return sortBy.desc ? sorted.reverse() : sorted;\n }\n\n if (sortBy?.id === 'score' || sortBy?.id === 'percentage') {\n const sorted = ArrayHelper.sortBy(students, student => {\n if (student.summary.awaitingMarking)\n return -1;\n\n return student.summary.percentCorrect;\n });\n\n return sortBy.desc ? sorted.reverse() : sorted;\n }\n\n return students;\n }, [ refreshData, sortBy, anonymiseUsers ]);\n}\n\nexport function highlightColumns(tableEl: HTMLElement, highlightIndex?: number): void {\n if (!tableEl)\n return;\n\n const rows = tableEl.querySelectorAll(`.${styles.resultsRow}`);\n\n rows?.forEach(row => {\n row.childNodes.forEach((col: HTMLElement, colIdx: number) => {\n col.classList.remove(styles.highlightColumn);\n\n if (colIdx === highlightIndex)\n col.classList.add(styles.highlightColumn);\n });\n });\n}\n\nexport function highlightRows(tableEl: HTMLElement, highlightIndex?: number): void {\n if (!tableEl)\n return;\n\n const rows = tableEl.querySelectorAll(`.${styles.resultsRow}`);\n\n rows?.forEach((row, rowIdx) => {\n row.classList.remove(styles.highlightResultsRow);\n\n if (rowIdx === highlightIndex)\n row.classList.add(styles.highlightResultsRow);\n });\n}","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Flight } from 'libs/common/react/index';\n\nimport { MarkInteractiveAnswer } from 'libs/shared/apps/analytics/interfaces/MarkInteractiveAnswer';\nimport { InteractiveResultsReport } from 'libs/shared/apps/analytics/interfaces/requests/InteractiveResultsReport';\nimport { InteractivesPendingReviewsRequest } from 'libs/shared/apps/analytics/interfaces/requests/InteractivesPendingReviewsRequest';\nimport { AnalyticsRequestFilter, CurrentUser, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getAnalyticsRequestKey } from 'libs/shared/utils/AnalyticsRequestUtils';\n\ninterface InteractiveResultFilters {\n currentUserId: string;\n currentCustomerId: string;\n dateRange?: { start: string, end: string }\n userIds?: string | string[];\n classroomsAndGroups?: string | string[];\n}\n\nfunction getInteractiveResultFilters(\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter\n): InteractiveResultFilters {\n return {\n currentUserId: currentUser.id,\n currentCustomerId: currentUser.customerId,\n dateRange: { start: filter.start, end: filter.end },\n userIds: filter.userId,\n classroomsAndGroups: filter.groupId\n };\n}\n\nexport const InteractiveResultsRequests = {\n /** \n * This endpoint returns data with a lot of duplicated ids,\n * e.g. student answers to the same question will have the same id.\n * Because of that, we don't normalize.\n */\n interactiveResultSet(\n interactiveId: string,\n interactiveMetadataId: string,\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter,\n success?: (data: InteractiveResultSet) => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v2/analytics/interactives/${interactiveId}/metadata/${interactiveMetadataId}`,\n key: getAnalyticsRequestKey(`interactive:result:set:${interactiveId}:${interactiveMetadataId}`, filter),\n data: getInteractiveResultFilters(currentUser, filter),\n type: HttpVerbs.POST,\n normalize: false,\n success,\n error,\n always\n };\n },\n \n /**\n * As the response from `interactiveResultSet` isn't normalised, we need to invalidate the cache\n * to update the results data.\n */\n mark(\n interactiveId: string,\n interactiveMetadataId: string,\n answerId: string,\n data: MarkInteractiveAnswer,\n success?: () => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v1/analytics/answers/${answerId}`,\n key: `mark:answer:${answerId}:${data.resultId}`,\n type: HttpVerbs.PUT,\n data,\n normalize: false,\n invalidationKeys: `interactive:result:set:${interactiveId}:${interactiveMetadataId}`,\n success,\n error,\n always\n };\n },\n\n pendingReviews(data: InteractivesPendingReviewsRequest): Flight.Request {\n return {\n url: `/api/domain/v1/analytics/interactives/pending-reviews/summary`,\n key: `interactives:pending:reviews`,\n type: HttpVerbs.POST,\n data\n };\n },\n\n interactiveResultsReport(data: InteractiveResultsReport): Flight.Request {\n return {\n url: '{gateway}/v2/analytics/interactives/report',\n key: 'interactive:results:report',\n data,\n type: HttpVerbs.POST,\n normalize: false\n };\n }\n};","import { Flight } from 'libs/common/flight';\n\nimport { InteractiveResultsRequests } from 'libs/shared/apps/analytics/flight-requests/InteractiveResultsRequests';\nimport { InteractiveRequests } from 'libs/shared/flight-requests/InteractiveRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { AnalyticsRequestFilter, CurrentUser, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nexport function useFetchInteractiveResults(\n interactiveMetadataId: string,\n requestFilter: AnalyticsRequestFilter\n): Flight.Response<InteractiveResultSet> {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(!!interactiveMetadataId &&\n InteractiveRequests.interactiveMetadata(interactiveMetadataId));\n\n const interactive = Flight.useBasicFetch<Interactive>(!!interactiveMetadata.data?.interactiveId &&\n InteractiveRequests.interactive(interactiveMetadata.data.interactiveId));\n\n const shouldFetchResults = !!currentUser.data && !!interactive.data && (!!requestFilter);\n\n return Flight.useBasicFetch<InteractiveResultSet>(shouldFetchResults &&\n InteractiveResultsRequests.interactiveResultSet(\n interactiveMetadata.data.interactiveId,\n interactiveMetadata.data.id,\n currentUser.data,\n requestFilter\n ));\n}","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { Interactive, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { flattenInteractions, getInteractions, getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\ninterface StudentGroups {\n markingRequired: StudentResultsWithSummary[];\n lowScore: StudentResultsWithSummary[];\n highScore: StudentResultsWithSummary[];\n completed: StudentResultsWithSummary[];\n notCompleted: StudentResultsWithSummary[];\n}\n\nexport function groupStudents(\n interactive: Interactive,\n results: InteractiveResultSet,\n scoreThreshold?: ScoreThresholds\n): StudentGroups {\n const groups: StudentGroups = {\n markingRequired: [],\n lowScore: [],\n highScore: [],\n completed: [],\n notCompleted: []\n };\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n \n results.students.forEach(s => {\n const withSummary = {\n ...s,\n summary: getStudentResultsSummary(interactive, s)\n };\n \n if (withSummary.summary.awaitingMarking) {\n groups.markingRequired.push(withSummary);\n return;\n }\n\n if (ArrayHelper.last(s.results).attempts.length === numInteractions) {\n groups.completed.push(withSummary);\n } else {\n groups.notCompleted.push(withSummary);\n return;\n }\n \n if (withSummary.summary.percentCorrect >= (scoreThreshold?.HIGH || ScoreThresholdDefaults.HIGH))\n groups.highScore.push(withSummary);\n \n if (withSummary.summary.percentCorrect < (scoreThreshold?.MODERATE || ScoreThresholdDefaults.MODERATE))\n groups.lowScore.push(withSummary);\n });\n \n const sortedLowScore = ArrayHelper.sortBy(groups.lowScore, s => s.summary.percentCorrect);\n const sortedHighScore = ArrayHelper.sortBy(groups.highScore, s => -s.summary.percentCorrect);\n \n return {\n ...groups,\n lowScore: sortedLowScore,\n highScore: sortedHighScore\n };\n}\n\nexport function getInteractionById(interactive: Interactive, interactionId: string): Interaction {\n const flattenedInteractions = flattenInteractions(interactive);\n return flattenedInteractions.find(i => i.id.toString() === interactionId.toString());\n}\n\n/**\n * We need to use the question and result ids as a list of one student's responses\n * to multiple questions will all have the same result id and a list of multiple\n * students responses to one question will all have the same questionId.\n */\nexport function getMarkedAnswerId(answer: StudentAnswer): string {\n return `${answer.questionId}:${answer.resultId}`;\n}\n\nexport function getMarkedStatus(\n interactionId: string,\n studentResults: StudentResults,\n markedAnswers: MarkedAnswerHash\n): InteractiveAnswerStatus {\n const result = getStudentResult(studentResults);\n const studentResponse = getStudentAttempt(interactionId, result);\n\n const isMarkedCorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Correct;\n });\n\n if (isMarkedCorrect)\n return InteractiveAnswerStatus.Correct;\n\n const isMarkedIncorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Incorrect;\n });\n\n if (isMarkedIncorrect)\n return InteractiveAnswerStatus.Incorrect;\n}\n\nexport function getInteractionResultsSummary(\n interaction: Interaction,\n results: InteractiveResultSet\n): ResultsSummary {\n const numStudents = results.students.length;\n let numCorrect = 0;\n let answered = 0;\n let unanswered = 0;\n let awaitingMarking = 0;\n let attempts = 0;\n\n results.students.forEach(s => {\n const result = getStudentResult(s);\n\n if (!result)\n return;\n\n attempts = attempts + s.results.length;\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(interaction, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.UnAnswered)\n unanswered++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n\n if (correctness !== InteractionCorrectness.UnAnswered)\n answered++;\n });\n\n\n const percentCorrect = numStudents > 0\n ? numCorrect / numStudents\n : 0;\n\n return {\n percentCorrect,\n correct: numCorrect,\n answered,\n unanswered,\n awaitingMarking,\n attempts\n };\n}\n\nexport function getStudentResultsSummary(interactive: Interactive, studentResults: StudentResults): ResultsSummary {\n const result = getStudentResult(studentResults);\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n\n let numCorrect = 0;\n let awaitingMarking = 0;\n\n interactions.forEach(i => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(i, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n });\n\n const percentCorrect = numInteractions > 0 ? numCorrect / numInteractions : 0;\n\n /**\n * Our interactions list has images and annotations filtered out.\n * We built a map of valid questions, so that we can calculate the unswered accurately.\n * We're doing this because of a bug that caused annotations and images to record answers in the player.\n * - Sha\n */\n const interactionIds = new Set(interactions.map(i => i.id));\n const answeredInteractions = result.attempts.filter(a => !!interactionIds.has(a?.answers[0]?.questionId)).length;\n\n return {\n answered: result.attempts.length,\n attempts: studentResults.results.length,\n unanswered: numInteractions - answeredInteractions,\n percentCorrect,\n correct: numCorrect,\n awaitingMarking\n };\n}","export enum InteractionCorrectness {\n Correct,\n Incorrect,\n AwaitingMarking,\n \n Answered,\n UnAnswered,\n NotApplicable\n}","export enum InteractiveAnswerStatus {\n Incorrect = 0,\n Correct = 1,\n PendingReview = 2\n}","import { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, InteractionTypeId, InteractiveResult, StudentAnswer } from 'libs/shared/interfaces';\n\ntype GetStudentAnswerByActionableItemId = (id: string) => string;\n\nfunction notApplicable(): InteractionCorrectness {\n return InteractionCorrectness.NotApplicable;\n}\n\nfunction awaitingMarking(): InteractionCorrectness {\n return InteractionCorrectness.AwaitingMarking;\n}\n\nfunction isMissingWordCorrect(\n interaction: Interaction,\n getStudentAnswer: GetStudentAnswerByActionableItemId\n): InteractionCorrectness {\n const items = interaction.actionableItems.filter(a => a\n .isCorrect);\n\n if (items.every(a => !getStudentAnswer(a.id)))\n return InteractionCorrectness.UnAnswered;\n\n const correct = items.every(a => a.name.trim().toLowerCase() === getStudentAnswer(a.id)?.trim().toLowerCase());\n return correct ? InteractionCorrectness.Correct : InteractionCorrectness.Incorrect;\n}\n\nfunction isMultipleChoiceCorrect(\n interaction: Interaction,\n getStudentAnswer: GetStudentAnswerByActionableItemId\n): InteractionCorrectness {\n if (interaction.actionableItems.every(a => !getStudentAnswer(a.id)))\n return InteractionCorrectness.UnAnswered;\n \n const correctItems = interaction.actionableItems.filter(a => a.isCorrect);\n\n const correct = correctItems.every(a => {\n const studentAnswer = getStudentAnswer(a.id);\n\n /**\n * In the past we've only ever checked the answer name. But since we introduced the ability to have image interactions\n * with no question text, we've need to swap to saving the id. But past submissions still have the name\n * - Sha\n */\n return studentAnswer?.toString() === a.id?.toString() || studentAnswer === a.name;\n });\n return correct ? InteractionCorrectness.Correct : InteractionCorrectness.Incorrect;\n}\n\nfunction isMarkableAnswerMarkedCorrect(\n interaction: Interaction,\n getStudentAnswer: (id: string) => StudentAnswer\n): InteractionCorrectness {\n let correctness: InteractionCorrectness;\n\n // There should only be one actionableItem\n interaction.actionableItems.forEach(item => {\n const studentAnswer = getStudentAnswer(item.id);\n\n if (!studentAnswer) {\n correctness = InteractionCorrectness.UnAnswered;\n return;\n }\n\n if (studentAnswer.status === InteractiveAnswerStatus.Correct) {\n correctness = InteractionCorrectness.Correct;\n return;\n }\n\n if (studentAnswer.status === InteractiveAnswerStatus.Incorrect) {\n correctness = InteractionCorrectness.Incorrect;\n return;\n }\n\n correctness = InteractionCorrectness.AwaitingMarking;\n });\n\n return correctness;\n}\n\ntype IsCorrectFunction = (interaction: Interaction, result: InteractiveResult) => InteractionCorrectness;\n\nfunction getGetStudentAnswer(interaction: Interaction, result: InteractiveResult): (id: string) => StudentAnswer {\n return (id: string) => {\n const attempt = result.attempts.find(a => a.id === interaction.id);\n return attempt?.answers.find(s => s.id === id);\n };\n}\n\nfunction wrapIsMissingWordCorrect(interaction: Interaction, result: InteractiveResult): InteractionCorrectness {\n const getStudentAnswer = getGetStudentAnswer(interaction, result);\n\n return isMissingWordCorrect(interaction, (id: string) => {\n const answer = getStudentAnswer(id);\n return answer?.text;\n });\n}\n\nfunction wrapIsMultipleChoiceCorrect(interaction: Interaction, result: InteractiveResult): InteractionCorrectness {\n const getStudentAnswer = getGetStudentAnswer(interaction, result);\n\n return isMultipleChoiceCorrect(interaction, (id: string) => {\n const answer = getStudentAnswer(id);\n return answer?.text;\n });\n}\n\nfunction wrapIsMarkableAnswerMarkedCorrect(\n interaction: Interaction,\n result: InteractiveResult\n): InteractionCorrectness {\n const getStudentAnswer = getGetStudentAnswer(interaction, result);\n return isMarkableAnswerMarkedCorrect(interaction, getStudentAnswer);\n}\n\nconst IsCorrectLookup: {[typeId: number]: IsCorrectFunction} = {\n [InteractionTypeId.Annotation]: notApplicable,\n [InteractionTypeId.Image]: notApplicable,\n [InteractionTypeId.MissingWord]: wrapIsMissingWordCorrect,\n [InteractionTypeId.MultipleChoice]: wrapIsMultipleChoiceCorrect,\n [InteractionTypeId.ShortAnswer]: wrapIsMarkableAnswerMarkedCorrect,\n [InteractionTypeId.TrueOrFalse]: wrapIsMultipleChoiceCorrect,\n [InteractionTypeId.Illustration]: wrapIsMarkableAnswerMarkedCorrect\n};\n\nfunction isInteractionCorrect(interaction: Interaction, result: InteractiveResult): InteractionCorrectness {\n const isCorrectFn = IsCorrectLookup[interaction.typeId];\n\n return isCorrectFn(interaction, result);\n}\n\nexport const InteractiveCorrectnessHelper = {\n notApplicable,\n awaitingMarking,\n isMissingWordCorrect,\n isMultipleChoiceCorrect,\n isInteractionCorrect\n};\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport {\n Interaction,\n InteractionTypeId,\n Interactive,\n InteractiveResult,\n StudentAttempt,\n StudentResults\n} from 'libs/shared/interfaces';\n\nfunction interactionRequiresAnswer(interaction: Interaction): boolean {\n return interaction.typeId !== InteractionTypeId.Annotation && interaction.typeId !== InteractionTypeId.Image;\n}\n\nexport function flattenInteractions(interactive: Interactive): Interaction[] {\n return ArrayHelper.flatten(interactive.timepoints.map(i => i.interactions));\n}\n\n/**\n * Centralised logic for using the most recent student result.\n */\nexport function getStudentResult(studentResults: StudentResults): InteractiveResult {\n return ArrayHelper.last(studentResults.results);\n}\n\nexport function getStudentAttempt(interactionId: string, result: InteractiveResult): StudentAttempt {\n return ArrayHelper.findWhere(result?.attempts, { id: interactionId });\n}\n\n/**\n * Returns a flat list of interactions on an interactive and filters out\n * those that don't require an answer (annotations and images).\n */\nexport function getInteractions(interactive: Interactive): Interaction [] {\n return flattenInteractions(interactive).filter(interactionRequiresAnswer);\n}","// extracted by mini-css-extract-plugin\nexport default {\"header\":\"hnMke\",\"row\":\"ILLa_\",\"fixedTable\":\"_fdpt\",\"interactionHeaderCellOuter\":\"kjXYB\",\"hasResults\":\"M4qgr\",\"interactionHeaderCellInner\":\"cnFvB\",\"resultsCellOuter\":\"bdzRb\",\"correct\":\"xANR6\",\"incorrect\":\"_44sb\",\"awaitingMarking\":\"eQ9sh\",\"unanswered\":\"xRUK8\",\"highlightColumn\":\"f9Zqr\",\"resultsCellInner\":\"LAFwi\",\"highlightResultsRow\":\"TwwLO\",\"resultsRow\":\"xZ5iP\"};"],"names":["getPhrase","getClassName","props","className","showLabel","PendingIndicator","Indicator","title","spanHack","spanHackClassName","tooltipClassName","InteractionsBar","duration","interactive","timepoints","map","t","i","interactions","length","timepoint","selectedInteraction","interaction","find","id","isSelected","bgClassName","InteractionTypeHelper","typeId","left","visibleAt","key","style","DurationHelper","LanguageService","InteractionResultsSummary","interactiveMetadata","summary","results","InteractionLabel","iconClassName","_parentClip","endTime","startTime","_parentVideo","awaitingMarking","PercentageIndicator","percentage","percentCorrect","layout","unanswered","InteractionResultsSummaryPopover","ref","popoverProps","Popover","InteractionHeaderCell","OverlayTrigger","trigger","students","placement","overlay","rootClose","onMouseEnter","onMouseLeave","interactionNumber","correctness","InteractionCorrectness","StudentResultCell","InteractiveCorrectnessHelper","studentResults","svgName","getSvgName","SvgContainer","RESULTS_COL_WIDTH","CellWrapper","children","HeaderCell","column","isSorted","phraseKey","useGetFixedColumns","anonymiseUsers","hasResults","Header","accessor","Cell","value","disableSortBy","sortType","sortDescFirst","correct","answered","width","useGetResultColumns","onColumnHover","refreshData","index","row","original","useGetResultsTableData","sortBy","forEach","s","push","sorted","ArrayHelper","student","user","desc","reverse","highlightColumns","tableEl","highlightIndex","rows","querySelectorAll","childNodes","col","colIdx","classList","remove","add","highlightRows","rowIdx","getInteractiveResultFilters","currentUser","filter","currentUserId","currentCustomerId","customerId","dateRange","start","end","userIds","userId","classroomsAndGroups","groupId","InteractiveResultsRequests","interactiveResultSet","interactiveId","interactiveMetadataId","success","error","always","url","data","type","normalize","mark","answerId","resultId","invalidationKeys","pendingReviews","interactiveResultsReport","useFetchInteractiveResults","requestFilter","shouldFetchResults","I","groupStudents","scoreThreshold","groups","markingRequired","lowScore","highScore","completed","notCompleted","numInteractions","withSummary","getStudentResultsSummary","attempts","HIGH","MODERATE","sortedLowScore","sortedHighScore","getInteractionById","interactionId","toString","getMarkedAnswerId","answer","questionId","getMarkedStatus","markedAnswers","result","studentResponse","answers","every","a","status","getInteractionResultsSummary","numStudents","numCorrect","interactionIds","Set","answeredInteractions","has","InteractiveAnswerStatus","notApplicable","isMissingWordCorrect","getStudentAnswer","items","actionableItems","isCorrect","name","trim","toLowerCase","isMultipleChoiceCorrect","studentAnswer","getGetStudentAnswer","attempt","wrapIsMultipleChoiceCorrect","text","wrapIsMarkableAnswerMarkedCorrect","item","isMarkableAnswerMarkedCorrect","IsCorrectLookup","isInteractionCorrect","isCorrectFn","interactionRequiresAnswer","flattenInteractions","getStudentResult","getStudentAttempt","getInteractions"],"sourceRoot":""}
|