@clickview/lite 0.82.2 → 0.83.0-rc.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 (143) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/languages/en.json +1 -1
  3. package/dist/scripts/1074-fdce06d863-lite.chunk.js +2 -0
  4. package/dist/scripts/1074-fdce06d863-lite.chunk.js.map +1 -0
  5. package/dist/scripts/{1199-da55d69853-lite.chunk.js → 1199-01cc084886-lite.chunk.js} +1 -1
  6. package/dist/scripts/{1199-da55d69853-lite.chunk.js.map → 1199-01cc084886-lite.chunk.js.map} +1 -1
  7. package/dist/scripts/{2664-87c8cbfa7f-lite.chunk.js → 2664-907153c03b-lite.chunk.js} +2 -2
  8. package/dist/scripts/2664-907153c03b-lite.chunk.js.map +1 -0
  9. package/dist/scripts/2970-024b1dd55d-lite.chunk.js +2 -0
  10. package/dist/scripts/2970-024b1dd55d-lite.chunk.js.map +1 -0
  11. package/dist/scripts/{8133-ffcff3b7fc-lite.chunk.js → 3392-f7f8cb65e5-lite.chunk.js} +3 -3
  12. package/dist/scripts/3392-f7f8cb65e5-lite.chunk.js.map +1 -0
  13. package/dist/scripts/3840-59e5e53cda-lite.chunk.js +2 -0
  14. package/dist/scripts/3840-59e5e53cda-lite.chunk.js.map +1 -0
  15. package/dist/scripts/{4177-285ddf9ae3-lite.chunk.js → 4177-2d876c7b14-lite.chunk.js} +2 -2
  16. package/dist/scripts/4177-2d876c7b14-lite.chunk.js.map +1 -0
  17. package/dist/scripts/{1336-1826f6e582-lite.chunk.js → 4208-0706461da6-lite.chunk.js} +2 -2
  18. package/dist/scripts/4208-0706461da6-lite.chunk.js.map +1 -0
  19. package/dist/scripts/{4578-7578bcf17a-lite.chunk.js → 4578-27028d26eb-lite.chunk.js} +2 -2
  20. package/dist/scripts/4578-27028d26eb-lite.chunk.js.map +1 -0
  21. package/dist/scripts/4598-8f5266e4c2-lite.chunk.js +2 -0
  22. package/dist/scripts/4598-8f5266e4c2-lite.chunk.js.map +1 -0
  23. package/dist/scripts/{4621-1f79d94416-lite.chunk.js → 4621-7fb0a05bcb-lite.chunk.js} +2 -2
  24. package/dist/scripts/4621-7fb0a05bcb-lite.chunk.js.map +1 -0
  25. package/dist/scripts/4806-a6f31d703c-lite.chunk.js +2 -0
  26. package/dist/scripts/4806-a6f31d703c-lite.chunk.js.map +1 -0
  27. package/dist/scripts/{4948-de1c75e7fb-lite.chunk.js → 4948-ba684e5f4f-lite.chunk.js} +1 -1
  28. package/dist/scripts/{4948-de1c75e7fb-lite.chunk.js.map → 4948-ba684e5f4f-lite.chunk.js.map} +1 -1
  29. package/dist/scripts/4985-7e02d5df40-lite.chunk.js +2 -0
  30. package/dist/scripts/4985-7e02d5df40-lite.chunk.js.map +1 -0
  31. package/dist/scripts/{5554-17bb3b86fc-lite.chunk.js → 5554-f1f3baf822-lite.chunk.js} +2 -2
  32. package/dist/scripts/5554-f1f3baf822-lite.chunk.js.map +1 -0
  33. package/dist/scripts/5712-7cee70c6b4-lite.chunk.js +2 -0
  34. package/dist/scripts/5712-7cee70c6b4-lite.chunk.js.map +1 -0
  35. package/dist/scripts/6550-d99e0ed75d-lite.chunk.js +2 -0
  36. package/dist/scripts/6550-d99e0ed75d-lite.chunk.js.map +1 -0
  37. package/dist/scripts/{6909-a9b8930e37-lite.chunk.js → 6909-ba75701156-lite.chunk.js} +2 -2
  38. package/dist/scripts/6909-ba75701156-lite.chunk.js.map +1 -0
  39. package/dist/scripts/7148-1ced1b5dce-lite.chunk.js +2 -0
  40. package/dist/scripts/7148-1ced1b5dce-lite.chunk.js.map +1 -0
  41. package/dist/scripts/7568-55e9b01367-lite.chunk.js +3 -0
  42. package/dist/scripts/7568-55e9b01367-lite.chunk.js.map +1 -0
  43. package/dist/scripts/{7617-9d34c841e6-lite.chunk.js → 7617-211f084b70-lite.chunk.js} +2 -2
  44. package/dist/scripts/7617-211f084b70-lite.chunk.js.map +1 -0
  45. package/dist/scripts/7742-514844bd1a-lite.chunk.js +2 -0
  46. package/dist/scripts/7742-514844bd1a-lite.chunk.js.map +1 -0
  47. package/dist/scripts/7843-cbebf1a786-lite.chunk.js +2 -0
  48. package/dist/scripts/7843-cbebf1a786-lite.chunk.js.map +1 -0
  49. package/dist/scripts/8077-870bd8e245-lite.chunk.js +3 -0
  50. package/dist/scripts/8077-870bd8e245-lite.chunk.js.map +1 -0
  51. package/dist/scripts/843-4dbc5df109-lite.chunk.js +3 -0
  52. package/dist/scripts/843-4dbc5df109-lite.chunk.js.LICENSE.txt +1 -0
  53. package/dist/scripts/843-4dbc5df109-lite.chunk.js.map +1 -0
  54. package/dist/scripts/8735-e74a148502-lite.chunk.js +2 -0
  55. package/dist/scripts/8735-e74a148502-lite.chunk.js.map +1 -0
  56. package/dist/scripts/8856-2d332952ae-lite.chunk.js +2 -0
  57. package/dist/scripts/8856-2d332952ae-lite.chunk.js.map +1 -0
  58. package/dist/scripts/904-2784e45cfc-lite.chunk.js +2 -0
  59. package/dist/scripts/904-2784e45cfc-lite.chunk.js.map +1 -0
  60. package/dist/scripts/{9042-fdc5ecb459-lite.chunk.js → 9042-fd7e79b891-lite.chunk.js} +1 -1
  61. package/dist/scripts/{9042-fdc5ecb459-lite.chunk.js.map → 9042-fd7e79b891-lite.chunk.js.map} +1 -1
  62. package/dist/scripts/9295-eb130a0b17-lite.chunk.js +2 -0
  63. package/dist/scripts/9295-eb130a0b17-lite.chunk.js.map +1 -0
  64. package/dist/scripts/9528-4e954d9dff-lite.chunk.js +2 -0
  65. package/dist/scripts/9528-4e954d9dff-lite.chunk.js.map +1 -0
  66. package/dist/scripts/{9742-5f99d74bb0-lite.chunk.js → 9742-3f6b75484a-lite.chunk.js} +2 -2
  67. package/dist/scripts/9742-3f6b75484a-lite.chunk.js.map +1 -0
  68. package/dist/scripts/979-6a70a0e616-lite.chunk.js +2 -0
  69. package/dist/scripts/979-6a70a0e616-lite.chunk.js.map +1 -0
  70. package/dist/scripts/{3612-8c6423bd51-lite.chunk.js → 9911-8892b6dbfe-lite.chunk.js} +2 -2
  71. package/dist/scripts/{3612-8c6423bd51-lite.chunk.js.map → 9911-8892b6dbfe-lite.chunk.js.map} +1 -1
  72. package/dist/scripts/bundle-f926852f33.min.js +3 -0
  73. package/dist/scripts/{bundle-9a3e49399a.min.js.map → bundle-f926852f33.min.js.map} +1 -1
  74. package/package.json +1 -1
  75. package/dist/css/2074-lite-ac8da6c78b.chunk.css +0 -4
  76. package/dist/scripts/1202-d96ad80884-lite.chunk.js +0 -2
  77. package/dist/scripts/1202-d96ad80884-lite.chunk.js.map +0 -1
  78. package/dist/scripts/1336-1826f6e582-lite.chunk.js.map +0 -1
  79. package/dist/scripts/2074-39b86b9a22-lite.chunk.js +0 -2
  80. package/dist/scripts/2074-39b86b9a22-lite.chunk.js.map +0 -1
  81. package/dist/scripts/2664-87c8cbfa7f-lite.chunk.js.map +0 -1
  82. package/dist/scripts/2888-2596e106a5-lite.chunk.js +0 -2
  83. package/dist/scripts/2888-2596e106a5-lite.chunk.js.map +0 -1
  84. package/dist/scripts/289-669c0c8222-lite.chunk.js +0 -2
  85. package/dist/scripts/289-669c0c8222-lite.chunk.js.map +0 -1
  86. package/dist/scripts/3840-98c79fc0d8-lite.chunk.js +0 -2
  87. package/dist/scripts/3840-98c79fc0d8-lite.chunk.js.map +0 -1
  88. package/dist/scripts/3893-2856933742-lite.chunk.js +0 -2
  89. package/dist/scripts/3893-2856933742-lite.chunk.js.map +0 -1
  90. package/dist/scripts/4006-9dfe9cec1b-lite.chunk.js +0 -3
  91. package/dist/scripts/4006-9dfe9cec1b-lite.chunk.js.map +0 -1
  92. package/dist/scripts/4177-285ddf9ae3-lite.chunk.js.map +0 -1
  93. package/dist/scripts/4578-7578bcf17a-lite.chunk.js.map +0 -1
  94. package/dist/scripts/4621-1f79d94416-lite.chunk.js.map +0 -1
  95. package/dist/scripts/4806-f36469abb7-lite.chunk.js +0 -2
  96. package/dist/scripts/4806-f36469abb7-lite.chunk.js.map +0 -1
  97. package/dist/scripts/4985-bdfa839f8f-lite.chunk.js +0 -2
  98. package/dist/scripts/4985-bdfa839f8f-lite.chunk.js.map +0 -1
  99. package/dist/scripts/5554-17bb3b86fc-lite.chunk.js.map +0 -1
  100. package/dist/scripts/5579-a9c152057f-lite.chunk.js +0 -2
  101. package/dist/scripts/5579-a9c152057f-lite.chunk.js.map +0 -1
  102. package/dist/scripts/5712-e784cfe89c-lite.chunk.js +0 -2
  103. package/dist/scripts/5712-e784cfe89c-lite.chunk.js.map +0 -1
  104. package/dist/scripts/6070-a390fdce21-lite.chunk.js +0 -2
  105. package/dist/scripts/6070-a390fdce21-lite.chunk.js.map +0 -1
  106. package/dist/scripts/6909-a9b8930e37-lite.chunk.js.map +0 -1
  107. package/dist/scripts/7401-98135f09e8-lite.chunk.js +0 -2
  108. package/dist/scripts/7401-98135f09e8-lite.chunk.js.map +0 -1
  109. package/dist/scripts/7617-9d34c841e6-lite.chunk.js.map +0 -1
  110. package/dist/scripts/7742-342db3ce4f-lite.chunk.js +0 -2
  111. package/dist/scripts/7742-342db3ce4f-lite.chunk.js.map +0 -1
  112. package/dist/scripts/7843-f6033528ce-lite.chunk.js +0 -2
  113. package/dist/scripts/7843-f6033528ce-lite.chunk.js.map +0 -1
  114. package/dist/scripts/787-dcb3a0a26c-lite.chunk.js +0 -2
  115. package/dist/scripts/787-dcb3a0a26c-lite.chunk.js.map +0 -1
  116. package/dist/scripts/8077-9fdb522d7e-lite.chunk.js +0 -2
  117. package/dist/scripts/8077-9fdb522d7e-lite.chunk.js.map +0 -1
  118. package/dist/scripts/8133-ffcff3b7fc-lite.chunk.js.map +0 -1
  119. package/dist/scripts/8364-ff63447d36-lite.chunk.js +0 -3
  120. package/dist/scripts/8364-ff63447d36-lite.chunk.js.map +0 -1
  121. package/dist/scripts/8672-6967ce8a23-lite.chunk.js +0 -2
  122. package/dist/scripts/8672-6967ce8a23-lite.chunk.js.map +0 -1
  123. package/dist/scripts/9295-4242401e60-lite.chunk.js +0 -2
  124. package/dist/scripts/9295-4242401e60-lite.chunk.js.map +0 -1
  125. package/dist/scripts/9742-5f99d74bb0-lite.chunk.js.map +0 -1
  126. package/dist/scripts/979-4b893e5603-lite.chunk.js +0 -2
  127. package/dist/scripts/979-4b893e5603-lite.chunk.js.map +0 -1
  128. package/dist/scripts/9911-9272b96e46-lite.chunk.js +0 -2
  129. package/dist/scripts/9911-9272b96e46-lite.chunk.js.map +0 -1
  130. package/dist/scripts/bundle-9a3e49399a.min.js +0 -3
  131. /package/dist/css/{787-lite-5a317efacd.chunk.css → 2970-lite-5a317efacd.chunk.css} +0 -0
  132. /package/dist/css/{6070-lite-45dc286aab.chunk.css → 6550-lite-45dc286aab.chunk.css} +0 -0
  133. /package/dist/css/{2888-lite-856c02f000.chunk.css → 7148-lite-856c02f000.chunk.css} +0 -0
  134. /package/dist/css/{8364-lite-db31e36b79.chunk.css → 843-lite-db31e36b79.chunk.css} +0 -0
  135. /package/dist/css/{9911-lite-856c02f000.chunk.css → 8735-lite-856c02f000.chunk.css} +0 -0
  136. /package/dist/css/{5579-lite-f8e496136d.chunk.css → 8856-lite-f8e496136d.chunk.css} +0 -0
  137. /package/dist/css/{289-lite-2435a34b13.chunk.css → 904-lite-2435a34b13.chunk.css} +0 -0
  138. /package/dist/css/{1202-lite-4a892bdbf2.chunk.css → 9528-lite-4a892bdbf2.chunk.css} +0 -0
  139. /package/dist/css/{3612-lite-2b4142796a.chunk.css → 9911-lite-2b4142796a.chunk.css} +0 -0
  140. /package/dist/scripts/{4006-9dfe9cec1b-lite.chunk.js.LICENSE.txt → 3392-f7f8cb65e5-lite.chunk.js.LICENSE.txt} +0 -0
  141. /package/dist/scripts/{8133-ffcff3b7fc-lite.chunk.js.LICENSE.txt → 7568-55e9b01367-lite.chunk.js.LICENSE.txt} +0 -0
  142. /package/dist/scripts/{8364-ff63447d36-lite.chunk.js.LICENSE.txt → 8077-870bd8e245-lite.chunk.js.LICENSE.txt} +0 -0
  143. /package/dist/scripts/{bundle-9a3e49399a.min.js.LICENSE.txt → bundle-f926852f33.min.js.LICENSE.txt} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clickview/lite",
3
- "version": "0.82.2",
3
+ "version": "0.83.0-rc.0",
4
4
  "description": "ClickView Lite",
5
5
  "main": "dist/scripts/bundle.js",
6
6
  "types": "dist/projects/lite/src/index.d.ts",
@@ -1,4 +0,0 @@
1
- .Hdi6o{border-radius:.6rem}.Hdi6o .RvNxr{border-radius:0}.Hdi6o .RvNxr:first-child{border-top-left-radius:.6rem;border-bottom-left-radius:.6rem}.Hdi6o .RvNxr:last-child{border-top-right-radius:.6rem;border-bottom-right-radius:.6rem}.Hdi6o .RvNxr:not(:first-child){border-left:none}.Hdi6o .RvNxr:not(:last-child){border-right:none}.Hdi6o .RvNxr.GHSz9{min-width:7rem}.Hdi6o.VhJJa{border-radius:.375rem}.Hdi6o.VhJJa li:first-child{border-top-left-radius:.375rem;border-bottom-left-radius:.375rem}.Hdi6o.VhJJa li:last-child{border-top-right-radius:.375rem;border-bottom-right-radius:.375rem}.Hdi6o .WFyvo{padding-top:.53125rem;padding-bottom:.53125rem}
2
- .sybF_{width:.5625rem;height:.5625rem;border-radius:50%}.CXqJF{min-height:2rem}
3
- .dW1Zw{max-width:17.1875rem}.WfiUS{max-width:14.4375rem}
4
- .ZSzT3>:not(:first-child):before{display:inline-block;content:"•";padding:0 .5rem}
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[1202],{38307:(e,t,n)=>{n.d(t,{c:()=>y,l:()=>g});var r=n(32735),a=n(232),i=n.n(a),o=n(8604),c=n(83345);const s={heatMap:"epapa",legend:"uhH4p"};function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var u="shared.engagementHeatMap",d="#f1f1f1",m=i().scale(["#daf07d","#08bd1a"]),v=[0,.01,.25,.5,.75,1];function f(e,t){return e?m(e/t).hex():d}function p(e,t){for(var n=[],r=0;r<e.length;r++){var a=r>0&&e[r-1],i=e[r],o=r<e.length-1&&e[r+1];i===a&&i===o||n.push("".concat(f(i,t)," ").concat(100/e.length*r,"%"))}return"linear-gradient(to right, ".concat(n.join(","),")")}function g(){var e=Math.max.apply(Math,v),t=100/v.length;return r.createElement("div",{className:"d-flex justify-content-between w-100"},r.createElement(c.x,{namespace:u,phrase:"less"}),r.createElement("div",{className:"d-flex mx-1 flex-grow-1 ".concat(s.legend)},v.map(function(n,a){return r.createElement("div",{key:a,style:{width:"".concat(t,"%"),backgroundColor:f(n,e)}})})),r.createElement(c.x,{namespace:u,phrase:"more"}))}function y(e){var t,n,a,i=(0,o.O)(e.engagement),c=null!==(t=e.max)&&void 0!==t?t:Math.max.apply(Math,function(e){if(Array.isArray(e))return l(e)}(a=i)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(a)||function(e,t){if(e){if("string"==typeof e)return l(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)?l(e,t):void 0}}(a)||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 r.createElement("div",{className:"border rounded ".concat(s.heatMap," ").concat(null!==(n=e.className)&&void 0!==n?n:""),style:{background:p(i,c)}})}},84621:(e,t,n)=>{n.d(t,{L:()=>o});var r=n(32735),a=n(83914);const i={icon:"sAmpy",count:"faDs4"};function o(e){return r.createElement("section",{className:"d-flex flex-column border rounded p-3 h-100"},r.createElement("div",{className:"d-flex ".concat(e.subtitle?"align-items-top":"align-items-center"," mb-2")},r.createElement("div",{className:"".concat(i.icon," ").concat(e.svgClassName," rounded-circle d-flex justify-content-center align-items-center")},r.createElement(a.x,{svgName:e.svgName,size:a.S.Small})),r.createElement("div",{className:"d-flex flex-column ms-2"},r.createElement("h2",{className:"h6 mb-0"},e.title)),"number"==typeof e.count&&r.createElement("div",{className:"".concat(i.count," d-flex justify-content-center align-items-center bg-light rounded-circle ms-auto")},e.count)),e.children)}},70072:(e,t,n)=>{n.d(t,{d:()=>r});var r={fontSize:"12px",fontFamily:'"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"',fontWeight:"400",color:"#313543"}},26136:(e,t,n)=>{n.d(t,{B:()=>c});var r=n(76198),a=n(23481),i=n(64818),o=a.T.encloseNamespace("shared.analyticsUtils");function c(e,t){return e?t?(0,r._8)((n=e.id,a=e.sessionId,c=+"".concat(n||function(e){if(!e)return 0;for(var t=0,n=0;n<e.length;n++)t=(t<<5)-t+e.charCodeAt(n),t|=0;return Math.abs(t)}(a)).concat(Math.floor((new Date).getMinutes()/5)),{dictionaries:[r.O9,r.yd],separator:" ",length:2,style:"capital",seed:c})):e.deleted?o("deleted"):i.l.getFullName(e)||o("anonUser"):o("anonUser");var n,a,c}},8604:(e,t,n)=>{function r(e){var t=e.videoDuration||0;return new Array(Math.ceil(t)).fill(null).map(function(t,n){return(null==e?void 0:e.heatMap[n])||0})}function a(e){return null==e?void 0:e.reduce(function(t,n){return t+n.engagementRate/e.length},0)}n.d(t,{O:()=>r,Q:()=>a})},39157:(e,t,n)=>{n.d(t,{HI:()=>m,R6:()=>l,Rt:()=>f,UU:()=>d,Zs:()=>u,nq:()=>v});var r=n(75896),a=n(94892),i=n(28972),o=n(8246),c=n(83140),s=n(80845);function l(e,t,n){var i={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},o=(0,s.Q)(e),c=new Set(o.map(function(e){return e.id}));t.students.forEach(function(t){var o=Object.assign(Object.assign({},t),{summary:f(e,t)});o.summary.awaitingMarking?i.markingRequired.push(o):r.m.last(t.results).attempts.filter(function(e){var t;return!!c.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)}).length===c.size?(i.completed.push(o),o.summary.percentCorrect>=((null==n?void 0:n.HIGH)||a.i.HIGH)&&i.highScore.push(o),o.summary.percentCorrect<((null==n?void 0:n.MODERATE)||a.i.MODERATE)&&i.lowScore.push(o)):i.notCompleted.push(o)});var l=r.m.sortBy(i.lowScore,function(e){return e.summary.percentCorrect}),u=r.m.sortBy(i.highScore,function(e){return-e.summary.percentCorrect});return Object.assign(Object.assign({},i),{lowScore:l,highScore:u})}function u(e,t){return(0,s.Wn)(e).find(function(e){return e.id.toString()===t.toString()})}function d(e){return"".concat(e.questionId,":").concat(e.resultId)}function m(e,t,n){var r=(0,s.j_)(t),a=(0,s.f6)(e,r);return(null==a?void 0:a.answers.every(function(e){var t;return(null===(t=n[d(e)])||void 0===t?void 0:t.status)===o.N.Correct}))?o.N.Correct:(null==a?void 0:a.answers.every(function(e){var t;return(null===(t=n[d(e)])||void 0===t?void 0:t.status)===o.N.Incorrect}))?o.N.Incorrect:void 0}function v(e,t){var n=t.students.length,r=0,a=0,o=0,l=0,u=0;return t.students.forEach(function(t){var n=(0,s.j_)(t);if(n){u+=t.results.length;var d=c.A.isInteractionCorrect(e,n);d===i.w.Correct&&r++,d===i.w.UnAnswered&&o++,d===i.w.AwaitingMarking&&l++,d!==i.w.UnAnswered&&a++}}),{percentCorrect:n>0?r/n:0,correct:r,answered:a,unanswered:o,awaitingMarking:l,attempts:u}}function f(e,t){var n=(0,s.j_)(t),r=(0,s.Q)(e),a=r.length,o=0,l=0;r.forEach(function(e){var t=c.A.isInteractionCorrect(e,n);t===i.w.Correct&&o++,t===i.w.AwaitingMarking&&l++});var u=a>0?o/a:0,d=new Set(r.map(function(e){return e.id})),m=n.attempts.filter(function(e){var t;return!!d.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)}).length;return{answered:m,attempts:t.results.length,unanswered:a-m,percentCorrect:u,correct:o,awaitingMarking:l}}},77640:(e,t,n)=>{n.d(t,{t:()=>f});var r=n(32735),a=n(23481),i=n(31453),o=n(26136),c=n(97408),s=n(83914),l=n(76881),u=n(86613),d=n(64818),m=n(26521),v=a.T.encloseNamespace("shared.userRecipientItemMetadata");function f(e){var t=function(e){var t,n=e.user,r=e.anonymiseUsers,a=e.showDisplayName;if(n.sessionId||n.deleted){var i=(0,o.B)(n,r),c=i.split(" ").filter(function(e){return!!e});return{name:i,surname:c.slice(1).join(" "),avatarUrl:null}}return{name:r?(0,o.B)(n,!0):a?d.l.getDisplayName(n):d.l.getFullName(n),surname:n.surname,avatarUrl:null===(t=n.avatar)||void 0===t?void 0:t.url}}(e),n=t.name,a=t.surname,f=t.avatarUrl;return r.createElement(r.Fragment,null,r.createElement("div",{className:"".concat(m.Z.avatarContainer," ").concat(e.avatarClassName," d-inline-block flex-shrink-0")},r.createElement(c.q,{imageUrl:f,imageCdnUrl:e.imageCdnUrl,initials:d.l.getInitials(n,a),showAnonymousUser:!(e.anonymiseUsers||!e.user.sessionId&&!e.user.deleted),anonymiseUsers:e.anonymiseUsers,anonymousSvgSize:s.S.Small})),r.createElement("div",{className:e.detailsClassName},r.createElement("h4",{className:(0,i.A)("font-size-normal fw-normal m-0",e.nameClassName)},n),e.showSubText&&"id"in e.user&&r.createElement("p",{className:"text-secondary m-0"},e.getSubText?e.getSubText(e.user):function(e){var t=d.l.getUserType(e),n=d.l.getUserRole(e);if(t===l.Y.Staff)return n===u.i.Admin?v("admin"):v("staff");var r=d.l.getYearGroup(e);return(null==r?void 0:r.name)&&"Learners"!==r.name?r.name:v("student")}(e.user))))}f.defaults={showSubText:!0}},40782:(e,t,n)=>{n.d(t,{I:()=>r,O:()=>s});var r,a=n(32735),i=n(2606),o=n(362);function c(e){var t=a.useCallback(function(t){if(t){var n=t.r.baseVal.value,r=2*Math.PI*n,a=r-e.percentage*r;t.style.strokeDasharray="".concat(r," ").concat(r),t.style.strokeDashoffset=a.toString()}},[e.percentage]);return a.createElement("svg",null,a.createElement("circle",{r:(0,i.pu)(e.size),className:o.Z.backgroundCircle}),!(0,i.zR)(e.percentage)&&a.createElement("circle",{ref:t,r:(0,i.pu)(e.size),className:(0,i.V4)(e.percentage,e.scoreThresholds)}))}function s(e){var t,n=(0,i.Ki)(e.percentage),s=e.size||(e.layout===r.LabelInside?i.Mk.Large:i.Mk.Small),l=e.customLabel||(0,i.DV)(n);return e.layout===r.LabelOnly?a.createElement("span",{className:(0,i.IA)(n)},l):a.createElement("div",{className:"d-flex align-items-center justify-content-between ".concat(null!==(t=e.className)&&void 0!==t?t:"")},e.layout===r.LabelBefore&&a.createElement("span",{className:"me-2"},l),a.createElement("div",{className:(0,i.tw)(s,n)},a.createElement(c,{percentage:n,size:s,scoreThresholds:e.scoreThresholds}),e.layout===r.LabelInside&&a.createElement("span",{className:o.Z.centredPercentageText},l)))}!function(e){e.CircleOnly="circle_only",e.LabelOnly="label_only",e.LabelBefore="label_before",e.LabelInside="label_inside"}(r||(r={})),s.defaultProps={layout:r.CircleOnly}},2606:(e,t,n)=>{n.d(t,{DV:()=>g,IA:()=>v,Ki:()=>p,Mk:()=>c,V4:()=>m,pu:()=>d,tw:()=>f,zR:()=>y});var r=n(94892),a=n(362);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 o(e,t,n){return(t=function(e){var t=function(e){if("object"!=i(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=i(n))return n;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}var c,s=.2,l=.36;!function(e){e.Small="small",e.Large="large",e.ExtraSmall="extraSmall"}(c||(c={}));var u=o(o(o({},c.ExtraSmall,{size:2}),c.Small,{size:2}),c.Large,{size:5.8});function d(e){var t=u[e].size,n=e===c.Large?l:s;return"".concat(t/2-2*n,"rem")}function m(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:r.i;return e>=t.HIGH?a.Z.circleSuccess:e>=t.MODERATE?a.Z.circleWarning:a.Z.circleDanger}function v(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:r.i;return e>=t.HIGH?"text-success":e>=t.MODERATE?"text-warning":"text-danger"}function f(e,t){var n="d-inline-block ".concat(a.Z.circleContainer);return e===c.Large&&(n+=" ".concat(a.Z.lgCircleContainer)),e===c.ExtraSmall&&(n+=" ".concat(a.Z.xsCircleContainer)),y(t)&&(n+=" ".concat(a.Z.pendingCircle)),n}function p(e){if(!y(e))return+e.toFixed(2)}function g(e){return y(e)?"--%":"".concat(Math.round(100*e),"%")}function y(e){return"number"!=typeof e}},94892:(e,t,n)=>{n.d(t,{T:()=>a,i:()=>r});var r={HIGH:.75,MODERATE:.5},a={HIGH:.7,MODERATE:.7}},28972:(e,t,n)=>{var r;n.d(t,{w:()=>r}),function(e){e[e.Correct=0]="Correct",e[e.Incorrect=1]="Incorrect",e[e.AwaitingMarking=2]="AwaitingMarking",e[e.Answered=3]="Answered",e[e.UnAnswered=4]="UnAnswered",e[e.NotApplicable=5]="NotApplicable"}(r||(r={}))},8246:(e,t,n)=>{var r;n.d(t,{N:()=>r}),function(e){e[e.Incorrect=0]="Incorrect",e[e.Correct=1]="Correct",e[e.PendingReview=2]="PendingReview"}(r||(r={}))},54405:(e,t,n)=>{n.d(t,{X:()=>r});var r={interactive:function(){return{url:"/mocks/insights/interactive.json",key:"demo:interactive",normalize:!1}},interactiveMetadata:function(){return{url:"/mocks/insights/interactive-metadata.json",key:"demo:interactive:metadata",normalize:!1}},interactiveResults:function(){return{url:"/mocks/insights/interactive-results.json",key:"demo:interactive:results",normalize:!1}},videoViews:function(){return{url:"/mocks/insights/video-views.json",key:"demo:video:views",normalize:!1}},users:function(){return{url:"/mocks/insights/users.json",key:"demo:users",normalize:!1}},individualHeatmap:function(){return{url:"/mocks/insights/individual-heatmap.json",key:"demo:individual:heatmap",normalize:!1}},aggregateHeatmap:function(){return{url:"/mocks/insights/aggregate-heatmap.json",key:"demo:aggregate:heatmap",normalize:!1}}}},83140:(e,t,n)=>{n.d(t,{A:()=>p});var r=n(28972),a=n(8246),i=n(56644);function o(e){return o="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},o(e)}function c(e,t,n){return(t=function(e){var t=function(e){if("object"!=o(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=o(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==o(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(){return r.w.NotApplicable}function l(e,t){var n=e.actionableItems.filter(function(e){return e.isCorrect});return n.every(function(e){return!t(e.id)})?r.w.UnAnswered:n.every(function(e){var n;return e.name.trim().toLowerCase()===(null===(n=t(e.id))||void 0===n?void 0:n.trim().toLowerCase())})?r.w.Correct:r.w.Incorrect}function u(e,t){return e.actionableItems.every(function(e){return!t(e.id)})?r.w.UnAnswered:e.actionableItems.filter(function(e){return e.isCorrect}).every(function(e){var n,r=t(e.id);return(null==r?void 0:r.toString())===(null===(n=e.id)||void 0===n?void 0:n.toString())||r===e.name})?r.w.Correct:r.w.Incorrect}function d(e,t){return function(n){var r=null==t?void 0:t.attempts.find(function(t){return t.id===e.id});return null==r?void 0:r.answers.find(function(e){return e.id===n})}}function m(e,t){var n=d(e,t);return u(e,function(e){var t=n(e);return null==t?void 0:t.text})}function v(e,t){return function(e,t){var n;return e.actionableItems.forEach(function(e){var i=t(e.id);n=i?i.status!==a.N.Correct?i.status!==a.N.Incorrect?r.w.AwaitingMarking:r.w.Incorrect:r.w.Correct:r.w.UnAnswered}),n}(e,d(e,t))}var f=c(c(c(c(c(c(c({},i.Z9.Annotation,s),i.Z9.Image,s),i.Z9.MissingWord,function(e,t){var n=d(e,t);return l(e,function(e){var t=n(e);return null==t?void 0:t.text})}),i.Z9.MultipleChoice,m),i.Z9.ShortAnswer,v),i.Z9.TrueOrFalse,m),i.Z9.Illustration,v),p={notApplicable:s,awaitingMarking:function(){return r.w.AwaitingMarking},isMissingWordCorrect:l,isMultipleChoiceCorrect:u,isInteractionCorrect:function(e,t){return(0,f[e.typeId])(e,t)}}},9566:(e,t,n)=>{n.d(t,{$Z:()=>p,G6:()=>m,GJ:()=>f,VE:()=>h,_w:()=>v,po:()=>y,vJ:()=>g});var r=n(23481),a=n(110),i=n(33518),o=n(2510),c=n(4594),s=n(35223),l=n(14070),u=n(97291),d=r.T.encloseNamespace("myShares.demoInsights"),m={type:o.y.Link,privacy:i.e.JustMySchool,objectId:"0",objectTypeId:c.E.Interactive,viewCount:28,accessCount:15,dateCreated:(new Date).toISOString(),dateShared:(new Date).toISOString(),expireDate:null,link:{shortenedEmbedUrl:"",shortenedUrl:""},shareId:"0",ownerCustomerId:0,ownerId:0,recipients:[],options:{preventScrubbing:!1,immediateFeedback:!1}},v=Object.assign(Object.assign({},m),{type:o.y.Open,expireDate:a.O.add(new Date(m.dateCreated),30,"days").toISOString(),privacy:i.e.PinCode}),f={share:m,sharedObject:null,shareRecipients:null,dateShared:a.O.subtract(new Date,7,"days").toISOString()},p=Object.assign(Object.assign({},f),{share:v}),g={application:u.O.MY_SHARES,action:l.e.MyShares.INTERACTIVE_OVERVIEW_DEMO},y={application:u.O.MY_SHARES,action:l.e.MyShares.INTERACTIVE_OVERVIEW_OPEN_CLASSROOM_DEMO},h={svgName:s.vn.Analytics,label:d("demoInsights"),appLink:g,group:"insights",className:"btn btn-outline-dark"}},38926:(e,t,n)=>{n.r(t),n.d(t,{InteractiveInsightsOverviewDemoView:()=>I});var r=n(32735),a=n(23481),i=n(2948),o=n(20354),c=n(26025),s=n(2510),l=n(38143),u=n(39151),d=n(54405),m=n(31949),v=n(93322),f=n(79612),p=n(74049),g=n(54948),y=n(9566),h=n(10447),S=n(14070),b=n(97291);function E(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var w=a.T.encloseNamespace("insights.interactiveInsightsOverviewView");function I(e){var t,n,a,I,A,C,M=(A=(0,i.D)(l.g.ANONYMISE_USERS),C=1,function(e){if(Array.isArray(e))return e}(A)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,i,o,c=[],s=!0,l=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;s=!1}else for(;!(s=(r=i.call(n)).done)&&(c.push(r.value),c.length!==t);s=!0);}catch(e){l=!0,a=e}finally{try{if(!s&&null!=n.return&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw a}}return c}}(A,C)||function(e,t){if(e){if("string"==typeof e)return E(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)?E(e,t):void 0}}(A,C)||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];(0,v.F)();var O=o.a.useBasicFetch(m.N.currentUser()),N=o.a.useBasicFetch(u.L.config()),k=o.a.useBasicFetch(d.X.interactiveMetadata()),R=o.a.useBasicFetch(d.X.interactive()),T=c.B.getAudienceAppLinkParams(),j=c.B.getDateRangeAppLinkParams(),_=o.a.useBasicFetch(d.X.interactiveResults()),x=o.a.useBasicFetch(d.X.aggregateHeatmap()),D=o.a.useBasicFetch(d.X.videoViews());(0,f.M)({title:k.data?w("pageTitle",{video:null===(t=k.data)||void 0===t?void 0:t.name}):null});var U=O.data&&N.data&&k.data&&R.data&&_.data&&x.data&&!!D.data,L=Object.assign(Object.assign({},T),j),H=function(e,t,n){return n===s.y.Open?{resultsAppLink:{application:b.O.MY_SHARES,action:S.e.MyShares.INTERACTIVE_STUDENTS_OPEN_CLASSROOM_DEMO,args:[e],params:t},questionsAppLink:{application:b.O.MY_SHARES,action:S.e.MyShares.INTERACTIVE_QUESTIONS_OPEN_CLASSROOM_DEMO,args:[e],params:t},heatmapAppLink:{application:b.O.MY_SHARES,action:S.e.MyShares.INTERACTIVE_HEATMAP_OPEN_CLASSROOM_DEMO,args:[e],params:t}}:{resultsAppLink:{application:b.O.MY_SHARES,action:S.e.MyShares.INTERACTIVE_STUDENTS_DEMO,args:[e],params:t},questionsAppLink:{application:b.O.MY_SHARES,action:S.e.MyShares.INTERACTIVE_QUESTIONS_DEMO,args:[e],params:t},heatmapAppLink:{application:b.O.MY_SHARES,action:S.e.MyShares.INTERACTIVE_HEATMAP_DEMO,args:[e],params:t}}}("",L,e.type),V=e.type===s.y.Open?y._w:y.G6;return U?r.createElement("div",{className:"px-3"},r.createElement(p.j,{video:k.data,tabs:(0,h.aq)(null===(n=k.data)||void 0===n?void 0:n.id,"insights",L,e.type),dateRangeAppLinkParams:j,share:Object.assign(Object.assign({},V),{objectId:null===(a=k.data)||void 0===a?void 0:a.id}),yearGroups:[],markingRequired:e.type!==s.y.Open,isDemo:!0,hasData:!0}),r.createElement(g.m,{aggregateEngagement:x.data,interactive:R.data,interactiveMetadata:k.data,classroomStudents:null,results:_.data,osCount:null===(I=D.data)||void 0===I?void 0:I.osCount,config:N.data,interactiveInsightsAppLinks:H,anonymiseUsers:M,hasDataLoaded:U,share:V})):r.createElement(r.Fragment,null)}},26521:(e,t,n)=>{n.d(t,{Z:()=>r});const r={removeRecipient:"mCbMC",recipientItem:"kdcb0",showSpinner:"xH6Mu",avatarContainer:"Zcpg3",recipientDetails:"v5EmV",recipientDetailsWithRemoveButton:"_V928"}},362:(e,t,n)=>{n.d(t,{Z:()=>r});const r={circleContainer:"p8Vgz",backgroundCircle:"asGGE",circleSuccess:"PXLNj",circleWarning:"ZckRN",circleDanger:"slBRg",lgCircleContainer:"N8KCI",xsCircleContainer:"RPqZ2",pendingCircle:"DKrcq",centredPercentageText:"tpmLR"}}}]);
2
- //# sourceMappingURL=1202-d96ad80884-lite.chunk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/1202-d96ad80884-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/constants/ChartStyles.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/AnonymiseUserUtils.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/components/percentage-indicator/PercentageIndicator.tsx","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicatorUtils.ts","file:///app/packages/libs/shared/src/constants/ScoreThresholds.ts","file:///app/packages/libs/shared/src/enums/InteractionCorrectness.ts","file:///app/packages/libs/shared/src/enums/InteractiveAnswerStatus.ts","file:///app/packages/libs/shared/src/flight-requests/InsightsDemoRequests.ts","file:///app/packages/libs/shared/src/utils/InteractiveCorrectnessHelper.ts","file:///app/packages/projects/lite/src/apps/my-shares/constants/MySharesDemoInsights.ts","file:///app/packages/projects/lite/src/apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoView.tsx","file:///app/packages/projects/lite/src/apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoUtils.ts","file:///app/packages/libs/shared/src/apps/share/components/recipient-item/recipient-item.scss","file:///app/packages/libs/shared/src/components/percentage-indicator/percentage-indicator.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, SvgContainerSize } 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 rounded p-3 h-100'>\n <div className={`d-flex ${props.subtitle ? 'align-items-top' : 'align-items-center'} mb-2`}>\n <div className={`${styles.icon} ${props.svgClassName} rounded-circle d-flex justify-content-center align-items-center`}>\n <SvgContainer svgName={props.svgName} size={SvgContainerSize.Small} />\n </div>\n <div className='d-flex flex-column ms-2'>\n <h2 className='h6 mb-0'>{props.title}</h2>\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}","export const CHART_FONT_STYLES = {\n fontSize: '12px',\n fontFamily: `\"Inter\",-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",\"Liberation Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\"`,\n fontWeight: '400',\n color: '#313543'\n};","import { animals, colors, Config as UniqueNamesConfig, uniqueNamesGenerator } from 'unique-names-generator';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnonUser } from 'libs/shared/interfaces/models/interactive-results/AnonUser';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nconst namespace = 'shared.analyticsUtils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction guidToSeed(guid: string): number {\n if (!guid)\n return 0;\n\n // Simple hash function (DJB2-like) for browsers\n let hash = 0;\n for (let i = 0; i < guid.length; i++) {\n const char = guid.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash |= 0; // Convert to 32bit integer\n }\n return Math.abs(hash);\n}\n\nfunction getUniqueNamesConfig(userId: string, sessionId: string): UniqueNamesConfig {\n /**\n * Generate a seed that is unique to each user but changes every 5 minutes.\n * \n * We use a seed so that if the same user's name is anonymised multiple times\n * in quick succession (e.g. multiple renders), the same name will be returned each time.\n * \n * We change the seed every 5 minutes so that students don't always have the same name.\n */\n const seed = +`${userId || guidToSeed(sessionId)}${Math.floor((new Date()).getMinutes() / 5)}`;\n\n return {\n dictionaries: [ colors, animals ],\n separator: ' ',\n length: 2,\n style: 'capital',\n seed\n };\n}\n\nexport function anonymiseUserName(user: AnonUser, shouldAnonymise: boolean): string {\n if (!user) {\n return getPhrase('anonUser');\n }\n\n if (!shouldAnonymise) {\n if (user.deleted)\n return getPhrase('deleted');\n\n return UserHelper.getFullName(user) || getPhrase('anonUser');\n }\n\n return uniqueNamesGenerator(getUniqueNamesConfig(user.id, user.sessionId));\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 const videoDuration = engagement.videoDuration || 0;\n \n return (new Array(Math.ceil(videoDuration))).fill(null).map((t, idx) => engagement?.heatMap[idx] || 0);\n}\n\nexport function getEngagementRate(engagement: Engagement[]): number {\n return engagement?.reduce((prev, next) => prev + next.engagementRate / engagement.length, 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 const interactionIds = new Set(interactions.map(i => i.id));\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 const result = ArrayHelper.last(s.results);\n const answeredInteractions = result.attempts.filter(a => !!interactionIds.has(a?.answers[0]?.questionId)).length;\n\n if (answeredInteractions === interactionIds.size) {\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: answeredInteractions,\n attempts: studentResults.results.length,\n unanswered: numInteractions - answeredInteractions,\n percentCorrect,\n correct: numCorrect,\n awaitingMarking\n };\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { anonymiseUserName } from 'libs/shared/apps/analytics/utils/AnonymiseUserUtils';\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { UserRole } from 'libs/shared/enums/UserRole';\nimport { BaseObject, User } from 'libs/shared/interfaces';\nimport { AnonUser } from 'libs/shared/interfaces/models/interactive-results/AnonUser';\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 /**\n * Tertiary puts all students into a single group called 'Learners'.\n * When a student is in the 'Learners' group, we don't want to display the group name,\n * but instead we want to just show \"Student\". - Sha\n */\n if (yearGroup?.name && yearGroup.name !== 'Learners')\n return yearGroup.name;\n\n return getPhrase('student');\n}\n\nfunction getUserProps({\n user, anonymiseUsers, showDisplayName\n}: {\n user: AnonUser,\n showDisplayName: boolean;\n anonymiseUsers?: boolean;\n}) {\n if (user.sessionId || user.deleted) {\n const anonName = anonymiseUserName(user, anonymiseUsers);\n const nameParts = anonName.split(' ').filter(n => !!n);\n\n return {\n name: anonName,\n surname: nameParts.slice(1).join(' '),\n avatarUrl: null\n };\n }\n\n return {\n name: anonymiseUsers\n ? anonymiseUserName(user, true)\n : showDisplayName\n ? UserHelper.getDisplayName(user)\n : UserHelper.getFullName(user),\n surname: user.surname,\n avatarUrl: user.avatar?.url\n };\n}\n\nUserRecipientItemMetadata.defaults = {\n showSubText: true\n};\n\ninterface UserRecipientItemMetadataProps {\n user: AnonUser;\n imageCdnUrl: string;\n detailsClassName?: string;\n avatarClassName?: string;\n showDisplayName: boolean;\n nameClassName?: string;\n showSubText?: boolean;\n anonymiseUsers?: boolean;\n getSubText?: (user: BaseObject) => string;\n}\n\nexport function UserRecipientItemMetadata(props: UserRecipientItemMetadataProps): JSX.Element {\n const { name, surname, avatarUrl } = getUserProps(props);\n\n return (\n <>\n <div className={`${styles.avatarContainer} ${props.avatarClassName} d-inline-block flex-shrink-0`}>\n <Avatar\n imageUrl={avatarUrl}\n imageCdnUrl={props.imageCdnUrl}\n initials={UserHelper.getInitials(name, surname)}\n showAnonymousUser={!props.anonymiseUsers && (!!props.user.sessionId || !!props.user.deleted)}\n anonymiseUsers={props.anonymiseUsers}\n anonymousSvgSize={SvgContainerSize.Small}\n />\n </div>\n\n <div className={props.detailsClassName}>\n <h4 className={classNames('font-size-normal fw-normal m-0', props.nameClassName)}>\n {name}\n </h4>\n {props.showSubText && `id` in props.user && <p className='text-secondary m-0'>{props.getSubText ? props.getSubText(props.user) : getSubText(props.user)}</p>}\n </div>\n </>\n );\n}","import React from 'react';\n\nimport { ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport {\n getCircleClassName,\n getCircleContainerClassName,\n getCircleRadius,\n getColouredLabelClassName,\n getFormattedPercentage,\n getPercentageToFixed,\n isPending,\n ProgressCircleSize\n} from './PercentageIndicatorUtils';\n\nimport styles from './percentage-indicator.scss';\n\ninterface ProgressCircleProps {\n size: ProgressCircleSize;\n scoreThresholds?: ScoreThresholds;\n percentage?: number;\n}\n\nfunction ProgressCircle(props: ProgressCircleProps): JSX.Element {\n const ref = React.useCallback((circle: SVGCircleElement) => {\n if (!circle)\n return;\n\n const radius = circle.r.baseVal.value;\n const circumference = 2 * Math.PI * radius;\n const offset = circumference - props.percentage * circumference;\n\n circle.style.strokeDasharray = `${circumference} ${circumference}`;\n circle.style.strokeDashoffset = offset.toString();\n }, [props.percentage]);\n\n return (\n <svg>\n <circle r={getCircleRadius(props.size)} className={styles.backgroundCircle} />\n {!isPending(props.percentage) &&\n <circle\n ref={ref}\n r={getCircleRadius(props.size)}\n className={getCircleClassName(props.percentage, props.scoreThresholds)}\n />\n }\n </svg>\n );\n}\n\nexport enum PercentageIndicatorLayout {\n CircleOnly = 'circle_only',\n LabelOnly = 'label_only',\n LabelBefore = 'label_before',\n LabelInside = 'label_inside'\n}\n\ninterface PercentageIndicatorProps {\n layout: PercentageIndicatorLayout;\n percentage?: number; // Between 0 and 1 or undefined for pending\n className?: string;\n customLabel?: string;\n scoreThresholds?: ScoreThresholds;\n size?: ProgressCircleSize;\n}\n\nPercentageIndicator.defaultProps = {\n layout: PercentageIndicatorLayout.CircleOnly\n};\n\nexport function PercentageIndicator(props: PercentageIndicatorProps): JSX.Element {\n const percentageToFixed = getPercentageToFixed(props.percentage);\n\n const size = props.size ||\n (props.layout === PercentageIndicatorLayout.LabelInside\n ? ProgressCircleSize.Large\n : ProgressCircleSize.Small\n );\n\n const label = props.customLabel || getFormattedPercentage(percentageToFixed);\n\n if (props.layout === PercentageIndicatorLayout.LabelOnly)\n return (\n <span className={getColouredLabelClassName(percentageToFixed)}>\n {label}\n </span>\n );\n\n return (\n <div className={`d-flex align-items-center justify-content-between ${props.className ?? ''}`}>\n {props.layout === PercentageIndicatorLayout.LabelBefore &&\n <span className='me-2'>\n {label}\n </span>\n }\n <div className={getCircleContainerClassName(size, percentageToFixed)}>\n <ProgressCircle percentage={percentageToFixed} size={size} scoreThresholds={props.scoreThresholds} />\n {props.layout === PercentageIndicatorLayout.LabelInside &&\n <span className={styles.centredPercentageText}>\n {label}\n </span>\n }\n </div>\n </div>\n );\n}","import { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport styles from './percentage-indicator.scss';\n\n/**\n * Values for width and strokeWidth are taken from progress-circle.scss.\n * If either are changed, they must be updated in both places.\n */\nconst CIRCLE_WIDTH = 2; // rem\nconst CIRCLE_WIDTH_LG = 5.8; // rem\nconst CIRCLE_STROKE_WIDTH = 0.2; // rem\nconst CIRCLE_STROKE_WIDTH_LG = 0.36; // rem\n \nexport enum ProgressCircleSize {\n Small = 'small',\n Large = 'large',\n ExtraSmall = 'extraSmall'\n}\n\nconst ProgressCircleSizeMap = {\n [ProgressCircleSize.ExtraSmall]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Small]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Large]: {\n size: CIRCLE_WIDTH_LG\n }\n};\n\n/**\n * radius = width / 2 - strokeWidth * 2\n */\nexport function getCircleRadius(size: ProgressCircleSize): string {\n const width = ProgressCircleSizeMap[size].size;\n const strokeWidth = size === ProgressCircleSize.Large ? CIRCLE_STROKE_WIDTH_LG : CIRCLE_STROKE_WIDTH;\n return `${width / 2 - strokeWidth * 2}rem`;\n}\n \nexport function getCircleClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return styles.circleSuccess;\n \n if (percentage >= scoreThresholds.MODERATE)\n return styles.circleWarning;\n \n return styles.circleDanger;\n}\n \nexport function getColouredLabelClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return 'text-success';\n \n if (percentage >= scoreThresholds.MODERATE)\n return 'text-warning';\n \n return 'text-danger';\n}\n \nexport function getCircleContainerClassName(size: ProgressCircleSize, percentage?: number): string {\n let className = `d-inline-block ${styles.circleContainer}`;\n \n if (size === ProgressCircleSize.Large)\n className += ` ${styles.lgCircleContainer}`;\n\n if (size === ProgressCircleSize.ExtraSmall)\n className += ` ${styles.xsCircleContainer}`;\n\n if (isPending(percentage))\n className += ` ${styles.pendingCircle}`;\n \n return className;\n}\n\nexport function getPercentageToFixed(percentage?: number): number | undefined {\n if (isPending(percentage))\n return;\n \n return +percentage.toFixed(2);\n}\n \nexport function getFormattedPercentage(percentage?: number): string {\n if (isPending(percentage))\n return `--%`;\n\n return `${Math.round(percentage * 100)}%`;\n}\n\nexport function isPending(percentage?: number): boolean {\n return typeof percentage !== 'number';\n}","export interface ScoreThresholds {\n HIGH: number;\n MODERATE: number;\n}\n\nexport const ScoreThresholdDefaults: ScoreThresholds = {\n HIGH: 0.75,\n MODERATE: 0.5\n};\n\nexport const ScoreThresholdInsights: ScoreThresholds = {\n HIGH: 0.7,\n MODERATE: 0.7\n};","export enum InteractionCorrectness {\n Correct,\n Incorrect,\n AwaitingMarking,\n \n Answered,\n UnAnswered,\n NotApplicable\n}","export enum InteractiveAnswerStatus {\n Incorrect = 0,\n Correct = 1,\n PendingReview = 2\n}","import { Flight } from 'libs/common/react/index';\n\nexport const InsightsDemoRequests = {\n interactive(): Flight.Request {\n return {\n url: `/mocks/insights/interactive.json`,\n key: `demo:interactive`,\n normalize: false\n };\n },\n\n interactiveMetadata(): Flight.Request {\n return {\n url: `/mocks/insights/interactive-metadata.json`,\n key: `demo:interactive:metadata`,\n normalize: false\n };\n },\n\n interactiveResults(): Flight.Request {\n return {\n url: `/mocks/insights/interactive-results.json`,\n key: `demo:interactive:results`,\n normalize: false\n };\n },\n\n videoViews(): Flight.Request {\n return {\n url: `/mocks/insights/video-views.json`,\n key: `demo:video:views`,\n normalize: false\n };\n },\n\n users(): Flight.Request {\n return {\n url: `/mocks/insights/users.json`,\n key: `demo:users`,\n normalize: false\n };\n },\n\n individualHeatmap(): Flight.Request {\n return {\n url: `/mocks/insights/individual-heatmap.json`,\n key: `demo:individual:heatmap`,\n normalize: false\n };\n },\n\n aggregateHeatmap(): Flight.Request {\n return {\n url: `/mocks/insights/aggregate-heatmap.json`,\n key: `demo:aggregate:heatmap`,\n normalize: false\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 { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { SharePrivacy } from 'libs/shared/apps/share-v2/enums/SharePrivacy';\nimport { ShareType } from 'libs/shared/apps/share-v2/enums/ShareType';\nimport { Share } from 'libs/shared/apps/share-v2/interfaces/Share';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { MySharesTableData } from 'apps/my-shares/components/my-shares-table/MySharesTableUtils';\n\nconst namespace = 'myShares.demoInsights';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst DEMO_INSIGHT_DAYS_AGO = 7;\n\nexport const DEMO_INSIGHTS_SHARE: Share = {\n type: ShareType.Link,\n privacy: SharePrivacy.JustMySchool,\n objectId: '0',\n objectTypeId: MasterType.Interactive,\n viewCount: 28,\n accessCount: 15,\n dateCreated: new Date().toISOString(),\n dateShared: new Date().toISOString(),\n expireDate: null,\n link: {\n shortenedEmbedUrl: '',\n shortenedUrl: ''\n },\n shareId: '0',\n ownerCustomerId: 0,\n ownerId: 0,\n recipients: [],\n options: {\n preventScrubbing: false,\n immediateFeedback: false\n }\n};\n\nexport const DEMO_INSIGHTS_OPEN_CLASSROOM_SHARE: Share = {\n ...DEMO_INSIGHTS_SHARE,\n type: ShareType.Open,\n expireDate: DateHelper.add(new Date(DEMO_INSIGHTS_SHARE.dateCreated), 30, 'days').toISOString(),\n privacy: SharePrivacy.PinCode\n};\n\nexport const DEMO_INSIGHTS_SHARE_TABLE_DATA: MySharesTableData = {\n share: DEMO_INSIGHTS_SHARE,\n sharedObject: null,\n shareRecipients: null,\n dateShared: DateHelper.subtract(new Date(), DEMO_INSIGHT_DAYS_AGO, 'days').toISOString()\n};\n\nexport const DEMO_INSIGHTS_OPEN_CLASSROOM_SHARE_TABLE_DATA: MySharesTableData = {\n ...DEMO_INSIGHTS_SHARE_TABLE_DATA,\n share: DEMO_INSIGHTS_OPEN_CLASSROOM_SHARE\n};\n\nexport const DEMO_INSIGHTS_APPLINK: Core.AppLink = {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_OVERVIEW_DEMO\n};\n\nexport const DEMO_INSIGHTS_OPEN_CLASSROOM_APPLINK: Core.AppLink = {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_OVERVIEW_OPEN_CLASSROOM_DEMO\n};\n\nexport const DEMO_INSIGHTS_ACTION: ActionOptions = {\n svgName: cvSvgLibrary.Analytics,\n label: getPhrase('demoInsights'),\n appLink: DEMO_INSIGHTS_APPLINK,\n group: 'insights',\n className: 'btn btn-outline-dark'\n};\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { Flight } from 'libs/common/react/index';\n\nimport { BaseAnalyticsEventResponse } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { AnalyticsFilterHelper } from 'libs/shared/apps/analytics/utils/AnalyticsFilterUtils';\nimport { ShareType } from 'libs/shared/apps/share-v2/enums/ShareType';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { InsightsDemoRequests } from 'libs/shared/flight-requests/InsightsDemoRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useLockContentWidth } from 'libs/shared/hooks/useLockContentWidth';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { Config, CurrentUser, Engagement, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nimport { InsightsHeader } from 'apps/my-shares/components/insights-header/InsightsHeader';\nimport { InteractiveInsightsOverview } from 'apps/my-shares/components/interactive-insights-overview/InteractiveInsightsOverview';\nimport { DEMO_INSIGHTS_OPEN_CLASSROOM_SHARE, DEMO_INSIGHTS_SHARE } from 'apps/my-shares/constants/MySharesDemoInsights';\nimport { getInsightsDemoInteractiveTabs } from 'apps/my-shares/utils/InsightsAppLinkUtils';\nimport { getInteractiveInsightsAppLinks } from 'apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoUtils';\n\nconst namespace = 'insights.interactiveInsightsOverviewView';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InteractiveInsightsOverviewDemoViewProps {\n type?: ShareType;\n}\n\nexport function InteractiveInsightsOverviewDemoView(props: InteractiveInsightsOverviewDemoViewProps) {\n const [anonymiseUsers] = useViewModel<boolean>(SharedViewModelKeys.ANONYMISE_USERS);\n\n useLockContentWidth();\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(\n InsightsDemoRequests.interactiveMetadata()\n );\n\n const interactive = Flight.useBasicFetch<Interactive>(InsightsDemoRequests.interactive());\n\n const audienceAppLinkParams = AnalyticsFilterHelper.getAudienceAppLinkParams();\n const dateRangeAppLinkParams = AnalyticsFilterHelper.getDateRangeAppLinkParams();\n\n const results = Flight.useBasicFetch<InteractiveResultSet>(InsightsDemoRequests.interactiveResults());\n\n const aggregateEngagement = Flight.useBasicFetch<Engagement>(\n InsightsDemoRequests.aggregateHeatmap()\n );\n\n const videoViews = Flight.useBasicFetch<BaseAnalyticsEventResponse>(\n InsightsDemoRequests.videoViews()\n );\n\n useSetPageMetadata({ title: interactiveMetadata.data ? getPhrase('pageTitle', { video: interactiveMetadata.data?.name }) : null });\n\n const hasDataLoaded =\n currentUser.data &&\n config.data &&\n interactiveMetadata.data &&\n interactive.data &&\n results.data &&\n aggregateEngagement.data &&\n !!videoViews.data;\n\n const params = {\n ...audienceAppLinkParams,\n ...dateRangeAppLinkParams\n };\n const interactiveInsightsAppLinks = getInteractiveInsightsAppLinks(\n '',\n params,\n props.type\n );\n\n const share = props.type === ShareType.Open ? DEMO_INSIGHTS_OPEN_CLASSROOM_SHARE : DEMO_INSIGHTS_SHARE;\n\n if (!hasDataLoaded)\n return <></>;\n \n return (\n <div className='px-3'>\n <InsightsHeader\n video={interactiveMetadata.data}\n tabs={getInsightsDemoInteractiveTabs(interactiveMetadata.data?.id, 'insights', params, props.type)}\n dateRangeAppLinkParams={dateRangeAppLinkParams}\n share={{\n ...share,\n objectId: interactiveMetadata.data?.id\n }}\n yearGroups={[]}\n markingRequired={props.type !== ShareType.Open}\n isDemo\n hasData\n />\n\n <InteractiveInsightsOverview\n aggregateEngagement={aggregateEngagement.data}\n interactive={interactive.data}\n interactiveMetadata={interactiveMetadata.data}\n classroomStudents={null}\n results={results.data}\n osCount={videoViews.data?.osCount}\n config={config.data}\n interactiveInsightsAppLinks={interactiveInsightsAppLinks}\n anonymiseUsers={anonymiseUsers}\n hasDataLoaded={hasDataLoaded}\n share={share}\n />\n </div>\n );\n}","import { HashObject } from 'libs/common/react/interfaces';\n\nimport { ShareType } from 'libs/shared/apps/share-v2/enums/ShareType';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nexport function getInteractiveInsightsAppLinks(id: string, params?: HashObject, type?: ShareType) {\n if (type === ShareType.Open) {\n return {\n resultsAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_STUDENTS_OPEN_CLASSROOM_DEMO,\n args: [id],\n params\n },\n questionsAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_QUESTIONS_OPEN_CLASSROOM_DEMO,\n args: [id],\n params\n },\n heatmapAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_HEATMAP_OPEN_CLASSROOM_DEMO,\n args: [id],\n params\n }\n };\n }\n \n return {\n resultsAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_STUDENTS_DEMO,\n args: [id],\n params\n },\n questionsAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_QUESTIONS_DEMO,\n args: [id],\n params\n },\n heatmapAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_HEATMAP_DEMO,\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\"};","// extracted by mini-css-extract-plugin\nexport default {\"circleContainer\":\"p8Vgz\",\"backgroundCircle\":\"asGGE\",\"circleSuccess\":\"PXLNj\",\"circleWarning\":\"ZckRN\",\"circleDanger\":\"slBRg\",\"lgCircleContainer\":\"N8KCI\",\"xsCircleContainer\":\"RPqZ2\",\"pendingCircle\":\"DKrcq\",\"centredPercentageText\":\"tpmLR\"};"],"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","subtitle","svgClassName","SvgContainer","svgName","size","S","title","count","children","CHART_FONT_STYLES","fontSize","fontFamily","fontWeight","color","getPhrase","anonymiseUserName","user","shouldAnonymise","userId","id","sessionId","seed","guid","hash","charCodeAt","abs","guidToSeed","floor","Date","getMinutes","dictionaries","separator","deleted","getFullHeatMap","videoDuration","Array","ceil","fill","t","getEngagementRate","reduce","prev","next","engagementRate","groupStudents","interactive","results","scoreThreshold","groups","markingRequired","lowScore","highScore","completed","notCompleted","interactions","interactionIds","Set","students","forEach","s","withSummary","summary","getStudentResultsSummary","awaitingMarking","attempts","filter","a","has","answers","questionId","percentCorrect","HIGH","MODERATE","sortedLowScore","sortedHighScore","getInteractionById","interactionId","find","toString","getMarkedAnswerId","answer","resultId","getMarkedStatus","studentResults","markedAnswers","result","studentResponse","every","status","getInteractionResultsSummary","interaction","numStudents","numCorrect","answered","unanswered","correctness","correct","numInteractions","answeredInteractions","UserRecipientItemMetadata","anonymiseUsers","showDisplayName","anonName","nameParts","split","n","name","surname","slice","avatarUrl","avatar","url","getUserProps","avatarClassName","imageUrl","imageCdnUrl","initials","showAnonymousUser","anonymousSvgSize","detailsClassName","nameClassName","showSubText","getSubText","userType","role","yearGroup","defaults","PercentageIndicatorLayout","ProgressCircle","ref","circle","radius","r","baseVal","circumference","PI","offset","percentage","strokeDasharray","strokeDashoffset","scoreThresholds","PercentageIndicator","percentageToFixed","layout","LabelInside","label","customLabel","LabelOnly","LabelBefore","defaultProps","CircleOnly","ProgressCircleSize","CIRCLE_STROKE_WIDTH","CIRCLE_STROKE_WIDTH_LG","ProgressCircleSizeMap","ExtraSmall","Small","Large","getCircleRadius","strokeWidth","getCircleClassName","getColouredLabelClassName","getCircleContainerClassName","isPending","getPercentageToFixed","toFixed","getFormattedPercentage","round","ScoreThresholdDefaults","ScoreThresholdInsights","InteractionCorrectness","InteractiveAnswerStatus","InsightsDemoRequests","normalize","interactiveMetadata","interactiveResults","videoViews","users","individualHeatmap","aggregateHeatmap","notApplicable","isMissingWordCorrect","getStudentAnswer","items","actionableItems","isCorrect","trim","toLowerCase","isMultipleChoiceCorrect","studentAnswer","getGetStudentAnswer","attempt","wrapIsMultipleChoiceCorrect","text","wrapIsMarkableAnswerMarkedCorrect","item","isMarkableAnswerMarkedCorrect","IsCorrectLookup","InteractiveCorrectnessHelper","isInteractionCorrect","isCorrectFn","typeId","DEMO_INSIGHTS_SHARE","type","privacy","objectId","objectTypeId","viewCount","accessCount","dateCreated","toISOString","dateShared","expireDate","link","shortenedEmbedUrl","shortenedUrl","shareId","ownerCustomerId","ownerId","recipients","options","preventScrubbing","immediateFeedback","DEMO_INSIGHTS_OPEN_CLASSROOM_SHARE","DEMO_INSIGHTS_SHARE_TABLE_DATA","share","sharedObject","shareRecipients","DEMO_INSIGHTS_OPEN_CLASSROOM_SHARE_TABLE_DATA","DEMO_INSIGHTS_APPLINK","application","action","DEMO_INSIGHTS_OPEN_CLASSROOM_APPLINK","DEMO_INSIGHTS_ACTION","appLink","group","LanguageService","InteractiveInsightsOverviewDemoView","SharedViewModelKeys","useLockContentWidth","currentUser","UserRequests","config","ConfigRequests","audienceAppLinkParams","dateRangeAppLinkParams","aggregateEngagement","useSetPageMetadata","video","hasDataLoaded","params","interactiveInsightsAppLinks","ShareType","resultsAppLink","args","questionsAppLink","heatmapAppLink","getInteractiveInsightsAppLinks","InsightsHeader","tabs","yearGroups","isDemo","hasData","InteractiveInsightsOverview","classroomStudents","osCount"],"sourceRoot":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/1336-1826f6e582-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/IllustrationResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/MissingWordResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/MultipleChoiceResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/TrueOrFalseResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/ShortAnswerResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/interaction-response-item.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/InteractionResponseItem.tsx","file:///app/packages/libs/shared/src/utils/AnalyticsRequestUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/flight-requests/InteractiveResultsRequests.ts","file:///app/packages/libs/shared/src/apps/analytics/hooks/UseMarkAnswers.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/AnonymiseUserUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/InteractiveUtils.ts","file:///app/packages/libs/shared/src/constants/ScoreThresholds.ts"],"sourcesContent":["import React from 'react';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { StudentAnswer } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\ninterface AnswerContainerProps extends React.PropsWithChildren {\n answer: StudentAnswer;\n textClassName?: string;\n customAnswer?: boolean;\n}\n\nexport function AnswerContainer(props: AnswerContainerProps) {\n const { answer } = props;\n\n function getBgColour(status: InteractiveAnswerStatus) {\n switch (status) {\n case InteractiveAnswerStatus.Correct: return 'bg-light-green';\n case InteractiveAnswerStatus.Incorrect: return 'bg-light-red';\n case InteractiveAnswerStatus.PendingReview: return 'bg-light-blue';\n }\n }\n\n return (\n <div key={answer.id} className={`${getBgColour(answer.status)} rounded p-2 mb-2`}>\n <div className='d-flex align-items-center gap-2'>\n {answer.status === InteractiveAnswerStatus.Correct && <SvgContainer svgName={cvSvgLibrary.Check} className='svg-container flex-shrink-0 text-success' />}\n {answer.status === InteractiveAnswerStatus.Incorrect && <SvgContainer svgName={cvSvgLibrary.Close} className='svg-container flex-shrink-0 text-danger' />}\n {!props.customAnswer && <span className={props.textClassName}>{answer.text}</span>}\n </div>\n {props.children}\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nconst namespace = 'shared.interactionResponses';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function IllustrationResponse(props: ResponseItemComponentProps): JSX.Element {\n const answer = ArrayHelper.first(props.answers);\n\n if (!answer)\n return <></>;\n\n return (\n <AnswerContainer answer={answer} customAnswer>\n <div className='ratio ratio-16x9'>\n <img\n className='img-fluid bg-white border rounded h-100 w-100'\n src={answer.text}\n alt={`${getPhrase('illustrationAlt')}: ${props.interaction.name}`}\n />\n </div>\n {props.children}\n </AnswerContainer>\n );\n}","import React from 'react';\n\nimport { Interaction, InteractionTypeId, StudentAnswer, User } from 'libs/shared/interfaces';\n\nimport { IllustrationResponse } from './components/IllustrationResponse';\nimport { MissingWordResponse } from './components/MissingWordResponse';\nimport { MultipleChoiceResponse } from './components/MultipleChoiceResponse';\nimport { ShortAnswerResponse } from './components/ShortAnswerResponse';\nimport { TrueOrFalseResponse } from './components/TrueOrFalseResponse';\n\nexport interface ResponseItemComponentProps extends React.PropsWithChildren {\n interaction: Interaction;\n answers: StudentAnswer[];\n imageCdnUrl: string;\n user: User;\n showFeedback?: boolean;\n showAvatar?: boolean;\n anonymisedUserName?: string;\n}\nconst NoResponseRequired = () => <></>;\n\nexport const ResponseItemComponentLookup: {\n [typeId: number]: (props: ResponseItemComponentProps) => JSX.Element\n} = {\n [InteractionTypeId.Annotation]: NoResponseRequired,\n [InteractionTypeId.Image]: NoResponseRequired,\n [InteractionTypeId.MissingWord]: MissingWordResponse,\n [InteractionTypeId.MultipleChoice]: MultipleChoiceResponse,\n [InteractionTypeId.TrueOrFalse]: TrueOrFalseResponse,\n [InteractionTypeId.ShortAnswer]: ShortAnswerResponse,\n [InteractionTypeId.Illustration]: IllustrationResponse\n};","import React from 'react';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\n\nexport function MissingWordResponse(props: ResponseItemComponentProps) {\n if (!props.answers.length) return <></>;\n\n return (\n <ul className='list-unstyled'>\n {props.answers.map(answer => (\n <li key={answer.id}>\n <AnswerContainer\n answer={answer}\n textClassName='bg-white p-1 border border-gray-300 rounded'\n />\n </li>\n ))}\n </ul>\n );\n}","import React from 'react';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function MultipleChoiceResponse(props: ResponseItemComponentProps) {\n if (!props.answers.length) return <></>;\n\n return (\n <ul className='list-unstyled'>\n {props.answers.map(answer => (\n <li key={answer.id}>\n <AnswerContainer answer={answer} />\n </li>\n ))}\n </ul>\n );\n}","import React from 'react';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function TrueOrFalseResponse(props: ResponseItemComponentProps) {\n const answer = ArrayHelper.first(props.answers);\n\n if (!answer)\n return <></>;\n\n return (\n <AnswerContainer answer={answer} />\n );\n}","import React from 'react';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function ShortAnswerResponse(props: ResponseItemComponentProps): JSX.Element {\n const answer = ArrayHelper.first(props.answers);\n\n if (!answer)\n return <></>;\n\n return (\n <AnswerContainer answer={answer}>\n {props.children}\n </AnswerContainer>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"avatarContainer\":\"O7oaA\"};","import React from 'react';\n\nimport { ResponseItemComponentLookup } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { InteractionResponseCorrectness } from 'libs/shared/components/interaction-response/InteractionResponseCorrectness';\nimport { InteractionStudentDetailsHeader } from 'libs/shared/components/interaction-response/InteractionStudentDetailsHeader';\nimport { MarkResponse } from 'libs/shared/components/interaction-response/MarkResponse';\nimport { NoResponse } from 'libs/shared/components/interaction-response/response-types/NoResponse';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from './interaction-response-item.scss';\n\ninterface InteractionResponseProps {\n interaction: Interaction;\n studentResults: StudentResults;\n imageCdnUrl: string;\n markInteraction: (answers: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n markedStatus?: InteractiveAnswerStatus;\n showStudentDetails?: boolean;\n className?: string;\n showFeedback?: boolean;\n showAvatar?: boolean;\n anonymisedUserName?: string;\n responseComponentClass?: string;\n}\n\nexport function InteractionResponseItem(props: InteractionResponseProps): JSX.Element {\n const ResponseItemComponent = ResponseItemComponentLookup[props.interaction.typeId];\n\n if (!ResponseItemComponent)\n return <></>;\n\n const result = getStudentResult(props.studentResults);\n\n const studentAttempt = getStudentAttempt(props.interaction.id, result);\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(props.interaction, result);\n\n return (\n <div className='position-relative'>\n <div className={`rounded ${props.className ?? ''}`}>\n <div className='d-flex'>\n {!!props.showStudentDetails &&\n <div className='me-2'>\n <div className={styles.avatarContainer}>\n <Avatar\n imageCdnUrl={props.imageCdnUrl}\n initials={props.anonymisedUserName\n ? UserHelper.getInitialsFromFullName(props.anonymisedUserName)\n : UserHelper.getInitials(props.studentResults.user?.name, props.studentResults.user?.surname)\n }\n imageUrl={props.anonymisedUserName ? null : props.studentResults.user?.avatar?.url}\n showAnonymousUser={!!props.studentResults?.user?.sessionId}\n />\n </div>\n \n </div>\n }\n <div className='flex-grow-1'>\n {!!props.showStudentDetails &&\n <InteractionStudentDetailsHeader\n studentResults={props.studentResults}\n correctness={correctness}\n anonymisedUserName={props.anonymisedUserName}\n />\n }\n <div className='d-flex justify-content-between'>\n <div className={`flex-grow-1 mb-2 ${props.responseComponentClass ? props.responseComponentClass : ''}`}>\n {studentAttempt\n ? <ResponseItemComponent\n interaction={props.interaction}\n answers={studentAttempt.answers}\n imageCdnUrl={props.imageCdnUrl}\n user={props.studentResults.user}\n showFeedback={props.showFeedback}\n showAvatar={props.showAvatar}\n >\n <MarkResponse\n studentAttempt={studentAttempt}\n correctness={correctness}\n markInteraction={props.markInteraction}\n markedStatus={props.markedStatus}\n />\n </ResponseItemComponent>\n : <NoResponse />\n }\n </div>\n {!props.showStudentDetails &&\n <InteractionResponseCorrectness correctness={correctness} />\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}","import { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\nexport function getAnalyticsRequestKey(baseKey: string, filter: AnalyticsRequestFilter, extra?: string): string {\n if (!filter)\n return baseKey;\n\n let key = `${baseKey}:${filter.start}:${filter.end}`;\n\n const userIdKey = Array.isArray(filter.userId) ? filter.userId.sort().join(':') : filter.userId;\n const groupIdKey = Array.isArray(filter.groupId) ? filter.groupId.sort().join(':') : filter.groupId;\n const customerIdKey = Array.isArray(filter.customerId) ? filter.customerId.sort().join(':') : filter.customerId;\n\n if (userIdKey)\n key += `:${userIdKey}`;\n\n if (groupIdKey)\n key += `:${groupIdKey}`;\n\n if (customerIdKey)\n key += `:${customerIdKey}`;\n\n if (extra)\n key += `:${extra}`;\n\n return key;\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 shareId?: string;\n}\n\nfunction getInteractiveResultFilters(\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter,\n shareId?: string\n): InteractiveResultFilters {\n return {\n currentUserId: currentUser.id,\n currentCustomerId: currentUser.customerId,\n dateRange: filter ? { start: filter.start, end: filter.end } : undefined,\n userIds: filter?.userId,\n classroomsAndGroups: filter?.groupId,\n shareId: shareId\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 shareId?: string,\n success?: (data: InteractiveResultSet) => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: shareId ?\n `/api/domain/v3/analytics/interactives/${interactiveId}/metadata/${interactiveMetadataId}` :\n `/api/domain/v2/analytics/interactives/${interactiveId}/metadata/${interactiveMetadataId}`,\n key: getAnalyticsRequestKey(`interactive:result:set:${interactiveId}:${interactiveMetadataId}:${shareId}`, filter),\n data: getInteractiveResultFilters(currentUser, filter, shareId),\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 const key = data.interactives.map(interactive => `${interactive.interactiveId}:${interactive.metadataId}:${interactive.shareId}`).join(',');\n return {\n url: `/api/domain/v1/analytics/interactives/pending-reviews/summary`,\n key: `interactives:pending:reviews:${key}`,\n type: HttpVerbs.POST,\n data,\n normalize: false\n };\n },\n\n interactiveResultsReport(data: InteractiveResultsReport): Flight.Request {\n return {\n url: '/api/domain/v3/analytics/interactives/report',\n key: 'interactive:results:report',\n data,\n type: HttpVerbs.POST,\n normalize: false\n };\n }\n};","import { useState } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { InteractiveResultsRequests } from 'libs/shared/apps/analytics/flight-requests/InteractiveResultsRequests';\nimport { getMarkedAnswerId } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { StudentAnswer } from 'libs/shared/interfaces';\n\nconst getPhrase = LanguageService.encloseNamespace('reportsShared.dataHooks');\n\nexport type MarkedAnswerHash = { [id: string]: StudentAnswer };\n\n/**\n * This hook manages the storing of a marked answer hash in state and then the submitting\n * of those answers via an api call.\n */\nexport const useMarkAnswers = (interactiveId: string, interactiveMetadataId: string, onDone?: () => void) => {\n const [ markedAnswers, setMarkedAnswers ] = useState<MarkedAnswerHash>({});\n\n const dispatch = useDispatch();\n const alerts = useAlerts();\n\n function addMarkedAnswers(answers: StudentAnswer[], status: InteractiveAnswerStatus): void {\n answers.forEach(a => {\n setMarkedAnswers(m => ({ ...m, [getMarkedAnswerId(a)]: { ...a, status } }));\n });\n }\n\n function submitMarkedAnswers(): void {\n const answers = Object.keys(markedAnswers).map(key => markedAnswers[key]);\n\n if (!answers.length)\n return;\n\n let completeCount = 0;\n let successCount = 0;\n\n function onSuccess(): void {\n successCount++;\n }\n\n function onAlways(): void {\n completeCount++;\n\n if (completeCount === answers.length)\n onComplete();\n }\n\n function onComplete(): void {\n let alertMessage = '';\n let useErrorAlert = false;\n\n if (successCount === 0) {\n alertMessage = getPhrase('error', { smartCount: answers.length });\n useErrorAlert = true;\n }\n\n if (successCount < completeCount) {\n alertMessage = getPhrase('success', { smartCount: successCount })\n + ` ${getPhrase('partialError', { smartCount: completeCount - successCount })}`;\n }\n\n if (successCount === completeCount) {\n alertMessage = getPhrase('success', { smartCount: successCount });\n }\n\n useErrorAlert\n ? alerts.error(alertMessage)\n : alerts.success(alertMessage);\n\n setMarkedAnswers({});\n\n onDone && onDone();\n }\n\n answers.forEach(({ id, resultId, questionId, status }) => {\n Flight.fetch(dispatch, InteractiveResultsRequests.mark(\n interactiveId,\n interactiveMetadataId,\n id,\n { id, resultId, questionId, status },\n onSuccess,\n null,\n onAlways\n ));\n });\n }\n\n return {\n markedAnswers,\n addMarkedAnswers,\n submitMarkedAnswers\n };\n};","import { animals, colors, Config as UniqueNamesConfig, uniqueNamesGenerator } from 'unique-names-generator';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnonUser } from 'libs/shared/interfaces/models/interactive-results/AnonUser';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nconst namespace = 'shared.analyticsUtils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction guidToSeed(guid: string): number {\n if (!guid)\n return 0;\n\n // Simple hash function (DJB2-like) for browsers\n let hash = 0;\n for (let i = 0; i < guid.length; i++) {\n const char = guid.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash |= 0; // Convert to 32bit integer\n }\n return Math.abs(hash);\n}\n\nfunction getUniqueNamesConfig(userId: string, sessionId: string): UniqueNamesConfig {\n /**\n * Generate a seed that is unique to each user but changes every 5 minutes.\n * \n * We use a seed so that if the same user's name is anonymised multiple times\n * in quick succession (e.g. multiple renders), the same name will be returned each time.\n * \n * We change the seed every 5 minutes so that students don't always have the same name.\n */\n const seed = +`${userId || guidToSeed(sessionId)}${Math.floor((new Date()).getMinutes() / 5)}`;\n\n return {\n dictionaries: [ colors, animals ],\n separator: ' ',\n length: 2,\n style: 'capital',\n seed\n };\n}\n\nexport function anonymiseUserName(user: AnonUser, shouldAnonymise: boolean): string {\n if (!user) {\n return getPhrase('anonUser');\n }\n\n if (!shouldAnonymise) {\n if (user.deleted)\n return getPhrase('deleted');\n\n return UserHelper.getFullName(user) || getPhrase('anonUser');\n }\n\n return uniqueNamesGenerator(getUniqueNamesConfig(user.id, user.sessionId));\n}\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { Interactive, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { flattenInteractions, getInteractions, getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\ninterface StudentGroups {\n markingRequired: StudentResultsWithSummary[];\n lowScore: StudentResultsWithSummary[];\n highScore: StudentResultsWithSummary[];\n completed: StudentResultsWithSummary[];\n notCompleted: StudentResultsWithSummary[];\n}\n\nexport function groupStudents(\n interactive: Interactive,\n results: InteractiveResultSet,\n scoreThreshold?: ScoreThresholds\n): StudentGroups {\n const groups: StudentGroups = {\n markingRequired: [],\n lowScore: [],\n highScore: [],\n completed: [],\n notCompleted: []\n };\n\n const interactions = getInteractions(interactive);\n const interactionIds = new Set(interactions.map(i => i.id));\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 const result = ArrayHelper.last(s.results);\n const answeredInteractions = result.attempts.filter(a => !!interactionIds.has(a?.answers[0]?.questionId)).length;\n\n if (answeredInteractions === interactionIds.size) {\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: answeredInteractions,\n attempts: studentResults.results.length,\n unanswered: numInteractions - answeredInteractions,\n percentCorrect,\n correct: numCorrect,\n awaitingMarking\n };\n}","export interface ScoreThresholds {\n HIGH: number;\n MODERATE: number;\n}\n\nexport const ScoreThresholdDefaults: ScoreThresholds = {\n HIGH: 0.75,\n MODERATE: 0.5\n};\n\nexport const ScoreThresholdInsights: ScoreThresholds = {\n HIGH: 0.7,\n MODERATE: 0.7\n};"],"names":["AnswerContainer","props","answer","key","id","className","status","InteractiveAnswerStatus","getBgColour","SvgContainer","svgName","customAnswer","textClassName","text","children","getPhrase","LanguageService","NoResponseRequired","ResponseItemComponentLookup","answers","length","map","ArrayHelper","src","alt","interaction","name","InteractionResponseItem","ResponseItemComponent","typeId","result","studentResults","studentAttempt","correctness","InteractiveCorrectnessHelper","showStudentDetails","Avatar","imageCdnUrl","initials","anonymisedUserName","UserHelper","user","surname","imageUrl","avatar","url","showAnonymousUser","sessionId","InteractionStudentDetailsHeader","responseComponentClass","showFeedback","showAvatar","MarkResponse","markInteraction","markedStatus","NoResponse","InteractionResponseCorrectness","getAnalyticsRequestKey","baseKey","filter","extra","start","end","userIdKey","Array","isArray","userId","sort","join","groupIdKey","groupId","customerIdKey","customerId","getInteractiveResultFilters","currentUser","shareId","currentUserId","currentCustomerId","dateRange","undefined","userIds","classroomsAndGroups","InteractiveResultsRequests","interactiveResultSet","interactiveId","interactiveMetadataId","success","error","always","data","type","HttpVerbs","normalize","mark","answerId","resultId","invalidationKeys","pendingReviews","interactives","interactive","metadataId","interactiveResultsReport","useMarkAnswers","onDone","useState","markedAnswers","setMarkedAnswers","dispatch","alerts","addMarkedAnswers","forEach","a","m","submitMarkedAnswers","Object","keys","completeCount","successCount","questionId","I","onSuccess","onAlways","alertMessage","useErrorAlert","smartCount","anonymiseUserName","shouldAnonymise","seed","guid","hash","i","charCodeAt","Math","abs","guidToSeed","floor","Date","getMinutes","dictionaries","separator","style","deleted","groupStudents","results","scoreThreshold","groups","markingRequired","lowScore","highScore","completed","notCompleted","interactions","interactionIds","Set","students","s","withSummary","summary","getStudentResultsSummary","awaitingMarking","push","attempts","has","size","percentCorrect","HIGH","MODERATE","sortedLowScore","sortedHighScore","getInteractionById","interactionId","find","toString","getMarkedAnswerId","getMarkedStatus","studentResponse","every","getInteractionResultsSummary","numStudents","numCorrect","answered","unanswered","correct","numInteractions","answeredInteractions","ScoreThresholdDefaults","ScoreThresholdInsights"],"sourceRoot":""}
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[2074],{44746:(e,a,t)=>{t.r(a),t.d(a,{HardGateInsightsView:()=>F});var s=t(32735),i=t(23481),n=t(20354),c=t(18488),r=t(21789),l=t(97958),d=t(83345),o=t(16714),h=t(39151),m=t(1666),u=t(31949),p=t(93322),E=t(22902),g=t(79612),I=t(35223),v=t(31908),b=t(99742),w=t(14070),C=t(97291),N=t(88630),_=t(74049),k=t(10447),V="insights.hardGateInsightsView",y=i.T.encloseNamespace(V);function F(e){var a,t;(0,p.F)();var i=(0,E.T)(),F=i.hasPermissions,S=i.getGatedPermission,G=n.a.useBasicFetch(h.L.config()),x=n.a.useBasicFetch(u.N.currentUser()),A=n.a.useBasicFetch(x.data&&m.h.yearGroups(x.data.customerId)),P=n.a.useBasicFetch(c.o.getShare(e.shareId)),T=r.x.getClassroomIdFromShare(P.data),f=n.a.useBasicFetch(T&&N.F.getClassroom(T)),B=P.data&&v.M.getVideoRequest(P.data.objectId,P.data.objectTypeId),L=n.a.useBasicFetch(B);return(0,g.M)({title:L.data?y("pageTitle",{video:null===(a=L.data)||void 0===a?void 0:a.name}):null}),s.createElement("div",{className:"px-3"},s.createElement(_.j,{video:L.data,classroom:f.data,tabs:(0,k.$6)(P.data,"insights"),hasAnalytics:F(o.C.ViewCustomerAnalytics),analyticsWebUrl:null===(t=G.data)||void 0===t?void 0:t.analyticsWebUrl,share:P.data,yearGroups:A.data,hasData:!1,viewInsightsGatedPermission:S(o.C.ViewInsights)}),s.createElement(l.u,null,s.createElement(l.u.Image,{src:b.W.Insights.SEND_PAPER_PLANE}),s.createElement(l.u.Heading,null,s.createElement(d.x,{namespace:V,phrase:"heading"})),s.createElement(l.u.Info,{className:"w-75"},s.createElement(d.x,{namespace:V,phrase:"description"})," "),s.createElement(l.u.Cta,{text:y("cta"),appLink:{application:C.O.SIGN_UP,action:w.e.SignUp.INVITE_COLLEAGUE},icon:I.vn.Share,className:"btn btn-dark mb-3"}),s.createElement(l.u.Cta,{text:"View demo data",appLink:{application:C.O.MY_SHARES,action:w.e.MyShares.INTERACTIVE_OVERVIEW_DEMO},className:"btn btn-link text-info py-0"})))}}}]);
2
- //# sourceMappingURL=2074-39b86b9a22-lite.chunk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/2074-39b86b9a22-lite.chunk.js","mappings":"mZA6BMA,EAAY,gCACZC,EAAY,qBAAiCD,GAM7C,SAAUE,EAAqBC,G,SACnC,SAEA,OAA+C,SAAvCC,EAAc,EAAdA,eAAgBC,EAAkB,EAAlBA,mBAElBC,EAAS,kBAA6B,cACtCC,EAAc,kBAAkC,mBAChDC,EAAa,kBACjBD,EAAYE,MAAQ,eAA4BF,EAAYE,KAAKC,aAG7DC,EAAQ,kBAA4B,aAAuBR,EAAMS,UAEjEC,EAAc,4BAAoCF,EAAMF,MACxDK,EAAY,kBAAgCD,GAAe,iBAA+BA,IAE1FE,EAAeJ,EAAMF,MAAQ,oBAA4BE,EAAMF,KAAKO,SAAUL,EAAMF,KAAKQ,cACzFC,EAAQ,kBAAiCH,GAI/C,OAFA,OAAmB,CAAEI,MAAOD,EAAMT,KAAOR,EAAU,YAAa,CAAEiB,MAAiB,QAAV,EAAAA,EAAMT,YAAI,eAAEW,OAAU,OAG7F,uBAAKC,UAAU,QACb,gBAAC,IAAc,CACbH,MAAOA,EAAMT,KACbK,UAAWA,EAAUL,KACrBa,MAAM,QAAqBX,EAAMF,KAAM,YACvCc,aAAcnB,EAAe,2BAC7BoB,gBAA4B,QAAX,EAAAlB,EAAOG,YAAI,eAAEe,gBAC9Bb,MAAOA,EAAMF,KACbD,WAAYA,EAAWC,KACvBgB,SAAS,EACTC,4BAA6BrB,EAAmB,oBAElD,gBAAC,IAAU,KACT,gBAAC,UAAgB,CAACsB,IAAK,gCACvB,gBAAC,YAAkB,KACjB,gBAAC,IAAI,CAAC3B,UAAWA,EAAW4B,OAAO,aAErC,gBAAC,SAAe,CAACP,UAAU,QACzB,gBAAC,IAAI,CAACrB,UAAWA,EAAW4B,OAAO,gBAAgB,KAErD,gBAAC,QAAc,CACbC,KAAM5B,EAAU,OAChB6B,QAAS,CACPC,YAAa,YACbC,OAAQ,6BAEVC,KAAM,WACNZ,UAAU,sBAEZ,gBAAC,QAAc,CACbQ,KAAM,iBACNC,QAAS,CACPC,YAAa,cACbC,OAAQ,wCAEVX,UAAU,iCAKpB,C","sources":["file:///app/packages/projects/lite/src/apps/my-shares/views/hard-gate-insights-view/HardGateInsightsView.tsx"],"sourcesContent":["import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { ShareRequests } from 'libs/shared/apps/share-v2/flight-requests/ShareRequests';\nimport { Share } from 'libs/shared/apps/share-v2/interfaces/Share';\nimport { ShareHelper } from 'libs/shared/apps/share-v2/utils/ShareHelper';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useLockContentWidth } from 'libs/shared/hooks/useLockContentWidth';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { Classroom, Config, CurrentUser, VideoTypes, YearGroup } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\nimport { VideoHelper } from 'libs/shared/utils/VideoHelper';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { ClassroomRequests } from 'apps/classrooms/flight-requests/ClassroomRequests';\nimport { InsightsHeader } from 'apps/my-shares/components/insights-header/InsightsHeader';\nimport { getInsightsVideoTabs } from 'apps/my-shares/utils/InsightsAppLinkUtils';\n\nconst namespace = 'insights.hardGateInsightsView';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface HardGateInsightsViewProps {\n shareId: string;\n}\n\nexport function HardGateInsightsView(props: HardGateInsightsViewProps) {\n useLockContentWidth();\n\n const { hasPermissions, getGatedPermission } = usePermissions();\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const yearGroups = Flight.useBasicFetch<YearGroup[]>(\n currentUser.data && CustomerRequests.yearGroups(currentUser.data.customerId)\n );\n\n const share = Flight.useBasicFetch<Share>(ShareRequests.getShare(props.shareId));\n\n const classroomId = ShareHelper.getClassroomIdFromShare(share.data);\n const classroom = Flight.useBasicFetch<Classroom>(classroomId && ClassroomRequests.getClassroom(classroomId));\n\n const videoRequest = share.data && VideoHelper.getVideoRequest(share.data.objectId, share.data.objectTypeId);\n const video = Flight.useBasicFetch<VideoTypes>(videoRequest);\n\n useSetPageMetadata({ title: video.data ? getPhrase('pageTitle', { video: video.data?.name }) : null });\n\n return (\n <div className='px-3'>\n <InsightsHeader\n video={video.data}\n classroom={classroom.data}\n tabs={getInsightsVideoTabs(share.data, 'insights')}\n hasAnalytics={hasPermissions(PermissionName.ViewCustomerAnalytics)}\n analyticsWebUrl={config.data?.analyticsWebUrl}\n share={share.data}\n yearGroups={yearGroups.data}\n hasData={false}\n viewInsightsGatedPermission={getGatedPermission(PermissionName.ViewInsights)}\n />\n <EmptyState>\n <EmptyState.Image src={ImageUrls.Insights.SEND_PAPER_PLANE} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info className='w-75'>\n <Text namespace={namespace} phrase='description' />&nbsp;\n </EmptyState.Info>\n <EmptyState.Cta\n text={getPhrase('cta')}\n appLink={{\n application: AppChannels.SIGN_UP,\n action: Actions.SignUp.INVITE_COLLEAGUE\n }}\n icon={cvSvgLibrary.Share}\n className='btn btn-dark mb-3'\n />\n <EmptyState.Cta\n text={'View demo data'}\n appLink={{\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_OVERVIEW_DEMO\n }}\n className='btn btn-link text-info py-0'\n />\n </EmptyState>\n </div>\n );\n}"],"names":["namespace","getPhrase","HardGateInsightsView","props","hasPermissions","getGatedPermission","config","currentUser","yearGroups","data","customerId","share","shareId","classroomId","classroom","videoRequest","objectId","objectTypeId","video","title","name","className","tabs","hasAnalytics","analyticsWebUrl","hasData","viewInsightsGatedPermission","src","phrase","text","appLink","application","action","icon"],"sourceRoot":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/2664-87c8cbfa7f-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/components/rostering/rostering-alert/RosteringAlert.tsx","file:///app/packages/libs/shared/src/hooks/useBulkCheckboxManager.ts","file:///app/packages/projects/lite/src/apps/classrooms/components/manage-classroom-teachers/empty-state/ManageClassroomTeachersEmptyState.tsx","file:///app/packages/projects/lite/src/apps/classrooms/components/manage-classroom-teacher-item/manage-classroom-teacher-item.scss","file:///app/packages/projects/lite/src/apps/classrooms/components/manage-classroom-teacher-item/ManageClassroomTeacherItem.tsx","file:///app/packages/projects/lite/src/apps/classrooms/components/manage-classroom-teachers/ManageClassroomTeachers.tsx","file:///app/packages/projects/lite/src/apps/classrooms/components/manage-classroom-teachers/partial-loading/partial-manage-classroom-teachers.scss","file:///app/packages/projects/lite/src/apps/classrooms/components/manage-classroom-teachers/partial-loading/PartialManageClassroomTeachers.tsx","file:///app/packages/projects/lite/src/apps/classrooms/views/classroom-teachers/ClassroomTeachersView.tsx","file:///app/packages/projects/lite/src/shared/hooks/useClassroomExperience.ts"],"sourcesContent":["import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nconst namespace = 'rostering.alert';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface RosteringAlertProps {\n type?: 'classroom' | 'general';\n}\n\nexport function RosteringAlert(props: RosteringAlertProps) {\n const text = props.type === 'classroom' ? getPhrase('classroom') : getPhrase('hasRostering');\n\n return (\n <div className='alert text-info bg-light-blue px-2 rounded-3 fw-semibold py-2 d-flex flex-wrap'>\n {text}&nbsp;\n {/* todo add it back when KB article link is ready */}\n {/* <ExternalLink\n className='text-info text-underline'\n href={''}\n newTab\n >\n {LanguageService.getPhrase(namespace, 'learnMore')}\n </ExternalLink> */}\n </div>\n );\n}","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { useForceUpdate } from 'libs/shared/hooks/useForceUpdate';\nimport { usePrevious } from 'libs/shared/hooks/usePrevious';\n\ntype CheckboxItemsState = Map<string, boolean>;\n\nexport interface BulkCheckboxManager {\n onToggleBulk: () => void;\n onToggleItem: (id: string) => void;\n getSelected: () => string[];\n isChecked: (item: string | number | HashObject<string>) => boolean;\n bulkChecked: boolean;\n deselectAll: () => void;\n hasSomeSelections: () => boolean;\n setSelected: (ids: string[]) => void;\n getSelectedCount: () => number;\n reset: () => void;\n getMap: () => Map<string, boolean>;\n}\n\nexport interface BulkCheckboxManagerOptions {\n idField?: string; // For objects like `PresentationAudiences` that don't use `id` as their identifier field\n persistNamespace?: string;\n preselectedIds?: string[];\n initialState?: CheckboxItemsState;\n}\n\n/**\n * @param collection - The collection you are keeping track of with checkboxes\n * @param options - See interface above\n */\nexport const useBulkCheckboxManager = (collection: HashObject[], options: BulkCheckboxManagerOptions = {}) => {\n const { idField = 'id', persistNamespace } = options;\n\n const initial = options.initialState ? options.initialState : new Map<string, boolean>();\n\n const items = React.useRef<CheckboxItemsState>(initial);\n \n const forceUpdate = useForceUpdate();\n\n const prevCollection = usePrevious(collection);\n const prevNamespace = usePrevious(persistNamespace);\n\n /**\n * This hook will clear the state of this hook when a user navigates between pages\n * if a persistNamespace was not provided\n */\n React.useEffect(() => {\n /**\n * If we're being passed initial state, we don't want to clear the state\n */\n if (options.initialState)\n return;\n\n /**\n * If we've been given a persist namespace, we don't want to clear our\n * selections while the namespace stays the same\n */\n if (persistNamespace && prevNamespace === persistNamespace)\n return;\n\n /**\n * Don't reinitialize if the ids of the new and old collection\n * are identical\n */\n const prevIds = prevCollection?.map(i => i[idField]).join();\n const ids = collection?.map(i => i[idField]).join();\n\n if (prevIds === ids)\n return;\n\n reset();\n }, [ prevCollection, prevNamespace, collection, options.initialState ]);\n\n React.useEffect(() => {\n if (!options.preselectedIds?.length)\n return;\n\n setSelected(options.preselectedIds);\n }, []);\n\n function reset(): void {\n items.current.clear();\n forceUpdate();\n }\n\n // When toggled on, all checkbox items will be enabled. Vice versa if toggled off\n function onToggleBulk(): void {\n const setValue = !isBulkChecked();\n\n collection.forEach(item => {\n if (setValue)\n items.current.set(item[idField].toString(), true);\n else\n items.current.delete(item[idField].toString());\n });\n\n forceUpdate();\n }\n\n // Toggles a single item\n function onToggleItem(id: string): void {\n const nextItemState = !items.current.get(id.toString());\n\n if (nextItemState)\n items.current.set(id.toString(), nextItemState);\n else\n items.current.delete(id.toString());\n \n forceUpdate();\n }\n\n // Returns the state of the item passed in\n function isChecked(item: string | number | HashObject<string>): boolean {\n if (typeof item === 'number')\n item = item.toString();\n else if (typeof item !== 'string')\n item = item[idField].toString();\n\n return items.current.get(item);\n }\n\n function getSelected(): string[] {\n return Array.from(items.current.keys());\n }\n\n function deselectAll(): void {\n if (!collection?.length) return;\n\n collection.forEach(item => {\n items.current.delete(item[idField].toString());\n });\n forceUpdate();\n }\n\n // Returns true if at least 1 item is checked\n function hasSomeSelections(): boolean {\n if (!collection?.length)\n return false;\n\n return !!collection.find(item => isChecked(item));\n }\n\n function isBulkChecked(): boolean {\n if (!collection?.length)\n return false;\n\n return collection.every(isChecked);\n }\n\n function setSelected(ids: string[]): void {\n ids.forEach(id => {\n items.current.set(id, true);\n });\n forceUpdate();\n }\n\n function getSelectedCount(): number {\n return items.current.size;\n }\n\n function getMap(): Map<string, boolean> {\n return items.current;\n }\n\n return {\n onToggleBulk,\n onToggleItem,\n getSelected,\n isChecked,\n bulkChecked: isBulkChecked(),\n deselectAll,\n hasSomeSelections,\n setSelected,\n getSelectedCount,\n reset,\n getMap\n };\n};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Classroom } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst namespace = 'classrooms.manageClassroomTeachersEmptyState';\n\ninterface ManageClassroomTeachersEmptyStateProps {\n classroom: Classroom;\n}\n\nexport function RosteredClassroomTeachersEmptyState(): JSX.Element {\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={ImageUrls.EmptyStates.Classrooms.TEACHERS} />\n\n <EmptyState.Heading><Text phrase='emptyStateHeading' /></EmptyState.Heading>\n\n <EmptyState.Info className='mb-2'><Text phrase='emptyStateInfo' /></EmptyState.Info>\n\n {/* todo add kb link */}\n <a className='btn btn-link info-link font-semibold' href={''} target='_blank'>\n {LanguageService.getPhrase(namespace, 'rosteringCta')}\n </a>\n\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n\nexport function ManageClassroomTeachersEmptyState(props: ManageClassroomTeachersEmptyStateProps): JSX.Element {\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={ImageUrls.EmptyStates.Classrooms.TEACHERS} />\n\n <EmptyState.Heading><Text phrase='emptyStateHeading' /></EmptyState.Heading>\n\n <EmptyState.Info ><Text phrase='emptyStateInfo' /></EmptyState.Info>\n \n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'addTeachers')}\n icon={cvSvgLibrary.Plus}\n appLink={{\n application: AppChannels.CLASSROOMS,\n action: Actions.Classrooms.ADD_TEACHERS,\n args: [props.classroom.id]\n }}\n />\n\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n","// extracted by mini-css-extract-plugin\nexport default {\"avatarContainer\":\"kTynd\",\"name\":\"UWi4G\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AssocDescriptor, EntityType, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { ActionOptions, Actions as MoreActions } from 'libs/shared/components/actions/Actions';\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { Checkbox } from 'libs/shared/components/forms/form-checkbox/Checkbox';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { UserRole } from 'libs/shared/enums/UserRole';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { Config, CurrentUser } from 'libs/shared/interfaces';\nimport { Classroom } from 'libs/shared/interfaces';\nimport { User } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport styles from './manage-classroom-teacher-item.scss';\n\nconst namespace = 'classrooms.manageClassroomTeacherItem';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst getRemoveTeachersAppLink = (teacherId: string, classroomId: string) => ({\n application: AppChannels.CLASSROOMS,\n action: Actions.Classrooms.REMOVE_TEACHERS,\n args: [classroomId],\n params: {\n teacherIds: [teacherId]\n }\n});\n\nconst getAssignAsOwnerAppLink = (teacherId: string, classroomId: string) => ({\n application: AppChannels.CLASSROOMS,\n action: Actions.Classrooms.ASSIGN_AS_OWNER,\n args: [ classroomId, teacherId ]\n});\n\nconst getRevokeOwnershipAppLink = (teacherId: string, classroomId: string) => ({\n application: AppChannels.CLASSROOMS,\n action: Actions.Classrooms.REVOKE_OWNERSHIP,\n args: [ classroomId, teacherId ]\n});\n\ninterface ManageClassroomTeacherItemProps {\n classroom: Classroom;\n teacher: User;\n config: Config;\n onToggleCheckbox: () => void;\n checked: boolean;\n isOwner: (userId: string) => boolean;\n currentUser: CurrentUser;\n readOnly?: boolean;\n readonlyTooltip?: string;\n}\n\nexport function ManageClassroomTeacherItem(props: ManageClassroomTeacherItemProps): JSX.Element {\n const { hasPermissions } = usePermissions();\n\n const teacherIsAdmin = UserHelper.getUserRole(props.teacher) === UserRole.Admin;\n\n function getCanManageTeacher(): boolean {\n // Current user can perform any action on themselves\n if (props.currentUser.id === props.teacher.id)\n return true;\n\n // This permission allows total control over a classroom\n if (hasPermissions(PermissionName.ManageAllClassrooms))\n return true;\n\n // Regular teachers or owners cannot perform actions on admins in the classroom\n if (teacherIsAdmin)\n return false;\n\n return props.isOwner(props.currentUser.id);\n }\n\n const canManageTeacher = getCanManageTeacher();\n\n const actionDisabled = !canManageTeacher || props.readOnly;\n\n function getActions(): ActionOptions[] {\n // Non-owners cannot perform any actions on other classroom teachers\n if (!props.isOwner(props.currentUser.id))\n return [];\n\n const actions: ActionOptions[] = [];\n\n const disabledClassName = 'text-secondary disabled cursor-default';\n\n // Actions are different if the user item is for the current user\n const isManagingCurrentUser = props.currentUser.id === props.teacher.id;\n\n if (!isManagingCurrentUser) {\n if (props.isOwner(props.teacher.id)) {\n actions.push({\n order: 0,\n label: getPhrase('revokeOwnership'),\n appLink: getRevokeOwnershipAppLink(props.teacher.id, props.classroom.id),\n analyticsData: {\n id: props.teacher.id,\n classroomId: props.classroom.id\n },\n analyticsOptions: {\n actionType: UserAction.Demote,\n entity: EntityType.User,\n descriptor: AssocDescriptor.Classroom,\n workflowPhase: WorkflowPhase.Start,\n location: LocationContext.ManageClassroomTeacherListItem\n },\n className: actionDisabled ? disabledClassName : '',\n disabled: actionDisabled,\n tooltip: props.readOnly ? props.readonlyTooltip : !canManageTeacher ? getPhrase('cannotRevokeOwnershipFromAdmin') : ''\n });\n } else {\n actions.push({\n order: 0,\n label: getPhrase('assignAsOwner'),\n appLink: getAssignAsOwnerAppLink(props.teacher.id, props.classroom.id),\n analyticsData: {\n id: props.teacher.id,\n classroomId: props.classroom.id\n },\n analyticsOptions: {\n actionType: UserAction.Promote,\n entity: EntityType.User,\n descriptor: AssocDescriptor.Classroom,\n workflowPhase: WorkflowPhase.Start,\n location: LocationContext.ManageClassroomTeacherListItem\n },\n className: actionDisabled ? disabledClassName : '',\n disabled: actionDisabled,\n tooltip: props.readOnly ? props.readonlyTooltip : !canManageTeacher ? getPhrase('cannotAssignAdminAsOwner') : ''\n });\n }\n }\n\n actions.push({\n order: 10,\n label: isManagingCurrentUser ? getPhrase('leaveClassroom') : getPhrase('removeTeacher'),\n appLink: getRemoveTeachersAppLink(props.teacher.id, props.classroom.id),\n analyticsData: {\n id: props.classroom.id,\n userId: props.teacher.id\n },\n analyticsOptions: {\n actionType: UserAction.Dissociate,\n entity: EntityType.Classroom,\n descriptor: AssocDescriptor.User,\n workflowPhase: WorkflowPhase.Start,\n location: LocationContext.ManageClassroomTeacherListItem\n },\n className: actionDisabled ? disabledClassName : 'text-danger',\n disabled: actionDisabled,\n tooltip: props.readOnly ? props.readonlyTooltip : !canManageTeacher ? getPhrase('cannotRemoveAdmin') : ''\n });\n\n return actions;\n }\n\n return (\n <div className='d-flex align-items-center py-1 px-4'>\n {props.isOwner(props.currentUser.id) && (\n <Checkbox\n id={props.teacher.id}\n checked={props.checked}\n onChange={props.onToggleCheckbox}\n className='me-2'\n disabled={props.readOnly}\n />\n )}\n\n <div className={`${styles.avatarContainer} me-2`}>\n <Avatar\n imageCdnUrl={props.config.imageCdnUrl}\n initials={UserHelper.getInitials(props.teacher.name, props.teacher.surname)}\n imageUrl={props.teacher.avatar?.url}\n />\n </div>\n\n <p className={`${styles.name} me-2 text-truncate mb-0 text-nowrap`}>{UserHelper.getFullName(props.teacher)}</p>\n\n {!!teacherIsAdmin && (\n <div className={`classroom-pill text-white bg-navy`}>\n <Text namespace={namespace} phrase='admin' />\n </div>\n )}\n\n {(!teacherIsAdmin && props.isOwner(props.teacher.id)) && (\n <div className={`classroom-pill text-white bg-indigo`}>\n <Text namespace={namespace} phrase='owner' />\n </div>\n )}\n\n <MoreActions\n actions={getActions()}\n className='ms-auto'\n actionsDropdownClassName='btn btn-link'\n />\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AssocDescriptor, EntityType, LocationContext, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Checkbox } from 'libs/shared/components/forms/form-checkbox/Checkbox';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { useBulkCheckboxManager } from 'libs/shared/hooks/useBulkCheckboxManager';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { Classroom, Config, CurrentUser, User } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { ManageClassroomTeacherItem } from 'apps/classrooms/components/manage-classroom-teacher-item/ManageClassroomTeacherItem';\n\nimport { ManageClassroomTeachersEmptyState } from './empty-state/ManageClassroomTeachersEmptyState';\n\nconst namespace = 'classrooms.manageClassroomTeachers';\n\ninterface ManageClassroomTeachersProps {\n classroom: Classroom;\n isOwner: (teacherId: string) => boolean;\n currentUser: CurrentUser;\n teachers: User[];\n config: Config;\n readOnly?: boolean;\n}\n\nexport function ManageClassroomTeachers(props: ManageClassroomTeachersProps): JSX.Element {\n const CheckboxHelper = useBulkCheckboxManager(props.teachers);\n const selectionCount = CheckboxHelper.getSelected().length;\n\n function onClickBulkRemoveTeachers(): void {\n if (!selectionCount || !props.isOwner(props.currentUser.id) || props.readOnly)\n return;\n\n const teacherIds = CheckboxHelper.getSelected();\n\n AnalyticsHelper.logUserAction({\n id: props.classroom.id,\n teacherCount: teacherIds.length\n }, {\n entity: EntityType.Classroom,\n descriptor: AssocDescriptor.User,\n workflowPhase: WorkflowPhase.Start,\n actionType: UserAction.Dissociate,\n location: LocationContext.ManageClassroomTeachers\n });\n\n Core.AppLinkHelper.trigger({\n application: AppChannels.CLASSROOMS,\n action: Actions.Classrooms.REMOVE_TEACHERS,\n args: [props.classroom.id],\n params: {\n teacherIds\n }\n });\n }\n\n const edgeToEdge = useMediaQuery(MediaQueryStrings.XLDown);\n\n if (!props.teachers?.length)\n return <ManageClassroomTeachersEmptyState classroom={props.classroom} />;\n\n return (\n <>\n <div className={`d-flex align-items-center py-2 ${edgeToEdge ? 'ps-2' : 'ps-4'}`}>\n {props.isOwner(props.currentUser.id) && (\n <>\n <Checkbox\n id='manage-classroom-teachers-bulk'\n onChange={CheckboxHelper.onToggleBulk}\n checked={CheckboxHelper.bulkChecked}\n className='me-2'\n indeterminate={CheckboxHelper.hasSomeSelections()}\n disabled={props.readOnly}\n />\n\n <DivButton\n className={!selectionCount || props.readOnly ? 'me-auto text-light cursor-default' : 'me-auto'}\n onClick={onClickBulkRemoveTeachers}\n >\n <SvgContainer\n svgName={cvSvgLibrary.Delete}\n title={props.readOnly ? LanguageService.getPhrase(namespace, 'disabledByRostering') : LanguageService.getPhrase(namespace, 'delete')}\n tooltipPlacement='top'\n tooltipSpanHack\n />\n </DivButton>\n <Tooltip\n spanHack\n title={props.readOnly ? LanguageService.getPhrase(namespace, 'disabledByRostering') : ''}\n >\n <IconButton\n disabled={props.readOnly}\n svgName={cvSvgLibrary.Plus}\n className='btn btn-outline-dark ms-auto'\n appLink={props.readOnly\n ? null\n : {\n application: AppChannels.CLASSROOMS,\n action: Actions.Classrooms.ADD_TEACHERS,\n args: [props.classroom.id]\n }}\n analyticsData={{ id: props.classroom.id }}\n analyticsOptions={{\n entity: EntityType.Classroom,\n descriptor: AssocDescriptor.User,\n workflowPhase: WorkflowPhase.Start,\n actionType: UserAction.Associate,\n location: LocationContext.ManageClassroomTeachers\n }}\n >\n <Text namespace={namespace} phrase='addTeacher' />\n </IconButton>\n </Tooltip>\n </>\n )}\n </div>\n\n <ul className='striped-list list-unstyled'>\n {props.teachers.map(teacher => (\n <li key={teacher.id}>\n <ManageClassroomTeacherItem\n classroom={props.classroom}\n teacher={teacher}\n config={props.config}\n checked={CheckboxHelper.isChecked(teacher.id)}\n onToggleCheckbox={() => CheckboxHelper.onToggleItem(teacher.id)}\n currentUser={props.currentUser}\n isOwner={props.isOwner}\n readOnly={props.readOnly}\n readonlyTooltip={props.readOnly ? LanguageService.getPhrase(namespace, 'disabledByRostering') : ''}\n />\n </li>\n ))}\n </ul>\n </>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"heading\":\"FQwVf\",\"avatar\":\"mYQWy\",\"checkbox\":\"svGp0\",\"actionIcon\":\"rKbj_\",\"addTeachers\":\"qigWD\",\"teacherName\":\"SiD8n\",\"moreActions\":\"sAUZY\"};","import React from 'react';\n\nimport { PartialBreadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { PartialPillTabSelector } from 'libs/shared/components/pill-tab-selector/partial-loading/PartialPillTabSelector';\n\nimport styles from './partial-manage-classroom-teachers.scss';\n\nexport const PartialManageClassroomTeachers = React.memo(function(): JSX.Element {\n return (\n <div className='px-3'>\n {/* Heading */}\n <div className={`mb-1 partial-loading-background ${styles.heading}`} />\n\n {/* Breadcrumbs */}\n <div className='pb-3'>\n <PartialBreadcrumbs numItems={2} />\n </div>\n\n {/* Pill tab selector */}\n <div className='pb-2'>\n <PartialPillTabSelector />\n </div>\n\n <div className='d-flex align-items-center py-2'>\n {/* Checkbox */}\n <div className={`ms-2 me-4 partial-loading-background ${styles.checkbox}`} />\n {/* Delete action */}\n <div className={`me-auto partial-loading-background ${styles.actionIcon}`} />\n\n {/* Add new teachers button */}\n <div className={`partial-loading-background ${styles.addTeachers}`} />\n </div>\n\n {/* Teachers list */}\n <ul className='striped-list list-unstyled'>\n {Array(3).fill(null).map((teacher, i) => (\n <li key={i}>\n <div className='d-flex align-items-center py-1 px-4'>\n {/* Checkbox */}\n <div className={`me-2 partial-loading-background ${styles.checkbox}`} />\n\n {/* Avatar */}\n <div className={`me-2 partial-loading-background ${styles.avatar}`} />\n\n {/* Teacher name */}\n <div className='w-25'>\n <div className={`partial-loading-background ${styles.teacherName}`} />\n </div>\n\n {/* More actions */}\n <div className={`ms-auto partial-loading-background ${styles.moreActions}`} />\n </div>\n </li>\n ))}\n </ul>\n </div>\n );\n});","import React from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { RosteringAlert } from 'libs/shared/components/rostering/rostering-alert/RosteringAlert';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { Classroom, Config, CurrentUser, User } from 'libs/shared/interfaces';\n\nimport { ManageClassroomTeachersEmptyState, RosteredClassroomTeachersEmptyState } from 'apps/classrooms/components/manage-classroom-teachers/empty-state/ManageClassroomTeachersEmptyState';\nimport { ManageClassroomTeachers } from 'apps/classrooms/components/manage-classroom-teachers/ManageClassroomTeachers';\nimport { PartialManageClassroomTeachers } from 'apps/classrooms/components/manage-classroom-teachers/partial-loading/PartialManageClassroomTeachers';\nimport { ClassroomRequests } from 'apps/classrooms/flight-requests/ClassroomRequests';\nimport { useCheckClassroomPermissions } from 'apps/classrooms/hooks/useClassroomPermissions';\nimport { useHandleClassroomErrors } from 'apps/classrooms/hooks/useHandleClassroomErrors';\nimport { ClassroomLayout } from 'apps/classrooms/layouts/ClassroomLayout';\n\nconst namespace = 'classrooms.classroomTeachers';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ClassroomTeachersViewProps {\n id: string;\n}\n\nexport function ClassroomTeachersView(props: ClassroomTeachersViewProps): JSX.Element {\n const { hasShareFlowV2 } = useSettings(null);\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const classroom = Flight.useBasicFetch<Classroom>(currentUser.data &&\n ClassroomRequests.getClassroom(props.id, currentUser.data.id));\n const owners = Flight.useBasicFetch<User[]>(ClassroomRequests.getClassroomOwners(props.id));\n const staff = Flight.useBasicFetch<User[]>(\n currentUser.data?.customerId && ClassroomRequests.getClassroomStaff(props.id, currentUser.data.customerId)\n );\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const dispatch = useDispatch();\n const { isOwner: currentUserIsOwner } = useCheckClassroomPermissions(props.id);\n\n const isRostered = classroom.data?._integrations?.rostered;\n\n useSetPageMetadata({\n title: getPhrase('pageTitle', { classroomName: classroom.data?.name })\n });\n useHandleClassroomErrors(classroom);\n \n function isOwner(teacherId: string): boolean {\n if (teacherId === currentUser.data.id)\n return currentUserIsOwner;\n\n return owners.data.some(owner => owner.id.toString() === teacherId.toString());\n }\n\n function onTogglePin(shouldPin: boolean, onSuccess: () => void, onError: () => void): void {\n if (isRostered)\n return;\n const request = shouldPin\n ? ClassroomRequests.pinClassroom\n : ClassroomRequests.unpinClassroom;\n\n Flight.fetch(dispatch, request(classroom.data, onSuccess, onError));\n }\n\n if (!classroom.data || !staff.hasCompleted || !owners.hasCompleted || !config.data)\n return <PartialManageClassroomTeachers />;\n\n return (\n <ClassroomLayout\n classroom={classroom.data}\n currentUser={currentUser.data}\n onTogglePin={onTogglePin}\n activeTab='teachers'\n isRostered={isRostered}\n hasShareFlowV2={hasShareFlowV2}\n >\n {(() => {\n if (isRostered) {\n return (\n <>\n <RosteringAlert type='classroom'/>\n {!staff.data?.length ? (\n <RosteredClassroomTeachersEmptyState />\n ) : (\n <ManageClassroomTeachers\n classroom={classroom.data}\n teachers={staff.data}\n config={config.data}\n currentUser={currentUser.data}\n isOwner={isOwner}\n readOnly\n />\n )}\n </>\n );\n }\n\n if (staff.data?.length) {\n return (\n <ManageClassroomTeachers\n config={config.data}\n classroom={classroom.data}\n teachers={staff.data}\n currentUser={currentUser.data}\n isOwner={isOwner}\n readOnly={isRostered}\n />\n );\n }\n\n return <ManageClassroomTeachersEmptyState classroom={classroom.data}/>;\n })()}\n\n </ClassroomLayout>\n );\n}\n","import { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\n\ntype ClassroomExperience = 'none' | 'minimal' | 'full';\n\nexport function useClassroomExperience() {\n const { hasShareFlowV2, hasClassrooms, isLoadingSettings } = useSettings(null);\n const { hasPermissions, isLoaded, getGatedPermission } = usePermissions();\n\n function getExperience(): ClassroomExperience {\n if (!hasClassrooms)\n return 'none';\n\n if (getGatedPermission(PermissionName.ViewClassrooms) === 'soft-gate')\n return 'minimal';\n\n if (hasPermissions(PermissionName.ViewClassrooms))\n return 'full';\n \n if (hasShareFlowV2)\n return 'minimal';\n }\n\n return {\n experience: getExperience(),\n loading: isLoadingSettings || !isLoaded\n };\n}"],"names":["getPhrase","RosteringAlert","props","text","type","className","useBulkCheckboxManager","collection","options","idField","persistNamespace","initial","initialState","Map","items","forceUpdate","prevCollection","prevNamespace","reset","current","clear","isChecked","item","toString","get","isBulkChecked","length","every","setSelected","ids","forEach","id","set","map","i","join","preselectedIds","onToggleBulk","setValue","onToggleItem","nextItemState","getSelected","Array","from","keys","bulkChecked","deselectAll","hasSomeSelections","find","getSelectedCount","size","getMap","namespace","RosteredClassroomTeachersEmptyState","value","EmptyState","src","ImageUrls","Text","phrase","href","target","LanguageService","ManageClassroomTeachersEmptyState","icon","appLink","application","action","args","classroom","getRemoveTeachersAppLink","teacherId","classroomId","params","teacherIds","getAssignAsOwnerAppLink","getRevokeOwnershipAppLink","ManageClassroomTeacherItem","hasPermissions","usePermissions","teacherIsAdmin","UserHelper","teacher","UserRole","canManageTeacher","currentUser","PermissionName","isOwner","actionDisabled","readOnly","Checkbox","checked","onChange","onToggleCheckbox","disabled","Avatar","imageCdnUrl","config","initials","name","surname","imageUrl","avatar","url","actions","disabledClassName","isManagingCurrentUser","push","order","label","analyticsData","analyticsOptions","actionType","entity","descriptor","workflowPhase","location","tooltip","readonlyTooltip","userId","getActions","actionsDropdownClassName","ManageClassroomTeachers","CheckboxHelper","teachers","selectionCount","edgeToEdge","indeterminate","DivButton","onClick","AnalyticsHelper","teacherCount","SvgContainer","svgName","title","tooltipPlacement","tooltipSpanHack","Tooltip","spanHack","IconButton","key","PartialManageClassroomTeachers","numItems","PartialPillTabSelector","fill","ClassroomTeachersView","hasShareFlowV2","useSettings","UserRequests","data","ClassroomRequests","owners","staff","customerId","ConfigRequests","dispatch","currentUserIsOwner","isRostered","_integrations","rostered","some","owner","useSetPageMetadata","classroomName","useHandleClassroomErrors","hasCompleted","ClassroomLayout","onTogglePin","shouldPin","onSuccess","onError","request","activeTab","useClassroomExperience","hasClassrooms","isLoadingSettings","isLoaded","getGatedPermission","experience","loading"],"sourceRoot":""}
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[2888],{3218:(e,t,n)=>{n.d(t,{R:()=>S});var r=n(32735),i=n(69087),a=n(26136),s=n(39157),o=n(69186),l=n(86572),u=n(28972),c=n(83140),d=n(80845),m=n(23481),v=n(2102),f=n(36532),b=m.T.encloseNamespace("interactives.studentResponseList");function g(e){var t=Object.keys(e.markedAnswers).length;return r.createElement("div",{className:"d-flex justify-content-end pt-3"},r.createElement("div",null,!e.showSubmitButtonSpinner&&r.createElement("button",{className:"btn btn-link",onClick:e.onClickClose},b("close")),!!e.interactionsToMark.length&&r.createElement(r.Fragment,null,e.isDemo?r.createElement(f.u,{id:"submitAnswers",title:b("demoOnly"),spanHack:!0,spanHackClassName:"d-inline-flex"},r.createElement("button",{className:"btn btn-outline-dark pointer-events-none",disabled:!t},b("submitAnswers"))):r.createElement(v.m,{variant:"outline-dark",onClick:e.onClickSubmit,disabled:!t,showSpinner:e.showSubmitButtonSpinner},b("submitAnswers")))))}var k=m.T.encloseNamespace("interactives.studentResponseList");function y(e){var t=Object.keys(e.markedAnswers).length;return r.createElement("div",{className:"d-flex justify-content-between pb-3"},r.createElement("div",{className:"d-flex"},!!e.summary.unanswered&&r.createElement("div",{className:"bg-light rounded p-2 me-2"},r.createElement("strong",{className:"me-2"},k("unanswered")),e.summary.unanswered),r.createElement("div",{className:"bg-light rounded p-2 me-2"},r.createElement("strong",{className:"me-2"},k("score")),e.summary.awaitingMarking?r.createElement("em",null,k("pending")):"".concat(Math.round(100*e.summary.percentCorrect),"%"))),!!e.interactionsToMark.length&&r.createElement(r.Fragment,null,e.isDemo?r.createElement(f.u,{id:"submitAnswers",title:k("demoOnly"),spanHack:!0},r.createElement("button",{className:"btn btn-outline-dark pointer-events-none",disabled:!t},k("submitAnswers"))):r.createElement(v.m,{variant:"outline-dark",onClick:e.onClickSubmit,disabled:!t,showSpinner:e.showSubmitButtonSpinner},k("submitAnswers"))))}const h={awaitingMarking:"MvGb5"};function p(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,i,a,s,o=[],l=!0,u=!1;try{if(a=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=a.call(n)).done)&&(o.push(r.value),o.length!==t);l=!0);}catch(e){u=!0,i=e}finally{try{if(!l&&null!=n.return&&(s=n.return(),Object(s)!==s))return}finally{if(u)throw i}}return o}}(e,t)||function(e,t){if(e){if("string"==typeof e)return w(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)?w(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function w(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function S(e){var t,n,m,v,f=p(r.useState(!1),2),b=f[0],k=f[1],w=(t=r.useRef(null),n=p(r.useState(!1),2),m=n[0],v=n[1],r.useEffect(function(){t.current&&!m&&(v(!0),requestAnimationFrame(function(){return t.current.scrollIntoView({behavior:"smooth",block:"center"})}))},[t.current,m]),t),S=(0,s.Rt)(e.interactive,e.studentResults),A=(0,d.Q)(e.interactive),E=function(e,t){return e.filter(function(e){return c.A.isInteractionCorrect(e,(0,d.j_)(t))===u.w.AwaitingMarking})}(A,e.studentResults);function C(){k(!0),e.submitMarkedAnswers()}return r.createElement(r.Fragment,null,r.createElement(y,{summary:S,interactionsToMark:E,markedAnswers:e.markedAnswers,onClickSubmit:C,showSubmitButtonSpinner:b,isDemo:e.isDemo}),r.createElement("ul",{className:"list-unstyled"},A.map(function(t,n){var u,c=t.id.toString()===(null===(u=e.selectedInteractionId)||void 0===u?void 0:u.toString()),d=E.some(function(e){return e.id===t.id}),m=(0,a.B)(e.studentResults.user,e.anonymiseUsers),v="p-2 mb-3 rounded";return c&&(v+=" border-2 border-info shadow"),v+=d?" ".concat(h.awaitingMarking):" border",r.createElement("li",{key:n,className:v,ref:c?w:null},r.createElement("div",{className:"d-flex mb-2"},r.createElement(l.y,{interaction:t,iconClassName:"flex-shrink-0"})),e.reportsStyling?r.createElement(o.O,{interaction:t,studentResults:e.studentResults,markedStatus:(0,s.HI)(t.id,e.studentResults,e.markedAnswers),markInteraction:e.addMarkedAnswers,imageCdnUrl:e.imageCdnUrl,anonymisedUserName:m,className:"bg-light ps-2",showFeedback:!0,reportsStyling:!0,responseComponentClass:"mx-n2"}):r.createElement(i.d,{interaction:t,studentResults:e.studentResults,markedStatus:(0,s.HI)(t.id,e.studentResults,e.markedAnswers),markInteraction:e.addMarkedAnswers,imageCdnUrl:e.imageCdnUrl,anonymisedUserName:m,showFeedback:!0}))})),r.createElement(g,{interactionsToMark:E,markedAnswers:e.markedAnswers,onClickSubmit:C,onClickClose:e.onClickClose,showSubmitButtonSpinner:b,isDemo:e.isDemo}))}},94644:(e,t,n)=>{n.d(t,{r:()=>c});var r=n(50242),i=n(81886),a=n(67058),s=n(14553),o=n(49267),l=n(49075),u={notFound:a.d,forbidden:{rating:s.q,yearLevel:s.q,region:o.a,privacy:s.q},badRequest:l._,internalServerError:l._};function c(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(e){var a;a="number"==typeof e?e:e.status;var s=Object.assign(Object.assign({},u),t);a&&i.Q.Ry.isStatusCodeError(a)&&(a!==r.o.InternalServer?a!==r.o.NotFound?a!==r.o.Forbidden?n.badRequest||i.Q.Ry.throw(new s.badRequest):n.forbidden||i.Q.Ry.throw(new s.forbidden.privacy):n.notFound||i.Q.Ry.throw(new s.notFound):n.internalServerError||i.Q.Ry.throw(new l._))}}},54405:(e,t,n)=>{n.d(t,{X:()=>r});var r={interactive:function(){return{url:"/mocks/insights/interactive.json",key:"demo:interactive",normalize:!1}},interactiveMetadata:function(){return{url:"/mocks/insights/interactive-metadata.json",key:"demo:interactive:metadata",normalize:!1}},interactiveResults:function(){return{url:"/mocks/insights/interactive-results.json",key:"demo:interactive:results",normalize:!1}},videoViews:function(){return{url:"/mocks/insights/video-views.json",key:"demo:video:views",normalize:!1}},users:function(){return{url:"/mocks/insights/users.json",key:"demo:users",normalize:!1}},individualHeatmap:function(){return{url:"/mocks/insights/individual-heatmap.json",key:"demo:individual:heatmap",normalize:!1}},aggregateHeatmap:function(){return{url:"/mocks/insights/aggregate-heatmap.json",key:"demo:aggregate:heatmap",normalize:!1}}}},91286:(e,t,n)=>{n.d(t,{v:()=>s});var r=n(32735),i=n(94644);function a(e){return e.map(function(e){return e.statusCode}).join(":")}function s(e,t,n){var s=Array.isArray(e)?e:[e];(0,r.useEffect)(function(){s.forEach(function(e){(0,i.r)(e.statusCode,t,n)})},[a(s),t,n])}},93322:(e,t,n)=>{n.d(t,{F:()=>a});var r=n(32735),i=n(13126);function a(){r.useEffect(function(){return i.e.lockContentWidth(),function(){return i.e.unlockContentWidth()}},[])}},55588:(e,t,n)=>{n.r(t),n.d(t,{InteractiveStudentResultsDemoView:()=>h});var r=n(32735),i=n(23481),a=n(20354),s=n(2948),o=n(9193),l=n(26136),u=n(3218),c=n(9111),d=n(38143),m=n(39151),v=n(54405),f=n(82541),b=n(91286),g=n(93322);function k(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var y=i.T.encloseNamespace("shared.interactiveStudentResults");function h(e){var t,n,i,h,p,w=(h=(0,s.D)(d.g.ANONYMISE_USERS),p=1,function(e){if(Array.isArray(e))return e}(h)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,i,a,s,o=[],l=!0,u=!1;try{if(a=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=a.call(n)).done)&&(o.push(r.value),o.length!==t);l=!0);}catch(e){u=!0,i=e}finally{try{if(!l&&null!=n.return&&(s=n.return(),Object(s)!==s))return}finally{if(u)throw i}}return o}}(h,p)||function(e,t){if(e){if("string"==typeof e)return k(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)?k(e,t):void 0}}(h,p)||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];(0,g.F)();var S=a.a.useBasicFetch(v.X.interactiveMetadata()),A=a.a.useBasicFetch(v.X.interactive()),E=a.a.useBasicFetch(v.X.interactiveResults()),C=a.a.useBasicFetch(m.L.config());(0,b.v)([S,E]),(0,f.b)(S);var R=(0,o.D)(null===(t=A.data)||void 0===t?void 0:t.id,null===(n=S.data)||void 0===n?void 0:n.id,e.closePopup),I=R.markedAnswers,N=R.addMarkedAnswers,j=R.submitMarkedAnswers,M=null===(i=E.data)||void 0===i?void 0:i.students.find(function(t){var n,r,i,a,s,o;return e.userId?(null===(r=null===(n=t.user)||void 0===n?void 0:n.id)||void 0===r?void 0:r.toString())===(null===(i=e.userId)||void 0===i?void 0:i.toString()):!!e.sessionId&&(null===(s=null===(a=t.user)||void 0===a?void 0:a.sessionId)||void 0===s?void 0:s.toString())===(null===(o=e.sessionId)||void 0===o?void 0:o.toString())}),F=M?y("heading",{studentName:(0,l.B)(M.user,w)}):"",O=!!A.data&&!!E.data&&!!C.data;return r.createElement(c.G,{title:F,showLoadingSpinner:!O,closePopup:e.closePopup,size:"lg"},O&&r.createElement(u.R,{interactive:A.data,studentResults:M,markedAnswers:I,addMarkedAnswers:N,submitMarkedAnswers:j,imageCdnUrl:C.data.imageCdnUrl,selectedInteractionId:e.interactionId,onClickClose:e.closePopup,anonymiseUsers:w,reportsStyling:e.reportsStyling,isDemo:!0}))}}}]);
2
- //# sourceMappingURL=2888-2596e106a5-lite.chunk.js.map