@clickview/lite 0.57.3-rc.0 → 0.58.0

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.
Files changed (23) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/scripts/{2564-98ba0d782a-lite.chunk.js → 2564-04ffede8c7-lite.chunk.js} +3 -3
  3. package/dist/scripts/{2564-98ba0d782a-lite.chunk.js.map → 2564-04ffede8c7-lite.chunk.js.map} +1 -1
  4. package/dist/scripts/2615-27b126b1ab-lite.chunk.js +3 -0
  5. package/dist/scripts/2615-27b126b1ab-lite.chunk.js.map +1 -0
  6. package/dist/scripts/{2978-b7bcc3eac4-lite.chunk.js → 2978-e4a60f90a5-lite.chunk.js} +2 -2
  7. package/dist/scripts/2978-e4a60f90a5-lite.chunk.js.map +1 -0
  8. package/dist/scripts/{8095-afb976fac0-lite.chunk.js → 8095-7236697220-lite.chunk.js} +2 -2
  9. package/dist/scripts/8095-7236697220-lite.chunk.js.map +1 -0
  10. package/dist/scripts/8849-7d50f76777-lite.chunk.js +2 -0
  11. package/dist/scripts/8849-7d50f76777-lite.chunk.js.map +1 -0
  12. package/dist/scripts/{bundle-b25c09d3e8.min.js → bundle-176a4f3a0a.min.js} +3 -3
  13. package/dist/scripts/{bundle-b25c09d3e8.min.js.map → bundle-176a4f3a0a.min.js.map} +1 -1
  14. package/package.json +1 -1
  15. package/dist/scripts/2615-e9b2938c18-lite.chunk.js +0 -3
  16. package/dist/scripts/2615-e9b2938c18-lite.chunk.js.map +0 -1
  17. package/dist/scripts/2978-b7bcc3eac4-lite.chunk.js.map +0 -1
  18. package/dist/scripts/8095-afb976fac0-lite.chunk.js.map +0 -1
  19. package/dist/scripts/8849-020bfd8cdd-lite.chunk.js +0 -2
  20. package/dist/scripts/8849-020bfd8cdd-lite.chunk.js.map +0 -1
  21. /package/dist/scripts/{2564-98ba0d782a-lite.chunk.js.LICENSE.txt → 2564-04ffede8c7-lite.chunk.js.LICENSE.txt} +0 -0
  22. /package/dist/scripts/{2615-e9b2938c18-lite.chunk.js.LICENSE.txt → 2615-27b126b1ab-lite.chunk.js.LICENSE.txt} +0 -0
  23. /package/dist/scripts/{bundle-b25c09d3e8.min.js.LICENSE.txt → bundle-176a4f3a0a.min.js.LICENSE.txt} +0 -0
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[8849],{53353:(e,t,n)=>{n.d(t,{c:()=>h,l:()=>f});var a=n(32735),r=n(232),s=n.n(r),i=n(8604),c=n(83345);const l={heatMap:"epapa",legend:"uhH4p"};function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=Array(t);n<t;n++)a[n]=e[n];return a}var u="shared.engagementHeatMap",m="#f1f1f1",d=s().scale(["#daf07d","#08bd1a"]),p=[0,.01,.25,.5,.75,1];function g(e,t){return e?d(e/t).hex():m}function v(e,t){for(var n=[],a=0;a<e.length;a++){var r=a>0&&e[a-1],s=e[a],i=a<e.length-1&&e[a+1];s===r&&s===i||n.push("".concat(g(s,t)," ").concat(100/e.length*a,"%"))}return"linear-gradient(to right, ".concat(n.join(","),")")}function f(){var e=Math.max.apply(Math,p),t=100/p.length;return a.createElement("div",{className:"d-flex justify-content-between w-100"},a.createElement(c.x,{namespace:u,phrase:"less"}),a.createElement("div",{className:"d-flex mx-1 flex-grow-1 ".concat(l.legend)},p.map((function(n,r){return a.createElement("div",{key:r,style:{width:"".concat(t,"%"),backgroundColor:g(n,e)}})}))),a.createElement(c.x,{namespace:u,phrase:"more"}))}function h(e){var t,n,r,s=(0,i.O)(e.engagement),c=null!==(t=e.max)&&void 0!==t?t:Math.max.apply(Math,function(e){if(Array.isArray(e))return o(e)}(r=s)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(r)||function(e,t){if(e){if("string"==typeof e)return o(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?o(e,t):void 0}}(r)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());return a.createElement("div",{className:"border rounded ".concat(l.heatMap," ").concat(null!==(n=e.className)&&void 0!==n?n:""),style:{background:v(s,c)}})}},25216:(e,t,n)=>{n.d(t,{L:()=>i});var a=n(32735),r=n(83914);const s={icon:"sAmpy",count:"faDs4"};function i(e){return a.createElement("section",{className:"d-flex flex-column border border-light rounded p-3 h-100"},a.createElement("div",{className:"d-flex align-items-center mb-2"},a.createElement("div",{className:"".concat(s.icon," ").concat(e.svgClassName," rounded-circle d-flex align-items-center justify-content-center")},a.createElement(r.x,{svgName:e.svgName})),a.createElement("div",{className:"d-flex flex-column ms-2"},a.createElement("h2",{className:"h6 mb-0"},e.title),e.subtitle&&a.createElement("p",{className:"text-secondary font-size-sm mb-0"},e.subtitle)),"number"==typeof e.count&&a.createElement("div",{className:"".concat(s.count," d-flex justify-content-center align-items-center bg-light rounded-circle ms-auto")},e.count)),e.children)}},69332:(e,t,n)=>{n.d(t,{x:()=>o});var a=n(32735),r=n(72306),s=n.n(r),i=n(70312),c=n.n(i);var l=function(e){return{title:{text:null},credits:{enabled:!1},yAxis:{title:{text:null},labels:{enabled:!1},gridLineWidth:0,min:0,tickAmount:1},xAxis:{title:{text:e,style:{color:"#313543",fontSize:"12px"}},labels:{style:{color:"#313543",fontSize:"12px"}},className:"nSTtI",lineWidth:0},legend:{enabled:!1},chart:{type:"column",backgroundColor:"transparent",height:"160px",spacingTop:20},plotOptions:{column:{dataLabels:{enabled:!1},enableMouseTracking:!1,minPointLength:8}}}};function o(e){return a.createElement(c(),{highcharts:s(),options:(t=e.chartData,n=l(e.label),Object.assign(Object.assign({},n),{xAxis:Object.assign(Object.assign({},n.xAxis),{categories:t.categories}),series:t.series}))});var t,n}},461:(e,t,n)=>{n.d(t,{y:()=>o});var a=n(32735),r=n(77640),s=n(36848),i=n(40782);const c={avatar:"uMuZt",image:"WdKiU"};var l=3;function o(e){return a.createElement(a.Fragment,null,e.students.length?a.createElement("ul",{className:"list-unstyled mb-2"},e.students.slice(0,l).map((function(t,n){return a.createElement("li",{key:n,className:"d-flex align-items-center mb-2"},a.createElement(r.t,{user:t,imageCdnUrl:e.imageCdnUrl,avatarClassName:c.avatar,detailsClassName:"ms-2",showDisplayName:!0,showSubText:!1,anonymiseUsers:e.anonymiseUsers}),a.createElement("div",{className:"d-flex align-items-center ms-auto"},a.createElement("span",{className:"me-1"},void 0===t.percentage?"- ":Math.round(100*t.percentage),"%"),a.createElement(i.O,{percentage:t.percentage})))}))):a.createElement("div",{className:"text-center"},a.createElement("img",{className:"".concat(c.image," mb-2"),src:e.imageUrl}),a.createElement("p",{className:"text-secondary mb-0",dangerouslySetInnerHTML:{__html:e.description}})),!!e.students.length&&a.createElement(s.F,{appLink:e.appLink,className:"text-info mt-auto"},e.appLinkText))}},42642:(e,t,n)=>{n.d(t,{i:()=>g});var a=n(32735),r=n(23481),s=n(75896),i=n(25216),c=n(69332),l=n(83345),o=n(35223);const u={font:"xTiKg",purpleChart:"OPcvi",grayChart:"HlWj7"};var m="shared.insightDevices",d=r.T.encloseNamespace(m);function p(e){switch(e){case"Android":case"Windows Phone":case"iOS":case"BlackBerry":return"Mobile";case"Linux":case"Unix":case"Macintosh":case"Windows":return"Computer"}}function g(e){var t,n,r=function(){var t,n={Phone:0,Computer:0};return(null===(t=e.osCount)||void 0===t?void 0:t.length)?e.osCount.reduce((function(e,t){if(!t.name)return e;var n=p(t.name);return e[n]=e[n]+t.count,e}),n):n}(),g=function(){var t;return(null===(t=e.osCount)||void 0===t?void 0:t.length)?e.osCount.reduce((function(t,n){return n.name&&n.count>t.count?n:s.m.first(e.osCount)})):null}(),v={categories:Object.keys(r),series:[{type:"column",borderRadius:4,dataLabels:{enabled:!0,style:{fontSize:"12px",fontWeight:"normal"},inside:!1,overflow:"allow",crop:!1,className:u.font},data:Object.keys(r).map((function(e){return{className:"".concat(0===r[e]?u.grayChart:u.purpleChart," ").concat(r[e]!==(null==g?void 0:g.count)?"opacity-25":""),y:r[e]}}))}]};return a.createElement(i.L,{title:d("title"),svgClassName:"bg-light-ultramarine text-ultramarine",svgName:o.vn.Monitor},a.createElement("p",{className:"mb-0"},(null===(t=e.osCount)||void 0===t?void 0:t.filter((function(e){return e.name})).length)?a.createElement(l.x,{namespace:m,phrase:"description",options:{device:null===(n=p(null==g?void 0:g.name))||void 0===n?void 0:n.toLowerCase()}}):a.createElement(l.x,{namespace:m,phrase:"notViewed"})),a.createElement("div",{className:"position-relative mt-auto"},a.createElement(c.x,{label:d("title"),chartData:v})))}},94652:(e,t,n)=>{n.d(t,{b:()=>p});var a=n(32735),r=n(23481),s=n(53353),i=n(25216),c=n(36848),l=n(83345),o=n(35223);const u={heatMap:"Rfr9N",heatMapTimepointIndicator:"s6JbA",heatMapTimepointIndicatorVisible:"mgjWX"};var m="shared.insightHeatmap",d=r.T.encloseNamespace(m);function p(e){var t=e.engagement.engagementRate>0?Math.round(100*e.engagement.engagementRate):null;return a.createElement(i.L,{title:d("title"),svgName:o.vn.Timer,svgClassName:"bg-light-green text-green"},a.createElement("div",{className:"mb-2"},a.createElement("p",{className:"mb-0"},t?a.createElement(l.x,{namespace:m,phrase:"everyoneWatched",options:{engagementRate:t}}):a.createElement(l.x,{namespace:m,phrase:"notWatched"})),t&&a.createElement(c.F,{appLink:e.heatmapAppLink,className:"text-info"},a.createElement(l.x,{namespace:m,phrase:"viewHeatmap"}))),a.createElement("div",{className:"mb-2"},a.createElement(s.c,{engagement:e.engagement,className:u.heatMap})),a.createElement("p",{className:"h3 text-center mb-2"},t||"--","%"),a.createElement("p",{className:"text-center mb-0 font-size-sm"},a.createElement(l.x,{namespace:m,phrase:"amountWatched"})))}},71553:(e,t,n)=>{n.d(t,{I:()=>i});var a=n(99940),r=n(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,n,i,c,l,o){return{url:"/api/domain/v2/analytics/interactives/".concat(e,"/metadata/").concat(t),key:(0,r.H)("interactive:result:set:".concat(e,":").concat(t),i),data:s(n,i),type:a.k.POST,normalize:!1,success:c,error:l,always:o}},mark:function(e,t,n,r,s,i,c){return{url:"/api/domain/v1/analytics/answers/".concat(n),key:"mark:answer:".concat(n,":").concat(r.resultId),type:a.k.PUT,data:r,normalize:!1,invalidationKeys:"interactive:result:set:".concat(e,":").concat(t),success:s,error:i,always:c}},pendingReviews:function(e){return{url:"/api/domain/v1/analytics/interactives/pending-reviews/summary",key:"interactives:pending:reviews",type:a.k.POST,data:e}},interactiveResultsReport:function(e){return{url:"{gateway}/v2/analytics/interactives/report",key:"interactive:results:report",data:e,type:a.k.POST,normalize:!1}}}},41196:(e,t,n)=>{n.d(t,{W:()=>c});var a=n(20354),r=n(71553),s=n(20768),i=n(31949);function c(e,t){var n,c=a.a.useBasicFetch(i.N.currentUser()),l=a.a.useBasicFetch(!!e&&s.b.interactiveMetadata(e)),o=a.a.useBasicFetch(!!(null===(n=l.data)||void 0===n?void 0:n.interactiveId)&&s.b.interactive(l.data.interactiveId)),u=!!c.data&&!!o.data&&!!t;return a.a.useBasicFetch(u&&r.I.interactiveResultSet(l.data.interactiveId,l.data.id,c.data,t))}},8604:(e,t,n)=>{function a(e){return new Array(Math.ceil(e.videoDuration)).fill(null).map((function(t,n){return e.heatMap[n]||0}))}n.d(t,{O:()=>a})},39157:(e,t,n)=>{n.d(t,{HI:()=>d,R6:()=>o,Rt:()=>g,UU:()=>m,Zs:()=>u,nq:()=>p});var a=n(75896),r=n(94892),s=n(28972),i=n(8246),c=n(83140),l=n(80845);function o(e,t,n){var s={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},i=(0,l.Q)(e).length;t.students.forEach((function(t){var c=Object.assign(Object.assign({},t),{summary:g(e,t)});c.summary.awaitingMarking?s.markingRequired.push(c):a.m.last(t.results).attempts.length===i?(s.completed.push(c),c.summary.percentCorrect>=((null==n?void 0:n.HIGH)||r.i.HIGH)&&s.highScore.push(c),c.summary.percentCorrect<((null==n?void 0:n.MODERATE)||r.i.MODERATE)&&s.lowScore.push(c)):s.notCompleted.push(c)}));var c=a.m.sortBy(s.lowScore,(function(e){return e.summary.percentCorrect})),o=a.m.sortBy(s.highScore,(function(e){return-e.summary.percentCorrect}));return Object.assign(Object.assign({},s),{lowScore:c,highScore:o})}function u(e,t){return(0,l.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,n){var a=(0,l.j_)(t),r=(0,l.f6)(e,a);return(null==r?void 0:r.answers.every((function(e){var t;return(null===(t=n[m(e)])||void 0===t?void 0:t.status)===i.N.Correct})))?i.N.Correct:(null==r?void 0:r.answers.every((function(e){var t;return(null===(t=n[m(e)])||void 0===t?void 0:t.status)===i.N.Incorrect})))?i.N.Incorrect:void 0}function p(e,t){var n=t.students.length,a=0,r=0,i=0,o=0,u=0;return t.students.forEach((function(t){var n=(0,l.j_)(t);if(n){u+=t.results.length;var m=c.A.isInteractionCorrect(e,n);m===s.w.Correct&&a++,m===s.w.UnAnswered&&i++,m===s.w.AwaitingMarking&&o++,m!==s.w.UnAnswered&&r++}})),{percentCorrect:n>0?a/n:0,correct:a,answered:r,unanswered:i,awaitingMarking:o,attempts:u}}function g(e,t){var n=(0,l.j_)(t),a=(0,l.Q)(e),r=a.length,i=0,o=0;a.forEach((function(e){var t=c.A.isInteractionCorrect(e,n);t===s.w.Correct&&i++,t===s.w.AwaitingMarking&&o++}));var u=r>0?i/r:0,m=new Set(a.map((function(e){return e.id}))),d=n.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:n.attempts.length,attempts:t.results.length,unanswered:r-d,percentCorrect:u,correct:i,awaitingMarking:o}}},77640:(e,t,n)=>{n.d(t,{t:()=>d});var a=n(32735),r=n(23481),s=n(26136),i=n(20789),c=n(76881),l=n(86613),o=n(64818),u=n(94831),m=r.T.encloseNamespace("shared.userRecipientItemMetadata");function d(e){var t;return a.createElement(a.Fragment,null,a.createElement("div",{className:"".concat(u.Z.avatarContainer," ").concat(e.avatarClassName," d-inline-block")},a.createElement(i.q,{imageUrl:null===(t=e.user.avatar)||void 0===t?void 0:t.url,imageCdnUrl:e.imageCdnUrl,initials:o.l.getInitials(e.user.name,e.user.surname)})),a.createElement("div",{className:e.detailsClassName},a.createElement("h4",{className:"font-size-normal fw-normal m-0"},e.anonymiseUsers?(0,s.B)(e.user,!0):e.showDisplayName?o.l.getDisplayName(e.user):o.l.getFullName(e.user)),e.showSubText&&a.createElement("p",{className:"text-secondary m-0"},e.getSubText?e.getSubText(e.user):function(e){var t=o.l.getUserType(e),n=o.l.getUserRole(e);if(t===c.Y.Staff)return n===l.i.Admin?m("admin"):m("staff");var a=o.l.getYearGroup(e);return(null==a?void 0:a.name)?a.name:m("student")}(e.user))))}d.defaults={showSubText:!0}},28972:(e,t,n)=>{var a;n.d(t,{w:()=>a}),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"}(a||(a={}))},8246:(e,t,n)=>{var a;n.d(t,{N:()=>a}),function(e){e[e.Incorrect=0]="Incorrect",e[e.Correct=1]="Correct",e[e.PendingReview=2]="PendingReview"}(a||(a={}))},17913:(e,t,n)=>{n.d(t,{u:()=>i});var a=n(97395),r=n(110),s=n(62875),i={individualEngagement:function(e,t,n,r,i,c){var l=Object.assign({objectId:e},t);return n&&(l.sharerId=n),{url:a._.urlBuilder("{gateway}/v1/analytics/heat-map",l),key:(0,s.H)("engagement:".concat(e),t,n),formatData:function(e){var t;return Object.assign(Object.assign({},e),{data:null===(t=e.data)||void 0===t?void 0:t.map((function(e){var t;return Object.assign(Object.assign({},e),{heatMap:null!==(t=e.heatMap)&&void 0!==t?t:[]})}))})},normalize:!1,success:r,error:i,always:c}},aggregateEngagement:function(e,t,n,r,i,c){var l=Object.assign({objectId:e},t);return n&&(l.sharerId=n),{url:a._.urlBuilder("{gateway}/v1/analytics/heat-map/aggregations",l),key:(0,s.H)("aggregate:engagement:".concat(e),t,n),formatData:function(e){var t;return Object.assign(Object.assign({},e),{heatMap:null!==(t=e.heatMap)&&void 0!==t?t:[]})},normalize:!1,success:r,error:i,always:c}},views:function(e,t,n,i,c,l){var o="video:views";t&&(o+=":".concat(t));var u=Object.assign(Object.assign({objectId:t},e),{timeOffset:r.O.getTimezoneOffset()});return n&&(u.sharerId=n),{url:a._.urlBuilder("{gateway}/v1/analytics/video-views",u),key:(0,s.H)(o,e,n),normalize:!1,success:i,error:c,always:l}}}},83140:(e,t,n)=>{n.d(t,{A:()=>v});var a=n(28972),r=n(8246),s=n(40424);function i(e){return i="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},i(e)}function c(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=i(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var a=n.call(e,"string");if("object"!=i(a))return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==i(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(){return a.w.NotApplicable}function o(e,t){var n=e.actionableItems.filter((function(e){return e.isCorrect}));return n.every((function(e){return!t(e.id)}))?a.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())}))?a.w.Correct:a.w.Incorrect}function u(e,t){return e.actionableItems.every((function(e){return!t(e.id)}))?a.w.UnAnswered:e.actionableItems.filter((function(e){return e.isCorrect})).every((function(e){var n,a=t(e.id);return(null==a?void 0:a.toString())===(null===(n=e.id)||void 0===n?void 0:n.toString())||a===e.name}))?a.w.Correct:a.w.Incorrect}function m(e,t){return function(n){var a=t.attempts.find((function(t){return t.id===e.id}));return null==a?void 0:a.answers.find((function(e){return e.id===n}))}}function d(e,t){var n=m(e,t);return u(e,(function(e){var t=n(e);return null==t?void 0:t.text}))}function p(e,t){return function(e,t){var n;return e.actionableItems.forEach((function(e){var s=t(e.id);n=s?s.status!==r.N.Correct?s.status!==r.N.Incorrect?a.w.AwaitingMarking:a.w.Incorrect:a.w.Correct:a.w.UnAnswered})),n}(e,m(e,t))}var g=c(c(c(c(c(c(c({},s.Z9.Annotation,l),s.Z9.Image,l),s.Z9.MissingWord,(function(e,t){var n=m(e,t);return o(e,(function(e){var t=n(e);return null==t?void 0:t.text}))})),s.Z9.MultipleChoice,d),s.Z9.ShortAnswer,p),s.Z9.TrueOrFalse,d),s.Z9.Illustration,p),v={notApplicable:l,awaitingMarking:function(){return a.w.AwaitingMarking},isMissingWordCorrect:o,isMultipleChoiceCorrect:u,isInteractionCorrect:function(e,t){return(0,g[e.typeId])(e,t)}}},80845:(e,t,n)=>{n.d(t,{Q:()=>o,Wn:()=>i,f6:()=>l,j_:()=>c});var a=n(75896),r=n(40424);function s(e){return e.typeId!==r.Z9.Annotation&&e.typeId!==r.Z9.Image}function i(e){return a.m.flatten(e.timepoints.map((function(e){return e.interactions})))}function c(e){return a.m.last(e.results)}function l(e,t){return a.m.findWhere(null==t?void 0:t.attempts,{id:e})}function o(e){return i(e).filter(s)}},80331:(e,t,n)=>{n.r(t),n.d(t,{InteractiveInsightsOverviewView:()=>me});var a=n(32735),r=n(2948),s=n(20354),i=n(75896),c=n(23481),l=n(25216),o=n(69332),u=n(83345),m=n(35223);const d={tealChart:"lZZf0",grayChart:"wJQc4",font:"o1Xbr"};function p(e){return p="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},p(e)}var g="shared.insightAverageAttempts",v=c.T.encloseNamespace(g);function f(e){var t,n,r=e.students.reduce((function(e,t){return t.summary.attempts>e?t.summary.attempts:e}),0),s=(t=function(){var t=e.students.reduce((function(e,t){var n,a,r,s=t.summary.attempts.toString();return s in e||Object.assign(e,(n={},r=0,(a=function(e){var t=function(e,t){if("object"!=p(e)||!e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var a=n.call(e,"string");if("object"!=p(a))return a;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==p(t)?t:t+""}(a=s))in n?Object.defineProperty(n,a,{value:r,enumerable:!0,configurable:!0,writable:!0}):n[a]=r,n)),e[s]++,e}),{});return Object.keys(t).length?t:{0:0}}(),n=0===t[0],{categories:Object.keys(t),series:[{type:"column",color:t[0]?"#EAEAEA":"#40C2BB",borderRadius:4,dataLabels:{enabled:!n,style:{fontSize:"12px",fontWeight:"normal"},inside:!1,overflow:"allow",crop:!1,className:d.font},data:Object.keys(t).map((function(e){return{className:"".concat(n?d.grayChart:d.tealChart," ").concat(r.toString()!==e?"opacity-25":""),y:t[e]}}))}]});return a.createElement(l.L,{title:v("title"),svgName:m.vn.Refresh,svgClassName:"bg-light-purple text-purple"},a.createElement("p",null,r?a.createElement(u.x,{namespace:g,phrase:"averageAttempts",options:{smartCount:r}}):a.createElement(u.x,{namespace:g,phrase:"noAttempts"})),a.createElement("div",{className:"mt-auto"},a.createElement(o.x,{label:v("attempts"),chartData:s})))}const h={redChart:"G7zOw",yellowChart:"k34mm",greenChart:"vBneA",blueChart:"RPTWm",grayChart:"k4JFZ",borderDark:"LWor3"};var y="shared.insightAverageScore",b=c.T.encloseNamespace(y);function E(e){return a.createElement(l.L,{title:b("title"),svgName:m.vn.Analytics,svgClassName:"bg-light-orange text-orange"},a.createElement("p",null,e.students.length?a.createElement(u.x,{namespace:y,phrase:"averageScore",options:(s=e.students.map((function(e){return e.summary.percentCorrect})),c=s.reduce((function(e,t){return e+t}),0)/s.length,d=i.m.last(i.m.last(e.students).results).attempts.length,{averageScore:Math.round(d*c),totalQuestions:d,averagePercentage:(100*c).toFixed(1)})}):a.createElement(u.x,{namespace:y,phrase:"noAnswers"})),a.createElement(o.x,{label:"".concat(b("studentScores")," (%)"),chartData:(t=Array(11).fill(0),n=e.students.reduce((function(e,t){return e[Math.floor(10*t.summary.percentCorrect)]++,e}),t),r=["0","10","20","30","40","50","60","70","80","90","100"],{categories:r,series:[{type:"column",color:"#4E9ACE",borderRadius:4,data:n.map((function(e,t){var n=Number(r[t]);return{className:"".concat(function(e,t){return 0===t?h.grayChart:e<50?h.redChart:e<70?h.yellowChart:e<90?h.greenChart:h.blueChart}(n,e)," rounded"),y:e}}))}]})}));var t,n,r,s,c,d}var C=n(461),w=c.T.encloseNamespace("shared.insightCompletedStudents");function N(e){return a.createElement(l.L,{title:w("title"),svgName:m.vn.Flag,svgClassName:"bg-light-indigo text-indigo",count:e.students.length},a.createElement(C.y,{students:e.students.map((function(e){return Object.assign(Object.assign({},e.user),{percentage:e.summary.percentCorrect})})),imageCdnUrl:e.imageCdnUrl,imageUrl:e.imageUrl,description:w("completedStudents"),appLink:e.resultsAppLink,appLinkText:w("viewAll"),anonymiseUsers:e.anonymiseUsers}))}var A=n(42642),S=n(39157),k=n(36848),I=n(86572),x=n(40782),O=n(80845),U="shared.insightEasiestQuestion",j=c.T.encloseNamespace(U);function L(e){var t,n=a.useMemo((function(){return t=e.interactive,n=e.results,a=(0,O.Q)(t).map((function(e){return Object.assign(Object.assign({},e),{resultsSummary:(0,S.nq)(e,n)})})).filter((function(e){return!!e.resultsSummary.answered&&!e.resultsSummary.awaitingMarking})),r=i.m.sortBy(a,(function(e){return e.resultsSummary.percentCorrect})),i.m.last(r);var t,n,a,r}),[e.results.students.length]);return a.createElement(l.L,{title:j("title"),subtitle:j("subtitle"),svgName:m.vn.StarOutline,svgClassName:"bg-light-blue text-blue"},a.createElement("div",{className:"d-flex align-items-center"},a.createElement(x.O,{percentage:null===(t=null==n?void 0:n.resultsSummary)||void 0===t?void 0:t.percentCorrect,layout:x.I.LabelInside}),n?a.createElement("div",{className:"d-flex ms-2"},a.createElement(I.y,{interaction:n,iconClassName:"flex-shrink-0"})):a.createElement("span",{className:"ms-2"},j("noAnswers"))),n&&a.createElement(k.F,{appLink:Object.assign(Object.assign({},e.questionsAppLink),{params:Object.assign(Object.assign({},e.questionsAppLink.params),{sortBy:"score_desc"})}),className:"text-info"},a.createElement(u.x,{namespace:U,phrase:"viewQuestions"})))}var T="shared.insightHardestQuestion",M=c.T.encloseNamespace(T);function R(e){var t,n=a.useMemo((function(){return t=e.interactive,n=e.results,a=(0,O.Q)(t).map((function(e){return Object.assign(Object.assign({},e),{resultsSummary:(0,S.nq)(e,n)})})).filter((function(e){return!!e.resultsSummary.answered&&!e.resultsSummary.awaitingMarking})),r=i.m.sortBy(a,(function(e){return e.resultsSummary.percentCorrect})),i.m.first(r);var t,n,a,r}),[e.results.students.length]);return a.createElement(l.L,{title:M("title"),subtitle:M("subtitle"),svgName:m.vn.QuestionMark,svgClassName:"bg-light-orange text-orange"},a.createElement("div",{className:"d-flex align-items-center"},a.createElement(x.O,{percentage:null===(t=null==n?void 0:n.resultsSummary)||void 0===t?void 0:t.percentCorrect,layout:x.I.LabelInside}),n?a.createElement("div",{className:"d-flex ms-2"},a.createElement(I.y,{interaction:n,iconClassName:"flex-shrink-0"})):a.createElement("span",{className:"ms-2"},M("noAnswers"))),n&&a.createElement(k.F,{appLink:Object.assign(Object.assign({},e.questionsAppLink),{params:Object.assign(Object.assign({},e.questionsAppLink.params),{sortBy:"score_asc"})}),className:"text-info"},a.createElement(u.x,{namespace:T,phrase:"viewQuestions"})))}var B=n(94652),H=c.T.encloseNamespace("shared.insightHighScoringStudents");function W(e){return a.createElement(l.L,{title:H("title"),subtitle:H("subtitle"),svgName:m.vn.Trophy,svgClassName:"bg-light-teal text-teal",count:e.students.length},a.createElement(C.y,{students:e.students.map((function(e){return Object.assign(Object.assign({},e.user),{percentage:e.summary.percentCorrect})})),imageCdnUrl:e.imageCdnUrl,imageUrl:e.greenChartImageUrl,description:H(e.completed.length?"noStudents":"highScore"),appLink:Object.assign(Object.assign({},e.resultsAppLink),{params:Object.assign(Object.assign({},e.resultsAppLink.params),{sortBy:"score_desc"})}),appLinkText:H("viewByHighest"),anonymiseUsers:e.anonymiseUsers}))}var P=c.T.encloseNamespace("shared.insightLowScoringStudents");function _(e){return a.createElement(l.L,{title:P("title"),subtitle:P("subtitle"),svgName:m.vn.Hand,svgClassName:"bg-light-red text-red",count:e.students.length},a.createElement(C.y,{students:e.students.map((function(e){return Object.assign(Object.assign({},e.user),{percentage:e.summary.percentCorrect})})),imageCdnUrl:e.imageCdnUrl,imageUrl:e.completed.length?e.heartImageUrl:e.redChartImageUrl,description:P(e.completed.length?"doingWell":"lowScore"),appLink:Object.assign(Object.assign({},e.resultsAppLink),{params:Object.assign(Object.assign({},e.resultsAppLink.params),{sortBy:"score_asc"})}),appLinkText:P("viewByLowest"),anonymiseUsers:e.anonymiseUsers}))}var F=c.T.encloseNamespace("shared.insightMarkingRequired");function q(e){return a.createElement(l.L,{title:F("title"),svgName:m.vn.Hand,svgClassName:"bg-light-blue text-blue",count:e.students.length},a.createElement(C.y,{students:e.students,imageCdnUrl:e.imageCdnUrl,imageUrl:e.imageUrl,description:F("studentsRequireMarking"),appLink:e.resultsAppLink,appLinkText:F("viewAll"),anonymiseUsers:e.anonymiseUsers}))}function D(e){return function(e){if(Array.isArray(e))return z(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return z(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?z(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function z(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=Array(t);n<t;n++)a[n]=e[n];return a}var Z=c.T.encloseNamespace("shared.insightNotCompletedStudents");function Q(e){var t,n,r,s=(t=e.markingRequiredStudents.map((function(e){return null==e?void 0:e.user.id})),n=e.completedStudents.map((function(e){return null==e?void 0:e.user.id})),r=e.classroomStudents.filter((function(e){return!t.includes(e.id)&&!n.includes(e.id)})),i.m.uniq([].concat(D(e.notCompletedStudents.map((function(e){return e.user}))),D(r)),"id"));return a.createElement(l.L,{title:Z("title"),svgName:m.vn.Puzzle,svgClassName:"bg-light-teal text-teal",count:s.length},a.createElement(C.y,{students:s,imageCdnUrl:e.imageCdnUrl,imageUrl:e.imageUrl,description:Z("completed"),appLink:e.resultsAppLink,appLinkText:Z("viewAll"),anonymiseUsers:e.anonymiseUsers}))}var G=n(41196),V=n(26025),K=n(74901),J=n(40003),Y=n(94892),$=n(38143),X=n(39151),ee=n(20768),te=n(31949),ne=n(17913),ae=n(99742),re=n(88630),se=n(5672),ie=n(83590),ce=n(14070),le=n(97291);function oe(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=Array(t);n<t;n++)a[n]=e[n];return a}var ue="insights.interactiveInsightsOverview";function me(e){var t,n,c,l,o,m,d=(o=(0,r.D)($.g.ANONYMISE_USERS),m=1,function(e){if(Array.isArray(e))return e}(o)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var a,r,s,i,c=[],l=!0,o=!1;try{if(s=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(a=s.call(n)).done)&&(c.push(a.value),c.length!==t);l=!0);}catch(e){o=!0,r=e}finally{try{if(!l&&null!=n.return&&(i=n.return(),Object(i)!==i))return}finally{if(o)throw r}}return c}}(o,m)||function(e,t){if(e){if("string"==typeof e)return oe(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?oe(e,t):void 0}}(o,m)||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.")}())[0],p=s.a.useBasicFetch(te.N.currentUser()),g=s.a.useBasicFetch(X.L.config()),v=s.a.useBasicFetch(p.data&&e.classroomId&&re.F.getClassroom(e.classroomId,p.data.id)),h=s.a.useBasicFetch(ee.b.interactiveMetadata(e.interactiveId)),y=s.a.useBasicFetch((null===(t=h.data)||void 0===t?void 0:t.interactiveId)&&ee.b.interactive(h.data.interactiveId)),b=V.B.getAudienceAppLinkParams(),C=V.B.getDateRangeAppLinkParams(),w=Object.assign(Object.assign({},(0,J.wO)((0,J.Hb)(),C)),(0,K.K)(b)),k=(0,G.W)(e.interactiveId,w),I=1===(null===(n=b.classrooms)||void 0===n?void 0:n.length)&&!(null===(c=b.classroomGroups)||void 0===c?void 0:c.length),x=s.a.useBasicFetch(I&&re.F.getClassroomStudents(i.m.first(b.classrooms))),O=s.a.useBasicFetch(ne.u.aggregateEngagement(e.interactiveId,w,p.data.id)),U=s.a.useBasicFetch(p.data&&ne.u.views(w,e.interactiveId,p.data.id)),j=p.data&&g.data&&(!e.classroomId||v.data)&&h.data&&y.data&&k.data&&(!I||x.data)&&O.data&&U.data,T=j&&(0,S.R6)(y.data,k.data,Y.T);if(!j)return a.createElement(a.Fragment,null);var M,H=Object.assign(Object.assign({},b),C),P=function(e,t){return{resultsAppLink:{application:le.O.INSIGHTS,action:ce.e.Insights.INTERACTIVE_RESULTS,args:[e],params:t},questionsAppLink:{application:le.O.INSIGHTS,action:ce.e.Insights.INTERACTIVE_QUESTIONS,args:[e],params:t},heatmapAppLink:{application:le.O.INSIGHTS,action:ce.e.Insights.INTERACTIVE_HEATMAP,args:[e],params:t}}}(e.interactiveId);return a.createElement("div",{className:"px-3"},a.createElement(ie.m,{video:h.data,audienceAppLinkParams:b,dateRangeAppLinkParams:C,tabs:(0,se.kj)(h.data.id,"overview",H)}),a.createElement("section",{className:"mb-5"},a.createElement("h2",{className:"h4"},a.createElement(u.x,{namespace:ue,phrase:"studentResponses"}),a.createElement("span",null,": ",T.completed.length,x.data?"/".concat(x.data.data.length):"")),a.createElement("div",{className:"row g-3"},a.createElement("div",{className:"col-12 col-md"},a.createElement(q,{imageUrl:ae.W.Insights.SPEECH_BUBBLE_ASTERISK,resultsAppLink:P.resultsAppLink,imageCdnUrl:g.data.imageCdnUrl,students:(M=T.markingRequired,M.map((function(e){return e.user}))),anonymiseUsers:d})),I&&a.createElement("div",{className:"col-12 col-md"},a.createElement(Q,{markingRequiredStudents:T.markingRequired,completedStudents:T.completed,notCompletedStudents:T.notCompleted,classroomStudents:x.data.data,imageCdnUrl:g.data.imageCdnUrl,imageUrl:ae.W.Insights.JIGSAW,resultsAppLink:P.resultsAppLink,anonymiseUsers:d})),a.createElement("div",{className:"col-12 col-md"},a.createElement(N,{students:T.completed,imageCdnUrl:g.data.imageCdnUrl,imageUrl:ae.W.Insights.AVATAR,resultsAppLink:P.resultsAppLink,anonymiseUsers:d})))),a.createElement("section",{className:"mb-5"},a.createElement("h2",{className:"h4"},a.createElement(u.x,{namespace:ue,phrase:"studentsPerformance"})),a.createElement("div",{className:"row g-3"},a.createElement("div",{className:"col-12 col-md-6"},a.createElement(_,{redChartImageUrl:ae.W.Insights.RED_CHART,heartImageUrl:ae.W.Insights.SPEECH_BUBBLE_HEART,resultsAppLink:P.resultsAppLink,imageCdnUrl:g.data.imageCdnUrl,students:T.lowScore,completed:T.completed,anonymiseUsers:d})),a.createElement("div",{className:"col-12 col-md-6"},a.createElement(W,{greenChartImageUrl:ae.W.Insights.GREEN_CHART,resultsAppLink:P.resultsAppLink,imageCdnUrl:g.data.imageCdnUrl,students:T.highScore,completed:T.completed,anonymiseUsers:d})),a.createElement("div",{className:"col-12 col-md-6"},a.createElement(R,{interactive:y.data,interactiveMetadata:h.data,results:k.data,questionsAppLink:P.questionsAppLink})),a.createElement("div",{className:"col-12 col-md-6"},a.createElement(L,{interactive:y.data,interactiveMetadata:h.data,results:k.data,questionsAppLink:P.questionsAppLink})))),a.createElement("section",{className:"mb-5"},a.createElement("h2",{className:"h4"},a.createElement(u.x,{namespace:ue,phrase:"classPerformance"})),a.createElement("div",{className:"row g-3"},a.createElement("div",{className:"col-12 col-md-6"},a.createElement(E,{students:T.completed})),a.createElement("div",{className:"col-12 col-md-6"},a.createElement(f,{students:T.completed})),a.createElement("div",{className:"col-12 col-md-6"},a.createElement(A.i,{osCount:null===(l=U.data)||void 0===l?void 0:l.osCount})),a.createElement("div",{className:"col-12 col-md-6"},a.createElement(B.b,{engagement:O.data,heatmapAppLink:P.heatmapAppLink})))))}},94831:(e,t,n)=>{n.d(t,{Z:()=>a});const a={removeRecipient:"mCbMC",recipientItem:"kdcb0",showSpinner:"xH6Mu",avatarContainer:"Zcpg3",recipientDetails:"v5EmV",recipientDetailsWithRemoveButton:"_V928"}}}]);
2
+ //# sourceMappingURL=8849-7d50f76777-lite.chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts/8849-7d50f76777-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/engagement-heat-map.scss","file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/EngagementHeatMap.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insight-card/insight-card.scss","file:///app/packages/libs/shared/src/apps/analytics/components/insight-card/InsightCard.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insight-chart/InsightChart.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insight-chart/insight-chart.scss","file:///app/packages/libs/shared/src/apps/analytics/components/insight-student-list/insight-student-list.scss","file:///app/packages/libs/shared/src/apps/analytics/components/insight-student-list/InsightStudentList.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/devices/insight-devices.scss","file:///app/packages/libs/shared/src/apps/analytics/components/insights/devices/InsightDevices.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/heatmap/insight-heatmap.scss","file:///app/packages/libs/shared/src/apps/analytics/components/insights/heatmap/InsightHeatmap.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/EngagementUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/InteractiveUtils.ts","file:///app/packages/libs/shared/src/apps/share/components/recipient-item/user-recipient-item-metadata/UserRecipientItemMetadata.tsx","file:///app/packages/libs/shared/src/enums/InteractionCorrectness.ts","file:///app/packages/libs/shared/src/enums/InteractiveAnswerStatus.ts","file:///app/packages/libs/shared/src/flight-requests/VideoViewRequests.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/insights/average-attempts/insight-average-attempts.scss","file:///app/packages/libs/shared/src/apps/analytics/components/insights/average-attempts/InsightAverageAttempts.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/average-score/insight-average-score.scss","file:///app/packages/libs/shared/src/apps/analytics/components/insights/average-score/InsightAverageScore.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/completed-students/InsightCompletedStudents.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/easiest-question/InsightEasiestQuestion.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/hardest-question/InsightHardestQuestion.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/high-scoring-students/InsightHighScoringStudents.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/low-scoring-students/InsightLowScoringStudents.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/marking-required/InsightMarkingRequired.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/insights/not-completed-students/InsightNotCompletedStudents.tsx","file:///app/packages/projects/lite/src/apps/insights/views/interactive/overview/InteractiveInsightsOverviewView.tsx","file:///app/packages/projects/lite/src/apps/insights/views/interactive/overview/InteractiveInsightsOverviewUtils.ts","file:///app/packages/libs/shared/src/apps/share/components/recipient-item/recipient-item.scss"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"heatMap\":\"epapa\",\"legend\":\"uhH4p\"};","import React from 'react';\nimport chroma from 'chroma-js';\n\nimport { getFullHeatMap } from 'libs/shared/apps/analytics/utils/EngagementUtils';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Engagement } from 'libs/shared/interfaces';\n\nimport styles from './engagement-heat-map.scss';\n\nconst namespace = 'shared.engagementHeatMap';\n\nconst ZERO_COLOUR = '#f1f1f1';\nconst MIN_COLOUR = '#daf07d';\nconst MAX_COLOUR = '#08bd1a';\n\nconst COLOUR_SCALE = chroma.scale([ MIN_COLOUR, MAX_COLOUR ]);\n\nconst LEGEND_VALUES = [ 0, 0.01, 0.25, 0.5, 0.75, 1 ];\n\nfunction getBackgroundColor(value: number, max: number): string {\n if (!value)\n return ZERO_COLOUR;\n\n return COLOUR_SCALE(value / max).hex();\n}\n\nfunction getGradient(data: number[], max: number): string {\n const gradient: string[] = [];\n\n for (let i = 0; i < data.length; i++) {\n const previousValue = i > 0 && data[i - 1];\n const currentValue = data[i];\n const nextValue = i < data.length - 1 && data[i + 1];\n\n /**\n * We want to capture colour changes but if a value has the same value\n * of both of its neighbours, we can skip it.\n */\n if (currentValue === previousValue && currentValue === nextValue)\n continue;\n\n gradient.push(`${getBackgroundColor(currentValue, max)} ${100 / data.length * i}%`);\n }\n\n return `linear-gradient(to right, ${gradient.join(',')})`;\n}\n\nexport function EngagementHeatMapLegend(): JSX.Element {\n const max = Math.max(...LEGEND_VALUES);\n const legendSquareWidthPercentage = 100 / LEGEND_VALUES.length;\n\n return (\n <div className='d-flex justify-content-between w-100'>\n <Text namespace={namespace} phrase='less' />\n <div className={`d-flex mx-1 flex-grow-1 ${styles.legend}`}>\n {LEGEND_VALUES.map((val, idx) => (\n <div\n key={idx}\n style={{\n width: `${legendSquareWidthPercentage}%`,\n backgroundColor: getBackgroundColor(val, max)\n }}\n />\n ))}\n </div>\n <Text namespace={namespace} phrase='more' />\n </div>\n );\n}\n\ninterface EngagementHeatMapProps {\n engagement: Engagement;\n max?: number;\n className?: string;\n}\n\nexport function EngagementHeatMap(props: EngagementHeatMapProps): JSX.Element {\n const heatMap = getFullHeatMap(props.engagement);\n const max = props.max ?? Math.max(...heatMap);\n\n return (\n <div\n className={`border rounded ${styles.heatMap} ${props.className ?? ''}`}\n style={{\n background: getGradient(heatMap, max)\n }}\n />\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"icon\":\"sAmpy\",\"count\":\"faDs4\"};","import React from 'react';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\n\nimport styles from './insight-card.scss';\n\ninterface InsightCardProps extends React.PropsWithChildren {\n svgName: string;\n svgClassName: string;\n title: string;\n subtitle?: string;\n count?: number;\n}\n\nexport function InsightCard(props: InsightCardProps) {\n return (\n <section className='d-flex flex-column border border-light rounded p-3 h-100'>\n <div className='d-flex align-items-center mb-2'>\n <div className={`${styles.icon} ${props.svgClassName} rounded-circle d-flex align-items-center justify-content-center`}>\n <SvgContainer svgName={props.svgName} />\n </div>\n <div className='d-flex flex-column ms-2'>\n <h2 className='h6 mb-0'>{props.title}</h2>\n {props.subtitle && <p className='text-secondary font-size-sm mb-0'>{props.subtitle}</p>}\n </div>\n {typeof props.count === 'number' && (\n <div className={`${styles.count} d-flex justify-content-center align-items-center bg-light rounded-circle ms-auto`}>\n {props.count}\n </div>\n )}\n </div>\n {props.children}\n </section>\n );\n}","import React from 'react';\nimport Highcharts from 'highcharts';\nimport HighchartsReact from 'highcharts-react-official';\n\nimport { ChartData } from 'libs/shared/apps/analytics/interfaces/ChartData';\n\nimport styles from './insight-chart.scss';\n\nconst getStaticChartOptions = (label: string): Highcharts.Options => {\n return {\n title: {\n text: null\n },\n credits: {\n enabled: false\n },\n yAxis: {\n title: {\n text: null\n },\n labels: {\n enabled: false\n },\n gridLineWidth: 0,\n min: 0,\n tickAmount: 1\n },\n xAxis: {\n title: {\n text: label,\n style: {\n color: '#313543',\n fontSize: '12px'\n }\n },\n labels: {\n style: {\n color: '#313543',\n fontSize: '12px'\n }\n },\n className: styles.font,\n lineWidth: 0\n },\n legend: {\n enabled: false\n },\n chart: {\n type: 'column',\n backgroundColor: 'transparent',\n height: '160px',\n spacingTop: 20\n },\n plotOptions: {\n column: {\n dataLabels: {\n enabled: false\n },\n enableMouseTracking: false,\n minPointLength: 8\n }\n }\n };\n};\n\ninterface InsightChartProps {\n label: string;\n chartData: ChartData;\n}\n\nexport function InsightChart(props: InsightChartProps) {\n function getChartOptions(): Highcharts.Options {\n const data = props.chartData;\n const staticChartOptions = getStaticChartOptions(props.label);\n\n return {\n ...staticChartOptions,\n xAxis: {\n ...staticChartOptions.xAxis,\n categories: data.categories\n },\n series: data.series\n };\n }\n\n return (\n <HighchartsReact\n highcharts={Highcharts}\n options={getChartOptions()}\n />\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"font\":\"nSTtI\"};","// extracted by mini-css-extract-plugin\nexport default {\"avatar\":\"uMuZt\",\"image\":\"WdKiU\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { UserRecipientItemMetadata } from 'libs/shared/apps/share/components/recipient-item/user-recipient-item-metadata/UserRecipientItemMetadata';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { PercentageIndicator } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { User } from 'libs/shared/interfaces';\n\nimport styles from './insight-student-list.scss';\n\nconst MAX_ITEMS = 3;\n\ninterface UserPercentage extends User {\n percentage?: number;\n}\n\ninterface InsightStudentListProps {\n students: UserPercentage[];\n imageUrl: string;\n imageCdnUrl: string;\n appLink: Core.AppLink;\n description: string;\n appLinkText: string;\n percentages?: number[];\n anonymiseUsers: boolean;\n}\n\nexport function InsightStudentList(props: InsightStudentListProps) {\n return (\n <>\n {props.students.length ? (\n <ul className='list-unstyled mb-2'>\n {props.students.slice(0, MAX_ITEMS).map((student, index) => (\n <li key={index} className='d-flex align-items-center mb-2'>\n <UserRecipientItemMetadata\n user={student}\n imageCdnUrl={props.imageCdnUrl}\n avatarClassName={styles.avatar}\n detailsClassName='ms-2'\n showDisplayName\n showSubText={false}\n anonymiseUsers={props.anonymiseUsers}\n />\n\n <div className='d-flex align-items-center ms-auto'>\n <span className='me-1'>{student.percentage === undefined ? '- ' : Math.round(student.percentage * 100)}%</span>\n <PercentageIndicator percentage={student.percentage} />\n </div>\n </li>\n ))}\n </ul>\n ) : (\n <div className='text-center'>\n <img className={`${styles.image} mb-2`} src={props.imageUrl} />\n <p className='text-secondary mb-0' dangerouslySetInnerHTML={{ __html: props.description }} />\n </div>\n )}\n\n {!!props.students.length && (\n <AppLink appLink={props.appLink} className='text-info mt-auto'>\n {props.appLinkText}\n </AppLink>\n )}\n </>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"font\":\"xTiKg\",\"purpleChart\":\"OPcvi\",\"grayChart\":\"HlWj7\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InsightChart } from 'libs/shared/apps/analytics/components/insight-chart/InsightChart';\nimport { GroupedAnalyticsCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { ChartData } from 'libs/shared/apps/analytics/interfaces/ChartData';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './insight-devices.scss';\n\nconst namespace = 'shared.insightDevices';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\n// Names from UserAgentHelper.getOperatingSystem()\nfunction getDeviceType(name: string) {\n switch (name) {\n case 'Android':\n case 'Windows Phone':\n case 'iOS':\n case 'BlackBerry':\n return 'Mobile';\n case 'Linux':\n case 'Unix':\n case 'Macintosh':\n case 'Windows':\n return 'Computer';\n }\n}\n\ninterface InsightDevicesProps {\n osCount: GroupedAnalyticsCount[]\n}\n\nexport function InsightDevices(props: InsightDevicesProps) {\n const categoriesData = getCategoriesData();\n const highestDeviceCount = getHighestDeviceCount();\n\n function getCategoriesData() {\n const defaultDevices: HashObject = { Phone: 0, Computer: 0 };\n\n if (!props.osCount?.length)\n return defaultDevices;\n\n return props.osCount.reduce((acc, group) => {\n if (!group.name) return acc;\n\n const deviceCategory = getDeviceType(group.name);\n\n acc[deviceCategory] = acc[deviceCategory] + group.count;\n\n return acc;\n }, defaultDevices);\n }\n\n function getHighestDeviceCount() {\n if (!props.osCount?.length) return null;\n\n return props.osCount.reduce((acc, group) => group.name && group.count > acc.count\n ? group\n : ArrayHelper.first(props.osCount));\n }\n\n function getChartData(): ChartData {\n return {\n categories: Object.keys(categoriesData),\n series: [{\n type: 'column',\n borderRadius: 4,\n dataLabels: {\n enabled: true,\n style: {\n fontSize: '12px',\n fontWeight: 'normal'\n },\n inside: false,\n overflow: 'allow',\n crop: false,\n className: styles.font\n },\n data: Object.keys(categoriesData).map(category => ({\n className: `${categoriesData[category] === 0 ? styles.grayChart : styles.purpleChart} ${categoriesData[category] !== highestDeviceCount?.count ? 'opacity-25' : ''}`,\n y: categoriesData[category]\n }))\n }]\n };\n }\n\n const chartData = getChartData();\n\n return (\n <InsightCard\n title={getPhrase('title')}\n svgClassName='bg-light-ultramarine text-ultramarine'\n svgName={cvSvgLibrary.Monitor}\n >\n <p className='mb-0'>\n {props.osCount?.filter(group => group.name).length\n ? (\n <Text\n namespace={namespace}\n phrase='description'\n options={{ device: getDeviceType(highestDeviceCount?.name)?.toLowerCase() }}\n />\n ) : (\n <Text\n namespace={namespace}\n phrase='notViewed'\n />\n )}\n </p>\n\n <div className='position-relative mt-auto'>\n <InsightChart label={getPhrase('title')} chartData={chartData} />\n </div>\n </InsightCard>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"heatMap\":\"Rfr9N\",\"heatMapTimepointIndicator\":\"s6JbA\",\"heatMapTimepointIndicatorVisible\":\"mgjWX\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EngagementHeatMap } from 'libs/shared/apps/analytics/components/engagement-heat-map/EngagementHeatMap';\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Engagement } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './insight-heatmap.scss';\n\nconst namespace = 'shared.insightHeatmap';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightHeatmapProps {\n engagement: Engagement;\n heatmapAppLink: Core.AppLink;\n}\n\nexport function InsightHeatmap(props: InsightHeatmapProps) {\n const engagementRate = props.engagement.engagementRate > 0 ? Math.round(props.engagement.engagementRate * 100) : null;\n\n return (\n <InsightCard\n title={getPhrase('title')}\n svgName={cvSvgLibrary.Timer}\n svgClassName='bg-light-green text-green'\n >\n <div className='mb-2'>\n <p className='mb-0'>\n {engagementRate\n ? (\n <Text namespace={namespace} phrase='everyoneWatched' options={{ engagementRate }} />\n )\n : <Text namespace={namespace} phrase='notWatched' />\n }\n </p>\n {engagementRate &&\n <AppLink appLink={props.heatmapAppLink} className='text-info'>\n <Text namespace={namespace} phrase='viewHeatmap' />\n </AppLink>\n }\n </div>\n\n <div className='mb-2'>\n <EngagementHeatMap\n engagement={props.engagement}\n className={styles.heatMap}\n />\n </div>\n\n <p className='h3 text-center mb-2'>{engagementRate || '--'}%</p>\n <p className='text-center mb-0 font-size-sm'><Text namespace={namespace} phrase='amountWatched' /></p>\n </InsightCard>\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 { Engagement } from 'libs/shared/interfaces';\n\n/**\n * The heat map in the API response won't contain trailing zeros so we need to add those\n * in manually.\n */\nexport function getFullHeatMap(engagement: Engagement): number[] {\n return (new Array(Math.ceil(engagement.videoDuration))).fill(null).map((t, idx) => engagement.heatMap[idx] || 0);\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}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { anonymiseUserName } from 'libs/shared/apps/analytics/utils/AnonymiseUserUtils';\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { UserRole } from 'libs/shared/enums/UserRole';\nimport { BaseObject, User } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from '../recipient-item.scss';\n\nconst namespace = 'shared.userRecipientItemMetadata';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getSubText(user: User): string {\n const userType = UserHelper.getUserType(user);\n const role = UserHelper.getUserRole(user);\n\n if (userType === UserGroup.Staff) {\n if (role === UserRole.Admin)\n return getPhrase('admin');\n\n return getPhrase('staff');\n }\n\n const yearGroup = UserHelper.getYearGroup(user);\n\n if (yearGroup?.name)\n return yearGroup.name;\n\n return getPhrase('student');\n}\n\nUserRecipientItemMetadata.defaults = {\n showSubText: true\n};\n\ninterface UserRecipientItemMetadataProps {\n user: User;\n imageCdnUrl: string;\n detailsClassName?: string;\n avatarClassName?: string;\n showDisplayName: boolean;\n showSubText?: boolean;\n anonymiseUsers?: boolean;\n getSubText?: (user: BaseObject) => string;\n}\n\nexport function UserRecipientItemMetadata(props: UserRecipientItemMetadataProps): JSX.Element {\n return (\n <>\n <div className={`${styles.avatarContainer} ${props.avatarClassName} d-inline-block`}>\n <Avatar\n imageUrl={props.user.avatar?.url}\n imageCdnUrl={props.imageCdnUrl}\n initials={UserHelper.getInitials(props.user.name, props.user.surname)}\n />\n </div>\n\n <div className={props.detailsClassName}>\n <h4 className='font-size-normal fw-normal m-0'>\n {props.anonymiseUsers\n ? anonymiseUserName(props.user, true)\n : props.showDisplayName\n ? UserHelper.getDisplayName(props.user)\n : UserHelper.getFullName(props.user)\n }\n </h4>\n {props.showSubText && <p className='text-secondary m-0'>{props.getSubText ? props.getSubText(props.user) : getSubText(props.user)}</p>}\n </div>\n </>\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 { Xhr } from 'libs/common/backbone/interfaces/Xhr';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { VideoViewEventResponse } from 'libs/shared/apps/analytics/interfaces/VideoViewEvent';\nimport { AnalyticsRequestFilter, Engagement, IndividualEngagementResponse } from 'libs/shared/interfaces';\nimport { getAnalyticsRequestKey } from 'libs/shared/utils/AnalyticsRequestUtils';\n\nexport const VideoViewRequests = {\n individualEngagement(\n objectId: string,\n filter: AnalyticsRequestFilter,\n sharerId?: string,\n success?: (data: IndividualEngagementResponse) => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n const queryParams: HashObject = {\n objectId,\n ...filter\n };\n\n if (sharerId)\n queryParams.sharerId = sharerId;\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/analytics/heat-map', queryParams),\n key: getAnalyticsRequestKey(`engagement:${objectId}`, filter, sharerId),\n formatData: (data: any) => {\n return {\n ...data,\n data: data.data?.map((d: any) => ({\n ...d,\n heatMap: d.heatMap ?? []\n }))\n };\n },\n normalize: false,\n success,\n error,\n always\n };\n },\n \n aggregateEngagement(\n objectId: string,\n filter: AnalyticsRequestFilter,\n sharerId?: string,\n success?: (data: Engagement) => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n const queryParams: HashObject = {\n objectId,\n ...filter\n };\n\n if (sharerId)\n queryParams.sharerId = sharerId;\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/analytics/heat-map/aggregations', queryParams),\n key: getAnalyticsRequestKey(`aggregate:engagement:${objectId}`, filter, sharerId),\n formatData: (data: Engagement) => {\n return {\n ...data,\n heatMap: data.heatMap ?? []\n };\n },\n normalize: false,\n success,\n error,\n always\n };\n },\n \n views(\n filter: AnalyticsRequestFilter,\n objectId?: string,\n sharerId?: string,\n success?: (data: VideoViewEventResponse) => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n let baseKey = 'video:views';\n\n if (objectId)\n baseKey += `:${objectId}`;\n\n const queryParams: HashObject = {\n objectId,\n ...filter,\n timeOffset: DateHelper.getTimezoneOffset()\n };\n\n if (sharerId)\n queryParams.sharerId = sharerId;\n\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/analytics/video-views', queryParams),\n key: getAnalyticsRequestKey(baseKey, filter, sharerId),\n normalize: false,\n success,\n error,\n always\n };\n }\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 {\"tealChart\":\"lZZf0\",\"grayChart\":\"wJQc4\",\"font\":\"o1Xbr\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InsightChart } from 'libs/shared/apps/analytics/components/insight-chart/InsightChart';\nimport { ChartData } from 'libs/shared/apps/analytics/interfaces/ChartData';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './insight-average-attempts.scss';\n\nconst namespace = 'shared.insightAverageAttempts';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightAverageAttemptsProps {\n students: StudentResultsWithSummary[];\n}\n\nexport function InsightAverageAttempts(props: InsightAverageAttemptsProps) {\n const averageAttempts = getAverageAttempts();\n const chartData = getChartData();\n\n function getCategoriesData() {\n const categoriesData = props.students.reduce((acc, student) => {\n const attemptsCategory = student.summary.attempts.toString();\n\n if (!(attemptsCategory in acc)) {\n Object.assign(acc, { [attemptsCategory]: 0 });\n }\n\n acc[attemptsCategory]++;\n\n return acc;\n }, {} as HashObject);\n return Object.keys(categoriesData).length ? categoriesData : { 0: 0 };\n }\n\n function getAverageAttempts() {\n return props.students.reduce((acc, student) => student.summary.attempts > acc ? student.summary.attempts : acc, 0);\n }\n\n function getChartData(): ChartData {\n const categoriesData = getCategoriesData();\n const noAttempts = categoriesData[0] === 0;\n\n return {\n categories: Object.keys(categoriesData),\n series: [{\n type: 'column',\n color: categoriesData[0] ? '#EAEAEA' : '#40C2BB',\n borderRadius: 4,\n dataLabels: {\n enabled: !noAttempts,\n style: {\n fontSize: '12px',\n fontWeight: 'normal'\n },\n inside: false,\n overflow: 'allow',\n crop: false,\n className: styles.font\n },\n data: Object.keys(categoriesData).map(category => ({\n className: `${noAttempts ? styles.grayChart : styles.tealChart} ${averageAttempts.toString() !== category ? 'opacity-25' : ''}`,\n y: categoriesData[category]\n }))\n }]\n };\n }\n\n return (\n <InsightCard\n title={getPhrase('title')}\n svgName={cvSvgLibrary.Refresh}\n svgClassName='bg-light-purple text-purple'\n >\n <p>\n {averageAttempts\n ? <Text namespace={namespace} phrase='averageAttempts' options={{ smartCount: averageAttempts }} />\n : <Text namespace={namespace} phrase='noAttempts'/>\n }\n </p>\n\n <div className='mt-auto'>\n <InsightChart label={getPhrase('attempts')} chartData={chartData} />\n </div>\n </InsightCard>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"redChart\":\"G7zOw\",\"yellowChart\":\"k34mm\",\"greenChart\":\"vBneA\",\"blueChart\":\"RPTWm\",\"grayChart\":\"k4JFZ\",\"borderDark\":\"LWor3\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InsightChart } from 'libs/shared/apps/analytics/components/insight-chart/InsightChart';\nimport { ChartData } from 'libs/shared/apps/analytics/interfaces/ChartData';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './insight-average-score.scss';\n\nconst namespace = 'shared.insightAverageScore';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\n\ninterface InsightAverageScoreProps {\n students: StudentResultsWithSummary[];\n}\n\nexport function InsightAverageScore(props: InsightAverageScoreProps) {\n function getChartData(): ChartData {\n const scoreCount = Array(11).fill(0);\n const scorePercentageData = props.students.reduce((acc, value) => {\n const scoreIndex = Math.floor(value.summary.percentCorrect * 10);\n acc[scoreIndex]++;\n\n return acc;\n }, scoreCount);\n\n const PERCENTAGES = [ '0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100' ];\n // TODO Outline \n // const averageScore = scorePercentageData.reduce((acc, value) => {\n // return value > acc ? value : acc;\n // }, 0);\n // ${averageScore === score ? styles.borderDark : ''}\n\n return {\n categories: PERCENTAGES,\n series: [{\n type: 'column',\n color: '#4E9ACE',\n borderRadius: 4,\n data: scorePercentageData.map((score, index) => {\n const percentageCategory = Number(PERCENTAGES[index]);\n\n const getChartColour = (percentage: number, score: number) => {\n if (score === 0)\n return styles.grayChart;\n if (percentage < 50)\n return styles.redChart;\n if (percentage < 70)\n return styles.yellowChart;\n if (percentage < 90)\n return styles.greenChart;\n\n return styles.blueChart;\n };\n\n return {\n className: `${getChartColour(percentageCategory, score)} rounded`,\n y: score\n };\n })\n }]\n };\n }\n\n function getAverageNumbers() {\n const averageScores = props.students.map(student => student.summary.percentCorrect);\n const averagePercentage = averageScores.reduce((a, b) => a + b, 0) / averageScores.length;\n const totalQuestions = ArrayHelper.last(\n ArrayHelper.last(props.students).results\n ).attempts.length;\n\n return {\n averageScore: Math.round(totalQuestions * averagePercentage),\n totalQuestions,\n averagePercentage: (averagePercentage * 100).toFixed(1)\n };\n }\n\n return (\n <InsightCard\n title={getPhrase('title')}\n svgName={cvSvgLibrary.Analytics}\n svgClassName='bg-light-orange text-orange'\n >\n <p>\n {props.students.length\n ? <Text namespace={namespace} phrase='averageScore' options={getAverageNumbers()} />\n : <Text namespace={namespace} phrase='noAnswers' />\n }\n </p>\n\n <InsightChart label={`${getPhrase('studentScores')} (%)`} chartData={getChartData()} />\n </InsightCard>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InsightStudentList } from 'libs/shared/apps/analytics/components/insight-student-list/InsightStudentList';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.insightCompletedStudents';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightCompletedStudentsProps {\n students: StudentResultsWithSummary[];\n imageCdnUrl: string;\n imageUrl: string;\n resultsAppLink: Core.AppLink;\n anonymiseUsers: boolean;\n}\n\nexport function InsightCompletedStudents(props: InsightCompletedStudentsProps) {\n return (\n <InsightCard\n title={getPhrase('title')}\n svgName={cvSvgLibrary.Flag}\n svgClassName='bg-light-indigo text-indigo'\n count={props.students.length}\n >\n <InsightStudentList\n students={props.students.map(student => ({ ...student.user, percentage: student.summary.percentCorrect }))}\n imageCdnUrl={props.imageCdnUrl}\n imageUrl={props.imageUrl}\n description={getPhrase('completedStudents')}\n appLink={props.resultsAppLink}\n appLinkText={getPhrase('viewAll')}\n anonymiseUsers={props.anonymiseUsers}\n />\n </InsightCard>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InteractionWithResultsSummary } from 'libs/shared/apps/analytics/interfaces/InteractionWithResultsSummary';\nimport { getInteractionResultsSummary } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { PercentageIndicator, PercentageIndicatorLayout } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getInteractions } from 'libs/shared/utils/InteractiveHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.insightEasiestQuestion';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightEasiestQuestionProps {\n interactive: Interactive;\n interactiveMetadata: InteractiveMetadata;\n results: InteractiveResultSet;\n questionsAppLink: Core.AppLink;\n}\n\nexport function InsightEasiestQuestion(props: InsightEasiestQuestionProps) {\n const easiestQuestion = React.useMemo(\n () => getEasiestQuestion(props.interactive, props.results),\n [props.results.students.length]\n );\n\n function getEasiestQuestion(interactive: Interactive, results: InteractiveResultSet): InteractionWithResultsSummary {\n const interactions: InteractionWithResultsSummary[] = getInteractions(interactive).map(i => ({\n ...i,\n resultsSummary: getInteractionResultsSummary(i, results)\n }));\n\n const answeredInteractions = interactions.filter(i =>\n !!i.resultsSummary.answered && !i.resultsSummary.awaitingMarking);\n\n const sortedInteractions = ArrayHelper.sortBy(\n answeredInteractions,\n i => i.resultsSummary.percentCorrect\n );\n\n return ArrayHelper.last(sortedInteractions);\n }\n\n return (\n <InsightCard\n title={getPhrase('title')}\n subtitle={getPhrase('subtitle')}\n svgName={cvSvgLibrary.StarOutline}\n svgClassName='bg-light-blue text-blue'\n >\n <div className='d-flex align-items-center'>\n <PercentageIndicator\n percentage={easiestQuestion?.resultsSummary?.percentCorrect}\n layout={PercentageIndicatorLayout.LabelInside}\n />\n {easiestQuestion\n ? <div className='d-flex ms-2'>\n <InteractionLabel interaction={easiestQuestion} iconClassName='flex-shrink-0' />\n </div>\n : <span className='ms-2'>{getPhrase('noAnswers')}</span>\n }\n </div>\n\n {easiestQuestion && (\n <AppLink\n appLink={{\n ...props.questionsAppLink,\n params: {\n ...props.questionsAppLink.params as HashObject,\n sortBy: 'score_desc'\n }\n }}\n className='text-info'>\n <Text namespace={namespace} phrase='viewQuestions' />\n </AppLink>\n )}\n </InsightCard>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InteractionWithResultsSummary } from 'libs/shared/apps/analytics/interfaces/InteractionWithResultsSummary';\nimport { getInteractionResultsSummary } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { PercentageIndicator, PercentageIndicatorLayout } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getInteractions } from 'libs/shared/utils/InteractiveHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.insightHardestQuestion';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightHardestQuestionProps {\n interactive: Interactive;\n interactiveMetadata: InteractiveMetadata;\n results: InteractiveResultSet;\n questionsAppLink: Core.AppLink;\n}\n\nexport function InsightHardestQuestion(props: InsightHardestQuestionProps) {\n const hardestQuestion = React.useMemo(\n () => getHardestQuestion(props.interactive, props.results),\n [props.results.students.length]\n );\n\n function getHardestQuestion(interactive: Interactive, results: InteractiveResultSet): InteractionWithResultsSummary {\n const interactions: InteractionWithResultsSummary[] = getInteractions(interactive).map(i => ({\n ...i,\n resultsSummary: getInteractionResultsSummary(i, results)\n }));\n\n const answeredInteractions = interactions.filter(i =>\n !!i.resultsSummary.answered && !i.resultsSummary.awaitingMarking);\n\n const sortedInteractions = ArrayHelper.sortBy(\n answeredInteractions,\n i => i.resultsSummary.percentCorrect\n );\n\n return ArrayHelper.first(sortedInteractions);\n }\n\n return (\n <InsightCard\n title={getPhrase('title')}\n subtitle={getPhrase('subtitle')}\n svgName={cvSvgLibrary.QuestionMark}\n svgClassName='bg-light-orange text-orange'\n >\n <div className='d-flex align-items-center'>\n <PercentageIndicator\n percentage={hardestQuestion?.resultsSummary?.percentCorrect}\n layout={PercentageIndicatorLayout.LabelInside}\n />\n {hardestQuestion\n ? <div className='d-flex ms-2'>\n <InteractionLabel interaction={hardestQuestion} iconClassName='flex-shrink-0' />\n </div>\n : <span className='ms-2'>{getPhrase('noAnswers')}</span>\n }\n </div>\n\n {hardestQuestion && (\n <AppLink\n appLink={{\n ...props.questionsAppLink,\n params: {\n ...props.questionsAppLink.params as HashObject,\n sortBy: 'score_asc'\n }\n }}\n className='text-info'\n >\n <Text namespace={namespace} phrase='viewQuestions' />\n </AppLink>\n )}\n </InsightCard>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InsightStudentList } from 'libs/shared/apps/analytics/components/insight-student-list/InsightStudentList';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.insightHighScoringStudents';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightHighScoringStudentsProps {\n students: StudentResultsWithSummary[];\n imageCdnUrl: string;\n greenChartImageUrl: string;\n resultsAppLink: Core.AppLink;\n completed: StudentResultsWithSummary[];\n anonymiseUsers?: boolean;\n}\n\nexport function InsightHighScoringStudents(props: InsightHighScoringStudentsProps) {\n return (\n <InsightCard\n title={getPhrase('title')}\n subtitle={getPhrase('subtitle')}\n svgName={cvSvgLibrary.Trophy}\n svgClassName='bg-light-teal text-teal'\n count={props.students.length}\n >\n <InsightStudentList\n students={props.students.map(student => ({ ...student.user, percentage: student.summary.percentCorrect }))}\n imageCdnUrl={props.imageCdnUrl}\n imageUrl={props.greenChartImageUrl}\n description={getPhrase(props.completed.length ? 'noStudents' : 'highScore')}\n appLink={{\n ...props.resultsAppLink,\n params: {\n ...props.resultsAppLink.params as HashObject,\n sortBy: 'score_desc'\n }\n }}\n appLinkText={getPhrase('viewByHighest')}\n anonymiseUsers={props.anonymiseUsers}\n />\n </InsightCard>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InsightStudentList } from 'libs/shared/apps/analytics/components/insight-student-list/InsightStudentList';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.insightLowScoringStudents';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightLowScoringStudentsProps {\n students: StudentResultsWithSummary[];\n imageCdnUrl: string;\n redChartImageUrl: string;\n heartImageUrl: string;\n resultsAppLink: Core.AppLink;\n completed: StudentResultsWithSummary[];\n anonymiseUsers: boolean;\n}\n\nexport function InsightLowScoringStudents(props: InsightLowScoringStudentsProps) {\n return (\n <InsightCard\n title={getPhrase('title')}\n subtitle={getPhrase('subtitle')}\n svgName={cvSvgLibrary.Hand}\n svgClassName='bg-light-red text-red'\n count={props.students.length}\n >\n <InsightStudentList\n students={props.students.map(student => ({ ...student.user, percentage: student.summary.percentCorrect }))}\n imageCdnUrl={props.imageCdnUrl}\n imageUrl={props.completed.length ? props.heartImageUrl : props.redChartImageUrl}\n description={getPhrase(props.completed.length ? 'doingWell' : 'lowScore')}\n appLink={{\n ...props.resultsAppLink,\n params: {\n ...props.resultsAppLink.params as HashObject,\n sortBy: 'score_asc'\n }\n }}\n appLinkText={getPhrase('viewByLowest')}\n anonymiseUsers={props.anonymiseUsers}\n />\n </InsightCard>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InsightStudentList } from 'libs/shared/apps/analytics/components/insight-student-list/InsightStudentList';\nimport { User } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\n\nconst namespace = 'shared.insightMarkingRequired';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\n\ninterface InsightMarkingRequiredProps {\n students: User[];\n imageCdnUrl: string;\n imageUrl: string;\n resultsAppLink: Core.AppLink;\n anonymiseUsers: boolean;\n}\n\nexport function InsightMarkingRequired(props: InsightMarkingRequiredProps) {\n return (\n <InsightCard\n title={getPhrase('title')}\n svgName={cvSvgLibrary.Hand}\n svgClassName='bg-light-blue text-blue'\n count={props.students.length}\n >\n <InsightStudentList\n students={props.students}\n imageCdnUrl={props.imageCdnUrl}\n imageUrl={props.imageUrl}\n description={getPhrase('studentsRequireMarking')}\n appLink={props.resultsAppLink}\n appLinkText={getPhrase('viewAll')}\n anonymiseUsers={props.anonymiseUsers}\n />\n </InsightCard>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { InsightCard } from 'libs/shared/apps/analytics/components/insight-card/InsightCard';\nimport { InsightStudentList } from 'libs/shared/apps/analytics/components/insight-student-list/InsightStudentList';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { User } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.insightNotCompletedStudents';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InsightNotCompletedStudentsProps {\n markingRequiredStudents: StudentResultsWithSummary[];\n completedStudents: StudentResultsWithSummary[];\n notCompletedStudents: StudentResultsWithSummary[];\n classroomStudents: User[];\n imageCdnUrl: string;\n imageUrl: string;\n resultsAppLink: Core.AppLink;\n anonymiseUsers: boolean;\n}\n\nexport function InsightNotCompletedStudents(props: InsightNotCompletedStudentsProps) {\n const notCompletedStudents = getNotCompletedStudents();\n\n function getNotCompletedStudents() {\n const markingRequiredStudentIds = props.markingRequiredStudents.map(student => student?.user.id);\n const completedStudentIds = props.completedStudents.map(student => student?.user.id);\n\n const notStartedStudents = props.classroomStudents.filter(student => {\n return !markingRequiredStudentIds.includes(student.id) &&\n !completedStudentIds.includes(student.id);\n });\n\n return ArrayHelper.uniq([\n ...props.notCompletedStudents.map(student => student.user),\n ...notStartedStudents\n ], 'id');\n }\n\n return (\n <InsightCard\n title={getPhrase('title')}\n svgName={cvSvgLibrary.Puzzle}\n svgClassName='bg-light-teal text-teal'\n count={notCompletedStudents.length}\n >\n <InsightStudentList\n students={notCompletedStudents}\n imageCdnUrl={props.imageCdnUrl}\n imageUrl={props.imageUrl}\n description={getPhrase('completed')}\n appLink={props.resultsAppLink}\n appLinkText={getPhrase('viewAll')}\n anonymiseUsers={props.anonymiseUsers}\n />\n </InsightCard>\n );\n}","import React from 'react';\n\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { InsightAverageAttempts } from 'libs/shared/apps/analytics/components/insights/average-attempts/InsightAverageAttempts';\nimport { InsightAverageScore } from 'libs/shared/apps/analytics/components/insights/average-score/InsightAverageScore';\nimport { InsightCompletedStudents } from 'libs/shared/apps/analytics/components/insights/completed-students/InsightCompletedStudents';\nimport { InsightDevices } from 'libs/shared/apps/analytics/components/insights/devices/InsightDevices';\nimport { InsightEasiestQuestion } from 'libs/shared/apps/analytics/components/insights/easiest-question/InsightEasiestQuestion';\nimport { InsightHardestQuestion } from 'libs/shared/apps/analytics/components/insights/hardest-question/InsightHardestQuestion';\nimport { InsightHeatmap } from 'libs/shared/apps/analytics/components/insights/heatmap/InsightHeatmap';\nimport { InsightHighScoringStudents } from 'libs/shared/apps/analytics/components/insights/high-scoring-students/InsightHighScoringStudents';\nimport { InsightLowScoringStudents } from 'libs/shared/apps/analytics/components/insights/low-scoring-students/InsightLowScoringStudents';\nimport { InsightMarkingRequired } from 'libs/shared/apps/analytics/components/insights/marking-required/InsightMarkingRequired';\nimport { InsightNotCompletedStudents } from 'libs/shared/apps/analytics/components/insights/not-completed-students/InsightNotCompletedStudents';\nimport { useFetchInteractiveResults } from 'libs/shared/apps/analytics/hooks/UseFetchInteractiveResults';\nimport { BaseAnalyticsEventResponse } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { AnalyticsFilterHelper } from 'libs/shared/apps/analytics/utils/AnalyticsFilterUtils';\nimport { getAudienceParams } from 'libs/shared/apps/analytics/utils/AudienceUtils';\nimport { getInsightsDateRangePresets, getStartEndParams } from 'libs/shared/apps/analytics/utils/DateRangeUtils';\nimport { groupStudents } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ScoreThresholdInsights } from 'libs/shared/constants/ScoreThresholds';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { InteractiveRequests } from 'libs/shared/flight-requests/InteractiveRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { VideoViewRequests } from 'libs/shared/flight-requests/VideoViewRequests';\nimport { BasePaginatedCollection, Classroom, Config, CurrentUser, Engagement, Interactive, InteractiveMetadata, User } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport { ClassroomRequests } from 'apps/classrooms/flight-requests/ClassroomRequests';\nimport { getInsightsInteractiveTabs } from 'apps/insights/utils/InsightsAppLinkUtils';\nimport { InsightsHeaderView } from 'apps/insights/views/header/InsightsHeaderView';\nimport { getInteractiveInsightsAppLinks } from 'apps/insights/views/interactive/overview/InteractiveInsightsOverviewUtils';\n\nconst namespace = 'insights.interactiveInsightsOverview';\n\ninterface InteractiveInsightsViewProps {\n interactiveId: string;\n classroomId?: string;\n}\n\nexport function InteractiveInsightsOverviewView(props: InteractiveInsightsViewProps) {\n const [anonymiseUsers] = useViewModel<boolean>(SharedViewModelKeys.ANONYMISE_USERS);\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const classroom = Flight.useBasicFetch<Classroom>(currentUser.data && props.classroomId &&\n ClassroomRequests.getClassroom(props.classroomId, currentUser.data.id));\n\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(\n InteractiveRequests.interactiveMetadata(props.interactiveId)\n );\n\n const interactive = Flight.useBasicFetch<Interactive>(interactiveMetadata.data?.interactiveId &&\n InteractiveRequests.interactive(interactiveMetadata.data.interactiveId));\n\n const audienceAppLinkParams = AnalyticsFilterHelper.getAudienceAppLinkParams();\n const dateRangeAppLinkParams = AnalyticsFilterHelper.getDateRangeAppLinkParams();\n const requestFilter = {\n ...getStartEndParams(getInsightsDateRangePresets(), dateRangeAppLinkParams),\n ...getAudienceParams(audienceAppLinkParams)\n };\n\n const results = useFetchInteractiveResults(props.interactiveId, requestFilter);\n\n const classroomFilterOnly =\n audienceAppLinkParams.classrooms?.length === 1 && !audienceAppLinkParams.classroomGroups?.length;\n const classroomStudents = Flight.useBasicFetch<BasePaginatedCollection<User>>(classroomFilterOnly &&\n ClassroomRequests.getClassroomStudents(ArrayHelper.first(audienceAppLinkParams.classrooms)));\n\n const aggregateEngagement = Flight.useBasicFetch<Engagement>(\n VideoViewRequests.aggregateEngagement(\n props.interactiveId,\n requestFilter,\n currentUser.data.id\n )\n );\n\n const videoViews = Flight.useBasicFetch<BaseAnalyticsEventResponse>(currentUser.data &&\n VideoViewRequests.views(requestFilter, props.interactiveId, currentUser.data.id));\n\n const hasDataLoaded =\n currentUser.data &&\n config.data &&\n (!props.classroomId || classroom.data) &&\n interactiveMetadata.data &&\n interactive.data &&\n results.data &&\n (!classroomFilterOnly || classroomStudents.data) &&\n aggregateEngagement.data &&\n videoViews.data;\n\n const studentGroups = hasDataLoaded && groupStudents(interactive.data, results.data, ScoreThresholdInsights);\n\n function getUsers(studentResult: StudentResultsWithSummary[]): User[] {\n return studentResult.map(student => student.user);\n }\n\n if (!hasDataLoaded) return <></>;\n const params = {\n ...audienceAppLinkParams,\n ...dateRangeAppLinkParams\n };\n const interactiveInsightsAppLinks = getInteractiveInsightsAppLinks(\n props.interactiveId\n );\n\n return (\n <div className='px-3'>\n <InsightsHeaderView\n video={interactiveMetadata.data}\n audienceAppLinkParams={audienceAppLinkParams}\n dateRangeAppLinkParams={dateRangeAppLinkParams}\n tabs={getInsightsInteractiveTabs(interactiveMetadata.data.id, 'overview', params)}\n />\n\n <section className='mb-5'>\n <h2 className='h4'>\n <Text namespace={namespace} phrase='studentResponses' />\n <span>: {studentGroups.completed.length}{classroomStudents.data ? `/${classroomStudents.data.data.length}` : ''}</span>\n </h2>\n\n <div className='row g-3'>\n <div className='col-12 col-md'>\n <InsightMarkingRequired\n imageUrl={ImageUrls.Insights.SPEECH_BUBBLE_ASTERISK}\n resultsAppLink={interactiveInsightsAppLinks.resultsAppLink}\n imageCdnUrl={config.data.imageCdnUrl}\n students={getUsers(studentGroups.markingRequired)}\n anonymiseUsers={anonymiseUsers}\n />\n </div>\n\n {classroomFilterOnly && (\n <div className='col-12 col-md'>\n <InsightNotCompletedStudents\n markingRequiredStudents={studentGroups.markingRequired}\n completedStudents={studentGroups.completed}\n notCompletedStudents={studentGroups.notCompleted}\n classroomStudents={classroomStudents.data.data}\n imageCdnUrl={config.data.imageCdnUrl}\n imageUrl={ImageUrls.Insights.JIGSAW}\n resultsAppLink={interactiveInsightsAppLinks.resultsAppLink}\n anonymiseUsers={anonymiseUsers}\n />\n </div>\n )}\n\n <div className='col-12 col-md'>\n <InsightCompletedStudents\n students={studentGroups.completed}\n imageCdnUrl={config.data.imageCdnUrl}\n imageUrl={ImageUrls.Insights.AVATAR}\n resultsAppLink={interactiveInsightsAppLinks.resultsAppLink}\n anonymiseUsers={anonymiseUsers}\n />\n </div>\n </div>\n </section>\n\n <section className='mb-5'>\n <h2 className='h4'>\n <Text namespace={namespace} phrase='studentsPerformance' />\n </h2>\n\n <div className='row g-3'>\n <div className='col-12 col-md-6'>\n <InsightLowScoringStudents\n redChartImageUrl={ImageUrls.Insights.RED_CHART}\n heartImageUrl={ImageUrls.Insights.SPEECH_BUBBLE_HEART}\n resultsAppLink={interactiveInsightsAppLinks.resultsAppLink}\n imageCdnUrl={config.data.imageCdnUrl}\n students={studentGroups.lowScore}\n completed={studentGroups.completed}\n anonymiseUsers={anonymiseUsers}\n />\n </div>\n <div className='col-12 col-md-6'>\n <InsightHighScoringStudents\n greenChartImageUrl={ImageUrls.Insights.GREEN_CHART}\n resultsAppLink={interactiveInsightsAppLinks.resultsAppLink}\n imageCdnUrl={config.data.imageCdnUrl}\n students={studentGroups.highScore}\n completed={studentGroups.completed}\n anonymiseUsers={anonymiseUsers}\n />\n </div>\n <div className='col-12 col-md-6'>\n <InsightHardestQuestion\n interactive={interactive.data}\n interactiveMetadata={interactiveMetadata.data}\n results={results.data}\n questionsAppLink={interactiveInsightsAppLinks.questionsAppLink}\n />\n </div>\n <div className='col-12 col-md-6'>\n <InsightEasiestQuestion\n interactive={interactive.data}\n interactiveMetadata={interactiveMetadata.data}\n results={results.data}\n questionsAppLink={interactiveInsightsAppLinks.questionsAppLink}\n />\n </div>\n </div>\n </section>\n\n <section className='mb-5'>\n <h2 className='h4'>\n <Text namespace={namespace} phrase='classPerformance' />\n </h2>\n\n <div className='row g-3'>\n <div className='col-12 col-md-6'>\n <InsightAverageScore\n students={studentGroups.completed}\n />\n </div>\n <div className='col-12 col-md-6'>\n <InsightAverageAttempts\n students={studentGroups.completed}\n />\n </div>\n <div className='col-12 col-md-6'>\n <InsightDevices\n osCount={videoViews.data?.osCount}\n />\n </div>\n <div className='col-12 col-md-6'>\n <InsightHeatmap\n engagement={aggregateEngagement.data}\n heatmapAppLink={interactiveInsightsAppLinks.heatmapAppLink}\n />\n </div>\n </div>\n </section>\n </div>\n );\n}","import { HashObject } from 'libs/common/react/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nexport function getInteractiveInsightsAppLinks(id: string, params?: HashObject) {\n return {\n resultsAppLink: {\n application: AppChannels.INSIGHTS,\n action: Actions.Insights.INTERACTIVE_RESULTS,\n args: [id],\n params\n },\n questionsAppLink: {\n application: AppChannels.INSIGHTS,\n action: Actions.Insights.INTERACTIVE_QUESTIONS,\n args: [id],\n params\n },\n heatmapAppLink: {\n application: AppChannels.INSIGHTS,\n action: Actions.Insights.INTERACTIVE_HEATMAP,\n args: [id],\n params\n }\n };\n}","// extracted by mini-css-extract-plugin\nexport default {\"removeRecipient\":\"mCbMC\",\"recipientItem\":\"kdcb0\",\"showSpinner\":\"xH6Mu\",\"avatarContainer\":\"Zcpg3\",\"recipientDetails\":\"v5EmV\",\"recipientDetailsWithRemoveButton\":\"_V928\"};"],"names":["namespace","ZERO_COLOUR","COLOUR_SCALE","LEGEND_VALUES","getBackgroundColor","value","max","hex","getGradient","data","gradient","i","length","previousValue","currentValue","nextValue","push","join","EngagementHeatMapLegend","Math","legendSquareWidthPercentage","className","Text","phrase","map","val","idx","key","style","width","backgroundColor","EngagementHeatMap","props","heatMap","engagement","background","InsightCard","svgClassName","SvgContainer","svgName","title","subtitle","count","children","getStaticChartOptions","label","text","credits","enabled","yAxis","labels","gridLineWidth","min","tickAmount","xAxis","color","fontSize","lineWidth","legend","chart","type","height","spacingTop","plotOptions","column","dataLabels","enableMouseTracking","minPointLength","InsightChart","highcharts","options","chartData","staticChartOptions","categories","series","MAX_ITEMS","InsightStudentList","students","slice","student","index","UserRecipientItemMetadata","user","imageCdnUrl","avatarClassName","detailsClassName","showDisplayName","showSubText","anonymiseUsers","undefined","percentage","round","PercentageIndicator","src","imageUrl","dangerouslySetInnerHTML","__html","description","AppLink","appLink","appLinkText","getPhrase","LanguageService","getDeviceType","name","InsightDevices","categoriesData","defaultDevices","Phone","Computer","osCount","reduce","acc","group","deviceCategory","getCategoriesData","highestDeviceCount","ArrayHelper","getHighestDeviceCount","Object","keys","borderRadius","fontWeight","inside","overflow","crop","category","y","filter","device","toLowerCase","InsightHeatmap","engagementRate","heatmapAppLink","getInteractiveResultFilters","currentUser","currentUserId","id","currentCustomerId","customerId","dateRange","start","end","userIds","userId","classroomsAndGroups","groupId","InteractiveResultsRequests","interactiveResultSet","interactiveId","interactiveMetadataId","success","error","always","url","normalize","mark","answerId","resultId","invalidationKeys","pendingReviews","interactiveResultsReport","useFetchInteractiveResults","requestFilter","interactiveMetadata","interactive","shouldFetchResults","I","getFullHeatMap","Array","ceil","videoDuration","fill","t","groupStudents","results","scoreThreshold","groups","markingRequired","lowScore","highScore","completed","notCompleted","numInteractions","forEach","s","withSummary","summary","getStudentResultsSummary","awaitingMarking","attempts","percentCorrect","HIGH","MODERATE","sortedLowScore","sortedHighScore","getInteractionById","interactionId","find","toString","getMarkedAnswerId","answer","questionId","getMarkedStatus","studentResults","markedAnswers","result","studentResponse","answers","every","a","status","getInteractionResultsSummary","interaction","numStudents","numCorrect","answered","unanswered","correctness","correct","interactions","interactionIds","Set","answeredInteractions","has","avatar","initials","surname","getSubText","userType","role","yearGroup","defaults","InteractionCorrectness","InteractiveAnswerStatus","VideoViewRequests","individualEngagement","objectId","sharerId","queryParams","formatData","d","aggregateEngagement","views","baseKey","timeOffset","notApplicable","isMissingWordCorrect","getStudentAnswer","items","actionableItems","isCorrect","trim","isMultipleChoiceCorrect","studentAnswer","getGetStudentAnswer","attempt","wrapIsMultipleChoiceCorrect","wrapIsMarkableAnswerMarkedCorrect","item","isMarkableAnswerMarkedCorrect","IsCorrectLookup","InteractiveCorrectnessHelper","isInteractionCorrect","isCorrectFn","typeId","interactionRequiresAnswer","flattenInteractions","timepoints","getStudentResult","getStudentAttempt","getInteractions","InsightAverageAttempts","noAttempts","averageAttempts","attemptsCategory","assign","smartCount","InsightAverageScore","averageScores","averagePercentage","b","totalQuestions","averageScore","toFixed","scoreCount","scorePercentageData","floor","PERCENTAGES","score","percentageCategory","Number","getChartColour","InsightCompletedStudents","resultsAppLink","InsightEasiestQuestion","easiestQuestion","resultsSummary","sortedInteractions","layout","InteractionLabel","iconClassName","questionsAppLink","params","sortBy","InsightHardestQuestion","hardestQuestion","InsightHighScoringStudents","greenChartImageUrl","InsightLowScoringStudents","heartImageUrl","redChartImageUrl","InsightMarkingRequired","InsightNotCompletedStudents","markingRequiredStudentIds","completedStudentIds","notStartedStudents","notCompletedStudents","markingRequiredStudents","completedStudents","classroomStudents","includes","InteractiveInsightsOverviewView","SharedViewModelKeys","UserRequests","config","ConfigRequests","classroom","classroomId","ClassroomRequests","InteractiveRequests","audienceAppLinkParams","dateRangeAppLinkParams","classroomFilterOnly","classrooms","classroomGroups","videoViews","hasDataLoaded","studentGroups","studentResult","interactiveInsightsAppLinks","application","action","args","getInteractiveInsightsAppLinks","InsightsHeaderView","video","tabs","ImageUrls"],"sourceRoot":""}