@clickview/lite 0.65.1 → 0.65.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/languages/en.json +1 -1
  3. package/dist/scripts/3549-c61e7b47a9-lite.chunk.js +2 -0
  4. package/dist/scripts/3549-c61e7b47a9-lite.chunk.js.map +1 -0
  5. package/dist/scripts/{3717-8a97ddeb28-lite.chunk.js → 3717-ce609e100b-lite.chunk.js} +2 -2
  6. package/dist/scripts/3717-ce609e100b-lite.chunk.js.map +1 -0
  7. package/dist/scripts/6802-2f25f55146-lite.chunk.js +2 -0
  8. package/dist/scripts/{6802-3187f3ece9-lite.chunk.js.map → 6802-2f25f55146-lite.chunk.js.map} +1 -1
  9. package/dist/scripts/7033-6ab57dea83-lite.chunk.js +2 -0
  10. package/dist/scripts/7033-6ab57dea83-lite.chunk.js.map +1 -0
  11. package/dist/scripts/{7177-a1731c906a-lite.chunk.js → 7177-2844888842-lite.chunk.js} +2 -2
  12. package/dist/scripts/7177-2844888842-lite.chunk.js.map +1 -0
  13. package/dist/scripts/{bundle-4bdf2c81c7.min.js → bundle-ccf68491f0.min.js} +3 -3
  14. package/dist/scripts/{bundle-4bdf2c81c7.min.js.map → bundle-ccf68491f0.min.js.map} +1 -1
  15. package/package.json +1 -1
  16. package/dist/scripts/3549-e85af77dce-lite.chunk.js +0 -2
  17. package/dist/scripts/3549-e85af77dce-lite.chunk.js.map +0 -1
  18. package/dist/scripts/3717-8a97ddeb28-lite.chunk.js.map +0 -1
  19. package/dist/scripts/6802-3187f3ece9-lite.chunk.js +0 -2
  20. package/dist/scripts/7033-6333c374da-lite.chunk.js +0 -2
  21. package/dist/scripts/7033-6333c374da-lite.chunk.js.map +0 -1
  22. package/dist/scripts/7177-a1731c906a-lite.chunk.js.map +0 -1
  23. /package/dist/scripts/{bundle-4bdf2c81c7.min.js.LICENSE.txt → bundle-ccf68491f0.min.js.LICENSE.txt} +0 -0
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[6802],{92869:(e,t,r)=>{r.d(t,{t:()=>i});var n=r(48088),a=r(95846),i={preventScrollTop:function(){n.Radio.channel(a.G.SHELL).trigger("prevent:scroll:top")}}},34079:(e,t,r)=>{r.d(t,{O:()=>s});var n=r(32735),a=r(23481),i=r(40782),l=r(36532),c=a.T.encloseNamespace("interactives.pendingIndicator");function o(e){var t="d-flex align-items-center h-100";return t+=e.showLabel?" justify-content-between":" justify-content-center",e.className&&(t+=" ".concat(e.className)),t}function s(e){var t=function(){return n.createElement("div",{className:o(e)},!!e.showLabel&&n.createElement("em",null,c("pending")),n.createElement(i.O,null))};return e.title?n.createElement(l.u,{title:e.title,spanHack:!0,spanHackClassName:e.tooltipClassName||"h-100 w-100 d-flex align-items-center"},n.createElement(t,null)):n.createElement(t,null)}},97364:(e,t,r)=>{r.d(t,{C:()=>i,P:()=>a});var n=r(94892);function a(e,t){switch(e){case"score_desc":return[{id:t,desc:!0}];case"score_asc":return[{id:t,desc:!1}];default:return[]}}function i(e,t){return"marking_required"===e&&!t.awaitingMarking||"helping_hand"===e&&t.percentCorrect>=n.T.HIGH||"not_completed"===e&&!t.unanswered}},1704:(e,t,r)=>{r.d(t,{l:()=>s});var n=r(32735),a=r(23481),i=r(9111),l=r(13876);function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var o=a.T.encloseNamespace("shared.confirmationPopup");function s(e){var t,r,a=(t=n.useState(!1),r=2,function(e){if(Array.isArray(e))return e}(t)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,i,l,c=[],o=!0,s=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;o=!1}else for(;!(o=(n=i.call(r)).done)&&(c.push(n.value),c.length!==t);o=!0);}catch(e){s=!0,a=e}finally{try{if(!o&&null!=r.return&&(l=r.return(),Object(l)!==l))return}finally{if(s)throw a}}return c}}(t,r)||function(e,t){if(e){if("string"==typeof e)return c(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?c(e,t):void 0}}(t,r)||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.")}()),s=a[0],u=a[1];return n.createElement(i.G,{title:e.title,closePopup:e.closePopup},n.createElement(n.Fragment,null,e.children,n.createElement(l.u,null,n.createElement(l.u.Cancel,{onClick:e.closePopup,variant:e.cancelButtonVariant,text:e.cancelButtonText||o("cancel")}),n.createElement(l.u.Submit,{onClick:function(){u(!0),e.onClickConfirm()},text:e.confirmButtonText||o("confirm"),variant:e.confirmButtonVariant,showSpinner:s,disabled:e.disabledConfirmButton}))))}s.defaultProps={confirmButtonVariant:"primary",cancelButtonVariant:"link"}},56802:(e,t,r)=>{r.d(t,{x:()=>he});var n=r(32735),a=r(23481),i=r(92869),l=r(75896),c=r(9570),o=r(23232),s=r(83345),u="shared.interactionResponseList";function m(e){return n.createElement(n.Fragment,null,n.createElement(o.u,{className:"m-4"},n.createElement(o.u.Image,{src:function(){switch(e.filter){case"correct":return e.correctImageUrl;case"incorrect":return e.incorrectImageUrl;case"marking_required":return e.markingRequiredImageUrl;case"skipped":return e.skippedImageUrl}}(),className:"w-25 h-auto"}),n.createElement(o.u.Info,null,n.createElement(s.x,{namespace:u,phrase:function(){switch(e.filter){case"correct":return"correctEmptyState";case"incorrect":return"incorrectEmptyState";case"marking_required":return"markingRequiredEmptyState";case"skipped":return"skippedEmptyState"}}()}))))}function d(e){function t(t){return"rounded-pill bg-light ".concat(function(t){return t===e.filter}(t)?"bg-dark text-white":"")}return n.createElement("div",{className:"d-flex gap-2 m-3"},n.createElement("button",{className:t("marking_required"),onClick:function(){return e.toggleFilter("marking_required")}},n.createElement(s.x,{namespace:u,phrase:"markingRequired"})),n.createElement("button",{className:t("correct"),onClick:function(){return e.toggleFilter("correct")}},n.createElement(s.x,{namespace:u,phrase:"correct"})),n.createElement("button",{className:t("incorrect"),onClick:function(){return e.toggleFilter("incorrect")}},n.createElement(s.x,{namespace:u,phrase:"incorrect"})),n.createElement("button",{className:t("skipped"),onClick:function(){return e.toggleFilter("skipped")}},n.createElement(s.x,{namespace:u,phrase:"skipped"})))}var f=r(86572),p=a.T.encloseNamespace("interactives.interactionResponseListHeader");function g(e){var t,r=null===(t=e.interaction.data)||void 0===t?void 0:t.suggestedResponse;return n.createElement("div",{className:"rounded bg-white"},n.createElement("div",{className:"p-2 position-relative"},n.createElement("div",{className:"d-flex"},n.createElement(f.y,{interaction:e.interaction,iconClassName:"flex-shrink-0"})),!!r&&n.createElement("div",{className:"mt-2"},n.createElement("strong",null,p("suggestedResponse")),n.createElement("p",{className:"m-0"},r))))}var b=a.T.encloseNamespace("shared.submitMarkedAnswers");function v(e){return n.createElement("div",{className:"d-flex justify-content-end"},n.createElement("button",{className:"btn btn-outline-dark",onClick:e.submit,disabled:e.disabled},b("submitAnswers")))}var y=r(26136),h=r(39157),E=r(44113),w=r(36532),k=r(28972),I=r(83140),N=r(80845);const S={awaitingMarking:"PPNkp"};function C(e){return C="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},C(e)}function A(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var x="shared.interactionResponseList",U=a.T.encloseNamespace(x);function j(e){var t,r,a,i,l=(a=n.useState(),i=2,function(e){if(Array.isArray(e))return e}(a)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,i,l,c=[],o=!0,s=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;o=!1}else for(;!(o=(n=i.call(r)).done)&&(c.push(n.value),c.length!==t);o=!0);}catch(e){s=!0,a=e}finally{try{if(!o&&null!=r.return&&(l=r.return(),Object(l)!==l))return}finally{if(s)throw a}}return c}}(a,i)||function(e,t){if(e){if("string"==typeof e)return A(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?A(e,t):void 0}}(a,i)||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.")}()),u=l[0],f=l[1],p=(r=e.interaction,e.results.students.filter((function(e){return I.A.isInteractionCorrect(r,(0,N.j_)(e))===k.w.AwaitingMarking})).reduce((function(e,t){var r,n;return Object.assign(Object.assign({},e),function(e,t,r){return(t=function(e){var t=function(e){if("object"!=C(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=C(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==C(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}({},(null===(r=t.user)||void 0===r?void 0:r.id)||(null===(n=t.publicUser)||void 0===n?void 0:n.profileId),!0))}),{})),b=Object.keys(e.markedAnswers).length;if(!(null===(t=e.results.students)||void 0===t?void 0:t.length))return n.createElement("div",{className:"d-flex flex-column h-100"},n.createElement(o.u,{className:"bg-white rounded mt-2 py-5 flex-grow-1 justify-content-center"},n.createElement(o.u.Image,{src:e.emptyStateImageUrl,size:"small"}),n.createElement(o.u.Heading,null,U("emptyStateHeading")),n.createElement(o.u.Info,{className:"w-100"},U("emptyStateDescription"))));var j=e.results.students.filter((function(t){var r=(0,N.j_)(t),n=I.A.isInteractionCorrect(e.interaction,r),a={correct:k.w.Correct,incorrect:k.w.Incorrect,marking_required:k.w.AwaitingMarking,skipped:k.w.UnAnswered};return!u||u in a&&n===a[u]}));return n.createElement(n.Fragment,null,e.reportsStyling&&n.createElement(g,{interaction:e.interaction}),n.createElement("div",{className:e.reportsStyling?"d-flex justify-content-end":"d-flex align-items-center justify-content-between border-bottom border-light px-3 py-2"},!e.reportsStyling&&n.createElement("p",{className:"fw-semibold mb-0"},n.createElement(s.x,{namespace:x,phrase:"studentAnswers"})),!!Object.keys(p).length&&n.createElement(w.u,{id:"submitAnswers",title:U("demoOnly"),spanHack:e.isDemo},n.createElement("div",{className:"".concat(e.isDemo?"pointer-events-none":""," ").concat(e.reportsStyling?"mt-2":"")},n.createElement(v,{submit:e.submitMarkedAnswers,disabled:!b})))),n.createElement(n.Fragment,null,!e.reportsStyling&&n.createElement(d,{filter:u,toggleFilter:function(e){f(u===e?null:e)}}),!e.reportsStyling&&!j.length&&u&&n.createElement(m,{filter:u,markingRequiredImageUrl:e.markingRequiredImageUrl,correctImageUrl:e.correctImageUrl,incorrectImageUrl:e.incorrectImageUrl,skippedImageUrl:e.skippedImageUrl}),j&&n.createElement("ul",{className:"list-unstyled mb-0"},j.map((function(t,r){var a,i,l=(0,y.B)(t.user||t.publicUser,e.anonymiseUsers),o=p[(null===(a=t.user)||void 0===a?void 0:a.id)||(null===(i=t.publicUser)||void 0===i?void 0:i.profileId)],s=e.reportsStyling?"bg-white p-2":"bg-white px-3 pt-3 pb-2";return o&&(s+=" ".concat(S.awaitingMarking," my-1")),n.createElement("li",{key:r,className:"border-bottom"},e.reportsStyling?n.createElement(E.O,{interaction:e.interaction,studentResults:t,markedStatus:(0,h.HI)(e.interaction.id,t,e.markedAnswers),markInteraction:e.addMarkedAnswers,imageCdnUrl:e.imageCdnUrl,showStudentDetails:!0,anonymisedUserName:l,className:s,showFeedback:!0,reportsStyling:!0,responseComponentClass:"mx-n2"}):n.createElement(c.d,{interaction:e.interaction,studentResults:t,markedStatus:(0,h.HI)(e.interaction.id,t,e.markedAnswers),markInteraction:e.addMarkedAnswers,imageCdnUrl:e.imageCdnUrl,showStudentDetails:!0,anonymisedUserName:l,className:s,showFeedback:!0}))}))),e.reportsStyling&&!!p.length&&n.createElement("div",{className:"mt-2"},n.createElement(v,{submit:e.submitMarkedAnswers,disabled:!b}))))}var T=r(34079);function O(e){var t;return n.createElement("div",null,n.createElement("p",{className:"mb-0"},(t=e.interaction.data.sentence)?t.split(/({\d+})/).map((function(t,r){var a=t.match(/{(\d+)}/);if(a){var i=a[1],l=e.interaction.actionableItems.find((function(e){return+e.order==+i}));if(l)return n.createElement("span",{className:"bg-white border border-gray-300 rounded p-1 lh-lg",key:r},l.name)}return t})):""))}var M=r(79671);const R={row:"fXno_",answerImage:"pDAuW",answerWidth:"YHK27"};function q(e){var t,r;return(null===(r=l.m.first(null===(t=e.interaction)||void 0===t?void 0:t.actionableItems).data)||void 0===r?void 0:r.imageUrl)?n.createElement("div",{className:R.answerWidth},n.createElement(M.n,{interaction:e.interaction,size:"sm",showFeedback:!1,showCorrectnessIcons:!0,isDisplayOnly:!0})):n.createElement("ul",{className:"".concat(R.answerWidth," list-unstyled row g-2")},e.interaction.actionableItems.map((function(t){return n.createElement("li",{key:t.id,className:"col-12"},n.createElement("div",{className:"".concat(t.isCorrect?"bg-light-green border-green":"bg-light-red border-red"," rounded border py-1 px-2 m-0")},n.createElement("span",{className:"fw-semibold"},e.indexToLetter(t.order),". "),n.createElement("span",null,t.name)))})))}var W="shared.questionTable";function P(e){var t,r=null===(t=e.interaction.data)||void 0===t?void 0:t.suggestedResponse;return r?n.createElement("div",{className:"".concat(R.answerWidth," bg-light-blue rounded p-2 mb-2")},n.createElement("div",{className:"d-flex justify-content-between"},n.createElement("p",{className:"fw-semibold mb-2"},n.createElement(s.x,{namespace:W,phrase:"suggestedResponse"}))),n.createElement("p",{className:"mb-0"},r)):n.createElement(n.Fragment,null)}function B(e){return n.createElement("ul",{className:"list-unstyled d-flex gap-2"},e.interaction.actionableItems.map((function(t){return n.createElement("li",{key:t.id,className:"".concat(t.isCorrect?"bg-light-green border-green":"bg-light-red border-red"," rounded border px-2 py-1 mb-2 w-50")},n.createElement("span",{className:"fw-semibold"},e.indexToLetter(t.order),". "),n.createElement("span",null,t.name))})))}var _=r(40424);function D(e){var t=function(){switch(e.interaction.typeId){case _.Z9.MultipleChoice:return n.createElement(q,{interaction:e.interaction,indexToLetter:G});case _.Z9.TrueOrFalse:return n.createElement(B,{interaction:e.interaction,indexToLetter:G});case _.Z9.ShortAnswer:return n.createElement(P,{interaction:e.interaction});case _.Z9.MissingWord:return n.createElement(O,{interaction:e.interaction});default:return null}}();return t?n.createElement("div",{className:"w-100 mt-3"},t):n.createElement(n.Fragment,null)}var F=r(40782);function L(e){return L="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},L(e)}var H=a.T.encloseNamespace("shared.questionTable");function Z(e,t,r){var n=e.cells.find((function(e){return e.column.id===r})).value,a=t.cells.find((function(e){return e.column.id===r})).value;return n.awaitingMarking?-1:a.awaitingMarking||n.percentCorrect>=a.percentCorrect?1:-1}function K(e){var t;return n.createElement("div",{className:"d-flex ".concat(null!==(t=e.className)&&void 0!==t?t:"")},e.children)}function V(e){return n.createElement(K,{className:e.column.isSorted&&"fw-bold"},H(e.phraseKey))}function G(e){return String.fromCharCode(e+"A".charCodeAt(0))}var z=r(8246),Q=a.T.encloseNamespace("shared.questionTable");function $(e,t){var r=e.actionableItems.map((function(t,r){return{id:t.id,label:e.typeId===_.Z9.MultipleChoice?G(r):t.name,isCorrect:t.isCorrect,count:0}}));return t.students.forEach((function(t){var n=l.m.last(t.results).attempts,a=l.m.findWhere(n,{id:e.id});a&&a.answers.forEach((function(e){var t=l.m.findWhere(r,{id:e.id});t&&t.count++}))})),r}function J(e,t){var r=e.actionableItems.map((function(e){return{id:e.id,label:e.name,isCorrect:e.isCorrect,count:0}}));return r.push({label:Q("incorrect"),count:0,isCorrect:!1}),t.students.forEach((function(t){var n=l.m.last(t.results).attempts,a=l.m.findWhere(n,{id:e.id});a&&a.answers.forEach((function(e){var t=l.m.findWhere(r,{id:e.id});t&&e.status===z.N.Correct?t.count++:l.m.findWhere(r,{label:Q("incorrect")}).count++}))})),r}function X(e,t){var r=[{label:Q("correct"),isCorrect:!0,count:0},{label:Q("incorrect"),isCorrect:!1,count:0}];return t.students.forEach((function(t){var n=l.m.last(t.results).attempts,a=l.m.findWhere(n,{id:e.id});a&&a.answers.forEach((function(e){if(e.status===z.N.Correct&&l.m.findWhere(r,{label:Q("correct")}).count++,e.status===z.N.Incorrect&&l.m.findWhere(r,{label:Q("incorrect")}).count++,e.status===z.N.PendingReview){var t=l.m.findWhere(r,{label:Q("pending")});t||(r.push({label:Q("pending"),count:0,isCorrect:!1}),t=l.m.findWhere(r,{label:Q("pending")})),t.count++}}))})),r}var Y=r(83914),ee=r(35223),te="shared.questionTable",re=a.T.encloseNamespace(te);function ne(e){var t=function(){if(e.interaction&&e.results){var t;switch(e.interaction.typeId){case _.Z9.ShortAnswer:case _.Z9.Illustration:t=X;break;case _.Z9.MissingWord:t=J;break;case _.Z9.MultipleChoice:case _.Z9.TrueOrFalse:t=$}return t(e.interaction,e.results)}}(),r=null==t?void 0:t.reduce((function(e,t){return t.count>e?t.count:e}),0);function a(e){var t="border rounded me-2";return e.count?e.label===re("pending")?"".concat(t," border-blue bg-light-blue"):e.isCorrect?"".concat(t," border-green bg-light-green"):"".concat(t," border-red bg-light-red"):"".concat(t," border-light bg-light px-1")}return n.createElement("div",{className:"border border-light rounded p-3 mb-3"},n.createElement("div",{className:"d-flex align-items-center gap-2 mb-3"},n.createElement("div",{className:"rounded-circle bg-light-teal text-teal"},n.createElement(Y.x,{svgName:ee.vn.Lightbulb,size:Y.S.Large})),n.createElement("h2",{className:"h6 mb-0"},n.createElement("span",null,n.createElement(s.x,{namespace:te,phrase:"questionSummary"})))),n.createElement("div",{className:"d-flex gap-2"},n.createElement("div",{className:"max-w-25"},null==t?void 0:t.map((function(e){return n.createElement("p",{key:e.label,className:"text-truncate mb-2"},e.label)}))),n.createElement("div",{className:"flex-grow-1"},null==t?void 0:t.map((function(e,t){return n.createElement("div",{key:t,className:"d-flex mb-2"},n.createElement("div",{className:a(e),style:{width:"".concat(e.count/r*100,"%"),height:20}}),n.createElement("span",null,e.count))})))))}var ae=a.T.encloseNamespace("shared.selectedInteractionEmptyState");function ie(e){return n.createElement(o.u,{className:"rounded h-100 bg-white justify-content-center py-4"},n.createElement(o.u.Image,{src:e.emptyStateUrl,size:"small"}),n.createElement(o.u.Info,{className:"w-100"},ae("emptyStateText")))}var le=r(97364),ce=r(69674),oe=r(57266);function se(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}function ue(e){var t,r,a,c,o=(a=n.useState((0,le.P)(e.sortBy,"correctlyAnswered")),c=2,function(e){if(Array.isArray(e))return e}(a)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,i,l,c=[],o=!0,s=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;o=!1}else for(;!(o=(n=i.call(r)).done)&&(c.push(n.value),c.length!==t);o=!0);}catch(e){s=!0,a=e}finally{try{if(!o&&null!=r.return&&(l=r.return(),Object(l)!==l))return}finally{if(s)throw a}}return c}}(a,c)||function(e,t){if(e){if("string"==typeof e)return se(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?se(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.")}()),s=o[0],u=o[1],m=function(e,t,r,a){return n.useMemo((function(){var r=(0,N.Q)(e),n=r.reduce((function(e,t,r){return Object.assign(Object.assign({},e),function(e,t,r){return(t=function(e){var t=function(e){if("object"!=L(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=L(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==L(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}({},t.id,r))}),{}),i=r.map((function(e){return Object.assign(Object.assign({},e),{questionNumber:n[e.id],resultsSummary:(0,h.nq)(e,t)})}));if("correctlyAnswered"===(null==a?void 0:a.id)){var c=l.m.sortBy(i,(function(e){return e.resultsSummary.awaitingMarking?-1:e.resultsSummary.percentCorrect}));return a.desc?c.reverse():c}return i}),[r,a])}(e.interactive,e.results,e.refreshTable,l.m.first(s)),d=e.selectedInteractionId&&(0,h.Zs)(e.interactive,e.selectedInteractionId);return n.createElement("div",{className:"row"},n.createElement("div",{className:"col-6 flex-grow-1"},n.createElement(ce.i,{key:e.selectedInteractionId,columns:(r=e.showAnswersInTable,[{Header:function(e){var t=e.column;return n.createElement(V,{column:t,phraseKey:"#"})},accessor:"questionNumber",id:"index",Cell:function(e){var t=e.row.original.questionNumber;return n.createElement(K,null,t+1,".")},width:15,disableSortBy:!0},{Header:function(e){var t=e.column;return n.createElement(V,{column:t,phraseKey:"question"})},accessor:"data",Cell:function(e){var t=e.row.original,a=e.initialState.selectedRowIds,i=null==a?void 0:a[null==t?void 0:t.id];return n.createElement(K,{className:"flex-column"},n.createElement("div",{className:"".concat(i?"":"clamp-1"," pe-2")},n.createElement(f.y,{interaction:t,containerClassName:"d-flex"})),r&&i&&n.createElement(D,{interaction:t}))},disableSortBy:!0},{Header:function(e){var t=e.column;return n.createElement(V,{column:t,phraseKey:"score"})},accessor:"resultsSummary",id:"correctlyAnswered",Cell:function(e){var t=e.value,r=t.percentCorrect;return t.awaitingMarking?n.createElement(T.O,{title:H("markingRequired"),className:"flex-grow-1",tooltipClassName:"d-block",showLabel:!0}):n.createElement(F.O,{percentage:r,layout:F.I.LabelBefore})},width:60,sortDescFirst:!0,sortType:Z}]),data:m,theme:e.theme,onSelectRow:function(e){var t=e.original;i.t.preventScrollTop(),oe.e.updateParams({interactionId:t.id},{merge:!0})},initialSelectedRowIds:d?[d.id]:null,getRowId:function(e){return e.id},enableSort:!0,manualSort:!0,onSort:u,initialSortBy:s})),n.createElement("div",{className:"col-6 d-flex flex-column"},!e.reportsStyling&&e.selectedInteractionId&&!!(null===(t=e.results.students)||void 0===t?void 0:t.length)&&n.createElement(ne,{interaction:d,results:e.results}),n.createElement("div",{className:"border border-light rounded flex-grow-1"},!!d&&n.createElement(j,{interaction:d,results:e.results,markedAnswers:e.markedAnswers,addMarkedAnswers:e.addMarkedAnswers,submitMarkedAnswers:e.submitMarkedAnswers,imageCdnUrl:e.imageCdnUrl,anonymiseUsers:e.anonymiseUsers,emptyStateImageUrl:e.emptyStateImageUrl,markingRequiredImageUrl:e.markingRequiredImageUrl,correctImageUrl:e.correctImageUrl,incorrectImageUrl:e.incorrectImageUrl,skippedImageUrl:e.skippedImageUrl,reportsStyling:e.reportsStyling,isDemo:e.isDemo}),!d&&n.createElement(ie,{emptyStateUrl:e.selectQuestionImageUrl}))))}var me=r(9193),de=r(1704),fe=r(99742);const pe={partialInsights:"bk68v"};function ge(){return n.createElement("div",null,n.createElement("div",{className:"row g-3 mb-5"},n.createElement("div",{className:"col-6"},n.createElement("div",{className:"".concat(pe.partialInsights," rounded partial-loading-background")})),n.createElement("div",{className:"col-6"},n.createElement("div",{className:"".concat(pe.partialInsights," rounded partial-loading-background")}))))}function be(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var ve=a.T.encloseNamespace("shared.interactiveInsightsQuestionsView"),ye={table:"bg-white rounded border border-light h-100 pb-2",header:"border-bottom px-3 py-2 mb-2",headerCell:"d-flex align-items-center",cell:"",row:"px-3 py-2 bg-light-blue-hover",selectedRow:"bg-gray-100",sortIndicator:"ms-2"};function he(e){var t,r,a,i,l,c=(i=n.useState(!1),l=2,function(e){if(Array.isArray(e))return e}(i)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,i,l,c=[],o=!0,s=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;o=!1}else for(;!(o=(n=i.call(r)).done)&&(c.push(n.value),c.length!==t);o=!0);}catch(e){s=!0,a=e}finally{try{if(!o&&null!=r.return&&(l=r.return(),Object(l)!==l))return}finally{if(s)throw a}}return c}}(i,l)||function(e,t){if(e){if("string"==typeof e)return be(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?be(e,t):void 0}}(i,l)||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.")}()),o=c[0],s=c[1],u=(0,me.D)(null===(t=e.interactive)||void 0===t?void 0:t.id,null===(r=e.interactiveMetadata)||void 0===r?void 0:r.id,(function(){return s(!1)})),m=u.markedAnswers,d=u.addMarkedAnswers,f=u.submitMarkedAnswers;return n.createElement(n.Fragment,null,!e.hasDataLoaded&&n.createElement(ge,null),e.hasDataLoaded&&n.createElement(ue,{interactive:e.interactive,results:e.results,markedAnswers:m,addMarkedAnswers:d,submitMarkedAnswers:function(){return s(!0)},imageCdnUrl:e.config.imageCdnUrl,selectedInteractionId:e.interactionId,refreshTable:e.isFetching,emptyStateImageUrl:fe.W.Insights.NO_RESPONSES,selectQuestionImageUrl:fe.W.Insights.NO_DATA,anonymiseUsers:e.anonymiseUsers,sortBy:e.sortBy,showAnswersInTable:!0,theme:ye,correctImageUrl:fe.W.Insights.JIGSAW,incorrectImageUrl:fe.W.Insights.RED_JIGSAW,skippedImageUrl:fe.W.Insights.SKIPPED,markingRequiredImageUrl:fe.W.Insights.CLIPBOARD,isDemo:e.isDemo}),o&&n.createElement(de.l,{title:ve("markPopupTitle",{smartCount:null!==(a=Object.keys(m).length)&&void 0!==a?a:0}),closePopup:function(){return s(!1)},confirmButtonText:ve("submit"),confirmButtonVariant:"dark",onClickConfirm:f},n.createElement("p",null,ve("markPopupBody"))))}}}]);
2
+ //# sourceMappingURL=6802-2f25f55146-lite.chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scripts/6802-3187f3ece9-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/common/src/backbone/utils/ScrollHelper.ts","file:///app/packages/libs/shared/src/apps/analytics/components/pending-indicator/PendingIndicator.tsx","file:///app/packages/libs/shared/src/apps/analytics/utils/StudentTableUtils.ts","file:///app/packages/libs/shared/src/components/confirmation-popup/ConfirmationPopup.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListFilters.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListHeader.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/submit-marked-answers/SubmitMarkedAnswers.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/interaction-response-list.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseList.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMissingWord.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/question-table-answers.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMultipleChoice.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableShortAnswer.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableTrueOrFalse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/QuestionTableUtils.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummaryUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummary.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/selected-interaction-empty-state/SelectedInteractionEmptyState.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/QuestionTable.tsx","file:///app/packages/projects/lite/src/apps/insights/views/interactive/questions/partial-loading/partial-interactive-insights-questions.scss","file:///app/packages/projects/lite/src/apps/insights/views/interactive/questions/partial-loading/PartialInteractiveInsightsQuestions.tsx","file:///app/packages/projects/lite/src/apps/insights/components/interactive-insights-questions/InteractiveInsightsQuestions.tsx"],"sourcesContent":["import { Radio } from 'backbone';\n\nimport { CommonChannels } from '../constants/CommonChannels';\n\nexport const ScrollHelper = {\n // Will prevent scrolling to the top of the page when applinks are triggered\n preventScrollTop(): void {\n Radio.channel(CommonChannels.SHELL).trigger('prevent:scroll:top');\n }\n};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { PercentageIndicator } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\n\nconst namespace = 'interactives.pendingIndicator';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getClassName(props: PendingIndicatorProps): string {\n let className = 'd-flex align-items-center h-100';\n\n className += props.showLabel ? ' justify-content-between' : ' justify-content-center';\n\n if (props.className)\n className += ` ${props.className}`;\n\n return className;\n}\n\ninterface PendingIndicatorProps {\n title?: string;\n className?: string;\n showLabel?: boolean;\n tooltipClassName?: string;\n}\n\nexport function PendingIndicator(props: PendingIndicatorProps): JSX.Element {\n const Indicator = () => (\n <div className={getClassName(props)}>\n {!!props.showLabel &&\n <em>{getPhrase('pending')}</em>\n }\n <PercentageIndicator />\n </div>\n );\n\n if (!props.title)\n return <Indicator />;\n\n return (\n <Tooltip title={props.title} spanHack spanHackClassName={props.tooltipClassName || 'h-100 w-100 d-flex align-items-center'}>\n <Indicator />\n </Tooltip>\n );\n}","import { SortingRule } from 'react-table';\n\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { ScoreThresholdInsights } from 'libs/shared/constants/ScoreThresholds';\n\nexport type SortStudentsBy = 'score_desc' | 'score_asc';\n\nexport function getSortStudents(sortBy: SortStudentsBy, id: string): SortingRule<any>[] {\n switch (sortBy) {\n case 'score_desc': return [{ id, desc: true }];\n case 'score_asc': return [{ id, desc: false }];\n default: return [];\n }\n}\n\nexport type FilterStudentsBy = 'not_completed' | 'marking_required' | 'helping_hand';\n\nexport function shouldFilterStudent(filter: FilterStudentsBy, summary: ResultsSummary): boolean {\n if (filter === 'marking_required' && !summary.awaitingMarking)\n return true;\n\n if (filter === 'helping_hand' && summary.percentCorrect >= ScoreThresholdInsights.HIGH)\n return true;\n\n if (filter === 'not_completed' && !summary.unanswered)\n return true;\n \n return false;\n}\n\n","import * as React from 'react';\nimport { ButtonProps } from 'react-bootstrap';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { Popup } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { PopupViewProps } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.confirmationPopup';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ConfirmationPopupProps {\n title: string;\n onClickConfirm: () => void;\n confirmButtonText?: string;\n cancelButtonText?: string;\n confirmButtonVariant?: ButtonProps['variant'];\n cancelButtonVariant?: ButtonProps['variant'];\n disabledConfirmButton?: boolean;\n}\n\nConfirmationPopup.defaultProps = {\n confirmButtonVariant: 'primary',\n cancelButtonVariant: 'link'\n};\n\ntype PropTypes = React.PropsWithChildren<ConfirmationPopupProps & PopupViewProps>;\n\nexport function ConfirmationPopup(props: PropTypes): React.ReactElement {\n const [ showButtonSpinner, setShowButtonSpinner ] = React.useState(false);\n\n return (\n <Popup title={props.title} closePopup={props.closePopup}>\n <>\n {props.children}\n <PopupButtons>\n <PopupButtons.Cancel\n onClick={props.closePopup}\n variant={props.cancelButtonVariant}\n text={props.cancelButtonText || getPhrase('cancel')}\n />\n <PopupButtons.Submit\n onClick={() => { setShowButtonSpinner(true); props.onClickConfirm(); }}\n text={props.confirmButtonText || getPhrase('confirm')}\n variant={props.confirmButtonVariant}\n showSpinner={showButtonSpinner}\n disabled={props.disabledConfirmButton}\n />\n </PopupButtons>\n </>\n </Popup>\n );\n}","import React from 'react';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'shared.interactionResponseList';\n\nexport type InteractionResponseFilterType = 'marking_required' | 'correct' | 'incorrect' | 'skipped';\n\ninterface InteractionResponseListFiltersEmptyStatesProps {\n filter: InteractionResponseFilterType;\n markingRequiredImageUrl: string;\n correctImageUrl: string;\n incorrectImageUrl: string;\n skippedImageUrl: string;\n}\n\nexport function InteractionResponseListFiltersEmptyStates(props: InteractionResponseListFiltersEmptyStatesProps) {\n function getFilterEmptyStateImageUrl() {\n switch (props.filter) {\n case 'correct': return props.correctImageUrl;\n case 'incorrect': return props.incorrectImageUrl;\n case 'marking_required': return props.markingRequiredImageUrl;\n case 'skipped': return props.skippedImageUrl;\n }\n }\n\n function getFilterEmptyStatePhrase() {\n switch (props.filter) {\n case 'correct': return 'correctEmptyState';\n case 'incorrect': return 'incorrectEmptyState';\n case 'marking_required': return 'markingRequiredEmptyState';\n case 'skipped': return 'skippedEmptyState';\n }\n }\n\n return (\n <>\n <EmptyState className='m-4'>\n <EmptyState.Image src={getFilterEmptyStateImageUrl()} className='w-25 h-auto' />\n <EmptyState.Info>\n <Text namespace={namespace} phrase={getFilterEmptyStatePhrase()} />\n </EmptyState.Info>\n </EmptyState>\n </>\n );\n}\n\ninterface InteractionResponseListFiltersProps {\n filter: InteractionResponseFilterType;\n toggleFilter: (filter: InteractionResponseFilterType) => void\n}\n\nexport function InteractionResponseListFilters(props: InteractionResponseListFiltersProps) {\n function isFilterSelected(filterButton: InteractionResponseFilterType) {\n return filterButton === props.filter;\n }\n\n function getFilterClassName(filterButton: InteractionResponseFilterType) {\n return `rounded-pill bg-light ${isFilterSelected(filterButton) ? 'bg-dark text-white' : ''}`;\n }\n\n return (\n\n <div className='d-flex gap-2 m-3'>\n <button className={getFilterClassName('marking_required')} onClick={() => props.toggleFilter('marking_required')}>\n <Text namespace={namespace} phrase='markingRequired' />\n </button>\n <button className={getFilterClassName('correct')} onClick={() => props.toggleFilter('correct')}>\n <Text namespace={namespace} phrase='correct' />\n </button>\n <button className={getFilterClassName('incorrect')} onClick={() => props.toggleFilter('incorrect')}>\n <Text namespace={namespace} phrase='incorrect' />\n </button>\n <button className={getFilterClassName('skipped')} onClick={() => props.toggleFilter('skipped')}>\n <Text namespace={namespace} phrase='skipped' />\n </button>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { Interaction } from 'libs/shared/interfaces';\n\nconst namespace = 'interactives.interactionResponseListHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InteractionResponseListHeaderProps {\n interaction: Interaction;\n}\n\nexport function InteractionResponseListHeader(props: InteractionResponseListHeaderProps): JSX.Element {\n const suggestedResponse = props.interaction.data?.suggestedResponse;\n\n return (\n <div className='rounded bg-white'>\n <div className='p-2 position-relative'>\n <div className='d-flex'>\n <InteractionLabel\n interaction={props.interaction}\n iconClassName='flex-shrink-0'\n />\n </div>\n {!!suggestedResponse &&\n <div className='mt-2'>\n <strong>{getPhrase('suggestedResponse')}</strong>\n <p className='m-0'>{suggestedResponse}</p>\n </div>\n }\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nconst namespace = 'shared.submitMarkedAnswers';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SubmitMarkedAnswersProps {\n submit: () => void;\n disabled: boolean\n}\n\nexport function SubmitMarkedAnswers(props: SubmitMarkedAnswersProps): JSX.Element {\n return (\n <div className='d-flex justify-content-end'>\n <button\n className='btn btn-outline-dark'\n onClick={props.submit}\n disabled={props.disabled}\n >\n {getPhrase('submitAnswers')}\n </button>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"awaitingMarking\":\"PPNkp\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { InteractionResponseItem } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/InteractionResponseItem';\nimport { InteractionResponseFilterType, InteractionResponseListFilters, InteractionResponseListFiltersEmptyStates } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListFilters';\nimport { InteractionResponseListHeader } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListHeader';\nimport { SubmitMarkedAnswers } from 'libs/shared/apps/analytics/components/questions-list/submit-marked-answers/SubmitMarkedAnswers';\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { anonymiseUserName } from 'libs/shared/apps/analytics/utils/AnonymiseUserUtils';\nimport { getMarkedStatus } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { InteractionResponse } from 'libs/shared/components/interaction-response/InteractionResponse';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, InteractiveResultSet, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\nimport styles from './interaction-response-list.scss';\n\nconst namespace = 'shared.interactionResponseList';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getResponsesToMark(\n interaction: Interaction,\n studentResults: StudentResults[]\n): HashObject {\n const responsesToMark = studentResults.filter(s => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(\n interaction,\n getStudentResult(s)\n );\n return correctness === InteractionCorrectness.AwaitingMarking;\n });\n\n return responsesToMark.reduce((acc, s) => ({\n ...acc,\n [s.user?.id || s.publicUser?.profileId]: true\n }), {});\n}\n\ninterface InteractionResponseListProps {\n interaction: Interaction\n results: InteractiveResultSet;\n markedAnswers: MarkedAnswerHash;\n addMarkedAnswers: (answer: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n submitMarkedAnswers: () => void;\n imageCdnUrl: string;\n anonymiseUsers: boolean;\n reportsStyling?: boolean;\n emptyStateImageUrl: string;\n markingRequiredImageUrl: string;\n correctImageUrl: string;\n incorrectImageUrl: string;\n skippedImageUrl: string;\n isDemo?: boolean;\n}\n\nexport function InteractionResponseList(props: InteractionResponseListProps): JSX.Element {\n const [ filter, setFilter ] = React.useState<InteractionResponseFilterType>();\n\n const responsesToMark = getResponsesToMark(props.interaction, props.results.students);\n const numMarkedAnswers = Object.keys(props.markedAnswers).length;\n\n if (!props.results.students?.length)\n return (\n <div className='d-flex flex-column h-100'>\n <EmptyState className='bg-white rounded mt-2 py-5 flex-grow-1 justify-content-center'>\n <EmptyState.Image src={props.emptyStateImageUrl} size='small' />\n <EmptyState.Heading>\n {getPhrase('emptyStateHeading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('emptyStateDescription')}\n </EmptyState.Info>\n </EmptyState>\n </div>\n );\n\n\n function toggleFilter(selectedFilter: InteractionResponseFilterType) {\n setFilter(filter === selectedFilter ? null : selectedFilter);\n }\n\n function filterStudentResults() {\n return props.results.students.filter(s => {\n const result = getStudentResult(s);\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(props.interaction, result);\n\n const filterMap = {\n correct: InteractionCorrectness.Correct,\n incorrect: InteractionCorrectness.Incorrect,\n marking_required: InteractionCorrectness.AwaitingMarking,\n skipped: InteractionCorrectness.UnAnswered\n };\n\n return !filter || (filter in filterMap && correctness === filterMap[filter]);\n });\n }\n\n const filteredStudentResults = filterStudentResults();\n\n return (\n <>\n {props.reportsStyling && <InteractionResponseListHeader interaction={props.interaction} />}\n <div className={props.reportsStyling\n ? 'd-flex justify-content-end'\n : 'd-flex align-items-center justify-content-between border-bottom border-light px-3 py-2'\n }>\n {!props.reportsStyling && <p className='fw-semibold mb-0'><Text namespace={namespace} phrase='studentAnswers' /></p>}\n {!!Object.keys(responsesToMark).length &&\n <Tooltip id='submitAnswers' title={getPhrase('demoOnly')} spanHack={props.isDemo}>\n <div className={props.isDemo ? 'pointer-events-none' : ''}>\n <SubmitMarkedAnswers submit={props.submitMarkedAnswers} disabled={!numMarkedAnswers} />\n </div>\n </Tooltip>\n }\n </div>\n <>\n {!props.reportsStyling && <InteractionResponseListFilters filter={filter} toggleFilter={toggleFilter} />}\n\n {!props.reportsStyling && !filteredStudentResults.length && filter && (\n <InteractionResponseListFiltersEmptyStates\n filter={filter}\n markingRequiredImageUrl={props.markingRequiredImageUrl}\n correctImageUrl={props.correctImageUrl}\n incorrectImageUrl={props.incorrectImageUrl}\n skippedImageUrl={props.skippedImageUrl}\n />\n )}\n \n {filteredStudentResults && (\n <ul className='list-unstyled mb-0'>\n {filteredStudentResults.map((s, idx) => {\n const anonymisedUserName = anonymiseUserName(s.user || s.publicUser, props.anonymiseUsers);\n const markingRequired = responsesToMark[s.user?.id || s.publicUser?.profileId];\n\n let className = props.reportsStyling ? 'bg-white p-2' : 'bg-white px-3 pt-3 pb-2';\n\n if (markingRequired)\n className += ` ${styles.awaitingMarking}`;\n\n return (\n <li key={idx}>\n {props.reportsStyling ? (\n <InteractionResponse\n interaction={props.interaction}\n studentResults={s}\n markedStatus={getMarkedStatus(props.interaction.id, s, props.markedAnswers)}\n markInteraction={props.addMarkedAnswers}\n imageCdnUrl={props.imageCdnUrl}\n showStudentDetails\n anonymisedUserName={anonymisedUserName}\n className={className}\n showFeedback\n reportsStyling\n responseComponentClass='mx-n2'\n />\n ) : (\n <InteractionResponseItem\n interaction={props.interaction}\n studentResults={s}\n markedStatus={getMarkedStatus(props.interaction.id, s, props.markedAnswers)}\n markInteraction={props.addMarkedAnswers}\n imageCdnUrl={props.imageCdnUrl}\n showStudentDetails\n anonymisedUserName={anonymisedUserName}\n className={className}\n showFeedback\n />\n )}\n </li>\n );\n })}\n </ul>\n )}\n {props.reportsStyling && !!responsesToMark.length &&\n <div className='mt-2'>\n <SubmitMarkedAnswers submit={props.submitMarkedAnswers} disabled={!numMarkedAnswers} />\n </div>\n }\n </>\n </>\n );\n}","import React from 'react';\n\nimport { QuestionTableAnswersProps } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\n\nexport function QuestionTableMissingWord(props: QuestionTableAnswersProps) {\n const replacePlaceholders = (str: string) => {\n if (!str) return '';\n\n return str.split(/({\\d+})/).map((part, index) => {\n const match = part.match(/{(\\d+)}/);\n\n if (match) {\n const key = match[1];\n\n const replacement = props.interaction.actionableItems.find(answer => +answer.order === +key);\n\n\n if (replacement) {\n return <span className='bg-white border border-gray-300 rounded p-1 lh-lg' key={index}>{replacement.name}</span>;\n }\n }\n\n return part;\n });\n };\n\n return (\n <div>\n <p className='mb-0'>{replacePlaceholders(props.interaction.data.sentence)}</p>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"row\":\"fXno_\",\"answerImage\":\"pDAuW\",\"answerWidth\":\"YHK27\"};","import React from 'react';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { QuestionTableAnswersProps } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\nimport { MultipleChoiceInteractionAnswers } from 'libs/shared/components/interaction-answers/multiple-choice/MultipleChoiceInteractionAnswers';\n\nimport styles from './question-table-answers.scss';\n\nexport function QuestionTableMultipleChoice(props: QuestionTableAnswersProps) {\n const hasImages = !!ArrayHelper.first(props.interaction?.actionableItems).data?.imageUrl;\n\n if (!hasImages) {\n return (\n <ul className={`${styles.answerWidth} list-unstyled row g-2`}>\n {props.interaction.actionableItems.map(option => {\n return (\n <li key={option.id} className='col-12'>\n <div className={`${option.isCorrect ? 'bg-light-green border-green' : 'bg-light-red border-red'} rounded border py-1 px-2 m-0`}>\n <span className='fw-semibold'>{props.indexToLetter(option.order)}. </span>\n <span>{option.name}</span>\n </div>\n </li>\n );\n })}\n </ul>\n );\n }\n\n return (\n <div className={styles.answerWidth}>\n <MultipleChoiceInteractionAnswers\n interaction={props.interaction}\n size='sm'\n showFeedback={false}\n showCorrectnessIcons\n isDisplayOnly\n />\n </div>\n );\n}","import React from 'react';\n\nimport { QuestionTableAnswersProps } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport styles from './question-table-answers.scss';\n\nconst namespace = 'shared.questionTable';\n\nexport function QuestionTableShortAnswer(props: QuestionTableAnswersProps) {\n const suggestedResponse = props.interaction.data?.suggestedResponse;\n\n if (!suggestedResponse) return <></>;\n\n return (\n <div className={`${styles.answerWidth} bg-light-blue rounded p-2 mb-2`}>\n <div className='d-flex justify-content-between'>\n <p className='fw-semibold mb-2'>\n <Text namespace={namespace} phrase='suggestedResponse' />\n </p>\n </div>\n\n <p className='mb-0'>{suggestedResponse}</p>\n </div>\n );\n}","import React from 'react';\n\nimport { QuestionTableAnswersProps } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\n\n\nexport function QuestionTableTrueOrFalse(props: QuestionTableAnswersProps) {\n return (\n <ul className='list-unstyled d-flex gap-2'>\n {props.interaction.actionableItems.map(option => {\n return (\n <li\n key={option.id}\n className={`${option.isCorrect ? 'bg-light-green border-green' : 'bg-light-red border-red'} rounded border px-2 py-1 mb-2 w-50`}\n >\n <span className='fw-semibold'>{props.indexToLetter(option.order)}. </span>\n <span>{option.name}</span>\n </li>\n );\n })}\n </ul>\n );\n}","import React from 'react';\n\nimport { QuestionTableMissingWord } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMissingWord';\nimport { QuestionTableMultipleChoice } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMultipleChoice';\nimport { QuestionTableShortAnswer } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableShortAnswer';\nimport { QuestionTableTrueOrFalse } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableTrueOrFalse';\nimport { indexToLetter } from 'libs/shared/apps/analytics/components/questions-list/question-table/QuestionTableUtils';\nimport { Interaction, InteractionTypeId } from 'libs/shared/interfaces';\n\nexport interface QuestionTableAnswersProps {\n interaction: Interaction;\n indexToLetter?: (index: number) => string;\n}\n\nexport function QuestionTableAnswers(props: QuestionTableAnswersProps) {\n function getQuestionTableAnswerComponent(): JSX.Element {\n switch (props.interaction.typeId) {\n case InteractionTypeId.MultipleChoice:\n return <QuestionTableMultipleChoice interaction={props.interaction} indexToLetter={indexToLetter} />;\n case InteractionTypeId.TrueOrFalse:\n return <QuestionTableTrueOrFalse interaction={props.interaction} indexToLetter={indexToLetter} />;\n case InteractionTypeId.ShortAnswer:\n return <QuestionTableShortAnswer interaction={props.interaction} />;\n case InteractionTypeId.MissingWord:\n return <QuestionTableMissingWord interaction={props.interaction} />;\n default: return null;\n }\n }\n\n const QuestionTableAnswerComponent = getQuestionTableAnswerComponent();\n\n if (!QuestionTableAnswerComponent) return <></>;\n\n return (\n <div className='w-100 mt-3'>\n {QuestionTableAnswerComponent}\n </div>\n );\n}","import React from 'react';\nimport { Column, ColumnInstance, Row, SortingRule } from 'react-table';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { PendingIndicator } from 'libs/shared/apps/analytics/components/pending-indicator/PendingIndicator';\nimport { QuestionTableAnswers } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\nimport { InteractionWithResultsSummary } from 'libs/shared/apps/analytics/interfaces/InteractionWithResultsSummary';\nimport { getInteractionResultsSummary } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { PercentageIndicator, PercentageIndicatorLayout } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Interactive, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getInteractions } from 'libs/shared/utils/InteractiveHelper';\n\nconst namespace = 'shared.questionTable';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction sortScore(\n rowA: Row<InteractionWithResultsSummary>,\n rowB: Row<InteractionWithResultsSummary>,\n columnId: string\n): 1 | -1 {\n const cellA = rowA.cells.find(cell => cell.column.id === columnId).value;\n const cellB = rowB.cells.find(cell => cell.column.id === columnId).value;\n\n if (cellA.awaitingMarking)\n return -1;\n\n if (cellB.awaitingMarking)\n return 1;\n\n return cellA.percentCorrect >= cellB.percentCorrect\n ? 1\n : -1;\n}\ninterface CellWrapperProps {\n className?: string;\n}\n\nfunction CellWrapper(props: React.PropsWithChildren<CellWrapperProps>): JSX.Element {\n return (\n <div className={`d-flex ${props.className ?? ''}`}>\n {props.children}\n </div>\n );\n}\n\ninterface HeaderCellProps {\n column: ColumnInstance<InteractionWithResultsSummary>;\n phraseKey: string;\n}\n\nfunction HeaderCell(props: HeaderCellProps): JSX.Element {\n return (\n <CellWrapper className={props.column.isSorted && 'fw-bold'}>\n {getPhrase(props.phraseKey)}\n </CellWrapper>\n );\n}\n\nexport function getColumns(\n showAnswersInTable: boolean\n): Column<InteractionWithResultsSummary>[] {\n return [\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='#' />,\n accessor: 'questionNumber',\n id: 'index',\n Cell: ({ row: { original: { questionNumber } } }) => {\n return <CellWrapper>{questionNumber + 1}.</CellWrapper>;\n },\n width: 15,\n disableSortBy: true\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='question' />,\n accessor: 'data', // This isn't used but it's needed for the typings on row,\n Cell: ({ row: { original: interaction }, initialState: { selectedRowIds } }) => {\n const selectedRow = selectedRowIds?.[interaction?.id];\n\n return (\n <CellWrapper className='flex-column'>\n <div className={`${!selectedRow ? 'clamp-1' : ''} pe-2`}>\n <InteractionLabel interaction={interaction} containerClassName='d-flex' />\n </div>\n\n {showAnswersInTable && selectedRow && (\n <QuestionTableAnswers interaction={interaction} />\n )}\n </CellWrapper>\n );\n },\n disableSortBy: true\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='score' />,\n accessor: 'resultsSummary',\n id: 'correctlyAnswered',\n Cell: ({ value: { percentCorrect, awaitingMarking } }) => {\n if (awaitingMarking) {\n return (\n <PendingIndicator\n title={getPhrase('markingRequired')}\n className='flex-grow-1'\n tooltipClassName='d-block'\n showLabel\n />\n );\n }\n\n return (\n <PercentageIndicator\n percentage={percentCorrect}\n layout={PercentageIndicatorLayout.LabelBefore}\n />\n );\n },\n width: 60,\n sortDescFirst: true,\n sortType: sortScore\n }\n ];\n}\n\n/**\n * Returns memoized table data. To trigger a recalculation, toggle the value of `refreshData`.\n */\nexport function useGetTableData(\n interactive: Interactive,\n results: InteractiveResultSet,\n refreshData: boolean,\n sortBy?: SortingRule<InteractionWithResultsSummary>\n): InteractionWithResultsSummary[] {\n return React.useMemo(() => {\n const flattenedInteractions = getInteractions(interactive);\n const questionNumbers: HashObject = flattenedInteractions.reduce((acc, interaction, index) => ({\n ...acc, [interaction.id]: index\n }), {});\n\n const interactions = flattenedInteractions.map(i => ({\n ...i,\n questionNumber: questionNumbers[i.id],\n resultsSummary: getInteractionResultsSummary(i, results)\n }));\n\n if (sortBy?.id === 'correctlyAnswered') {\n const sorted = ArrayHelper.sortBy(interactions, interaction => {\n if (interaction.resultsSummary.awaitingMarking)\n return -1;\n\n return interaction.resultsSummary.percentCorrect;\n });\n\n return sortBy.desc ? sorted.reverse() : sorted;\n }\n\n return interactions;\n }, [ refreshData, sortBy ]);\n}\n\nexport function indexToLetter(index: number) {\n return String.fromCharCode(index + 'A'.charCodeAt(0));\n}","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { indexToLetter } from 'libs/shared/apps/analytics/components/questions-list/question-table/QuestionTableUtils';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, InteractionTypeId, InteractiveResultSet } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.questionTable';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface QuestionSummary {\n id?: string;\n count: number;\n isCorrect: boolean;\n label?: string | number;\n}\n\nexport function multipleChoiceSummary(\n interaction: Interaction,\n studentResults: InteractiveResultSet\n): QuestionSummary[] {\n const questionsSummary: QuestionSummary[] = interaction.actionableItems.map((item, i) => {\n return {\n id: item.id,\n label: interaction.typeId === InteractionTypeId.MultipleChoice ? indexToLetter(i) : item.name,\n isCorrect: item.isCorrect,\n count: 0\n };\n });\n\n studentResults.students.forEach(student => {\n const latestAttempts = ArrayHelper.last(student.results).attempts;\n const response = ArrayHelper.findWhere(latestAttempts, { id: interaction.id });\n\n if (!response) return;\n\n response.answers.forEach(answer => {\n const questionSummary = ArrayHelper.findWhere(questionsSummary, { id: answer.id });\n\n if (questionSummary)\n questionSummary.count++;\n });\n });\n\n return questionsSummary;\n}\n\nexport function missingWordSummary(interaction: Interaction, studentResults: InteractiveResultSet): QuestionSummary[] {\n const questionsSummary: QuestionSummary[] = interaction.actionableItems.map(item => {\n return {\n id: item.id,\n label: item.name,\n isCorrect: item.isCorrect,\n count: 0\n };\n });\n\n questionsSummary.push({\n label: getPhrase('incorrect'),\n count: 0,\n isCorrect: false\n });\n\n studentResults.students.forEach(student => {\n const latestAttempts = ArrayHelper.last(student.results).attempts;\n const response = ArrayHelper.findWhere(latestAttempts, { id: interaction.id });\n\n if (!response) return;\n\n response.answers.forEach(answer => {\n const questionSummary = ArrayHelper.findWhere(questionsSummary, { id: answer.id });\n\n if (questionSummary && answer.status === InteractiveAnswerStatus.Correct) {\n questionSummary.count++;\n } else {\n const incorrectSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('incorrect') });\n\n incorrectSummary.count++;\n }\n });\n });\n\n return questionsSummary;\n}\n\nexport function markedSummary(interaction: Interaction, studentResults: InteractiveResultSet): QuestionSummary[] {\n const questionsSummary: QuestionSummary[] = [\n {\n label: getPhrase('correct'),\n isCorrect: true,\n count: 0\n },\n {\n label: getPhrase('incorrect'),\n isCorrect: false,\n count: 0\n }\n ];\n\n studentResults.students.forEach(student => {\n const latestAttempts = ArrayHelper.last(student.results).attempts;\n const response = ArrayHelper.findWhere(latestAttempts, { id: interaction.id });\n\n if (!response) return;\n\n response.answers.forEach(answer => {\n if (answer.status === InteractiveAnswerStatus.Correct) {\n const correctSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('correct') });\n correctSummary.count++;\n }\n if (answer.status === InteractiveAnswerStatus.Incorrect) {\n const incorrectSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('incorrect') });\n incorrectSummary.count++;\n }\n if (answer.status === InteractiveAnswerStatus.PendingReview) {\n let pendingSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('pending') });\n\n if (!pendingSummary) {\n questionsSummary.push({\n label: getPhrase('pending'),\n count: 0,\n isCorrect: false\n });\n pendingSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('pending') });\n }\n\n pendingSummary.count++;\n }\n });\n });\n\n return questionsSummary;\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { markedSummary, missingWordSummary, multipleChoiceSummary, QuestionSummary } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummaryUtils';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Interaction, InteractionTypeId, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.questionTable';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface QuestionResultsSummaryProps {\n interaction: Interaction;\n results: InteractiveResultSet;\n}\n\nexport function QuestionResultsSummary(props: QuestionResultsSummaryProps) {\n const questionSummary = getQuestionSummary();\n const maxResponseCount = getMaxResponseCount();\n\n function getQuestionSummary(): QuestionSummary[] {\n if (!props.interaction || !props.results) return;\n\n let summaryMethod: (\n interaction: Interaction,\n results: InteractiveResultSet,\n interactionTypeId?: InteractionTypeId\n ) => QuestionSummary[];\n\n switch (props.interaction.typeId) {\n case InteractionTypeId.ShortAnswer:\n case InteractionTypeId.Illustration:\n summaryMethod = markedSummary;\n break;\n case InteractionTypeId.MissingWord:\n summaryMethod = missingWordSummary;\n break;\n case InteractionTypeId.MultipleChoice:\n case InteractionTypeId.TrueOrFalse:\n summaryMethod = multipleChoiceSummary;\n break;\n }\n\n return summaryMethod(props.interaction, props.results);\n }\n\n function getMaxResponseCount() {\n return questionSummary?.reduce((acc, summary) => summary.count > acc ? summary.count : acc, 0);\n }\n\n function getBarClassName(summary: QuestionSummary) {\n const className = 'border rounded me-2';\n\n if (!summary.count)\n return `${className} border-light bg-light px-1`;\n\n if (summary.label === getPhrase('pending'))\n return `${className} border-blue bg-light-blue`;\n\n if (summary.isCorrect)\n return `${className} border-green bg-light-green`;\n\n return `${className} border-red bg-light-red`;\n }\n\n return (\n <div className='border border-light rounded p-3 mb-3'>\n <div className='d-flex align-items-center gap-2 mb-3'>\n <div className='rounded-circle bg-light-teal text-teal'>\n <SvgContainer svgName={cvSvgLibrary.Lightbulb} size={SvgContainerSize.Large} />\n </div>\n <h2 className='h6 mb-0'>\n <span><Text namespace={namespace} phrase='questionSummary' /></span>\n </h2>\n </div>\n <div className='d-flex gap-2'>\n <div className='max-w-25'>\n {questionSummary?.map(summary => {\n return (\n <p key={summary.label} className='text-truncate mb-2'>{summary.label}</p>\n );\n })}\n </div>\n <div className='flex-grow-1'>\n {questionSummary?.map((summary, i) => {\n return (\n <div key={i} className='d-flex mb-2'>\n <div\n className={getBarClassName(summary)}\n style={{ width: `${(summary.count / maxResponseCount) * 100}%`, height: 20 }}>\n </div>\n <span>{summary.count}</span>\n </div>\n );\n })}\n </div>\n </div>\n </div>\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';\n\nconst namespace = 'shared.selectedInteractionEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SelectedInteractionEmptyStateProps {\n emptyStateUrl: string;\n}\n\nexport function SelectedInteractionEmptyState(props: SelectedInteractionEmptyStateProps): JSX.Element {\n return (\n <EmptyState className='rounded h-100 bg-white justify-content-center py-4'>\n <EmptyState.Image\n src={props.emptyStateUrl}\n size='small'\n />\n <EmptyState.Info className='w-100'>\n {getPhrase('emptyStateText')}\n </EmptyState.Info>\n </EmptyState>\n );\n}","import React from 'react';\nimport { Row, SortingRule } from 'react-table';\n\nimport { ScrollHelper } from 'libs/common/backbone/utils/ScrollHelper';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { InteractionResponseList } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseList';\nimport { QuestionResultsSummary } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummary';\nimport { SelectedInteractionEmptyState } from 'libs/shared/apps/analytics/components/questions-list/selected-interaction-empty-state/SelectedInteractionEmptyState';\nimport { InteractionWithResultsSummary } from 'libs/shared/apps/analytics/interfaces/InteractionWithResultsSummary';\nimport { getInteractionById } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { getSortStudents, SortStudentsBy } from 'libs/shared/apps/analytics/utils/StudentTableUtils';\nimport { Table, TableTheme } from 'libs/shared/components/table/Table';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interactive, InteractiveResultSet, StudentAnswer } from 'libs/shared/interfaces';\nimport { AppRouteHelper } from 'libs/shared/utils/AppRouteHelper';\n\nimport { getColumns, useGetTableData } from './QuestionTableUtils';\n\ninterface QuestionTableProps {\n interactive: Interactive;\n results: InteractiveResultSet;\n markedAnswers: { [id: string]: StudentAnswer };\n addMarkedAnswers: (answer: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n submitMarkedAnswers: () => void;\n editSuggestedResponse?: () => void;\n imageCdnUrl: string;\n selectQuestionImageUrl: string;\n anonymiseUsers: boolean;\n sortBy?: SortStudentsBy;\n emptyStateImageUrl: string;\n markingRequiredImageUrl?: string;\n correctImageUrl?: string;\n incorrectImageUrl?: string;\n skippedImageUrl?: string;\n\n /**\n * As the table data is memoized, it must be prompted to recalculate.\n * Toggle `refreshTable` to do so.\n */\n refreshTable: boolean;\n selectedInteractionId?: string;\n showAnswersInTable?: boolean;\n theme: TableTheme;\n reportsStyling?: boolean;\n isDemo?: boolean;\n}\n\nexport function QuestionTable(props: QuestionTableProps): JSX.Element {\n const [ sortBy, setSortBy ] = React.useState<SortingRule<InteractionWithResultsSummary>[]>(\n getSortStudents(props.sortBy, 'correctlyAnswered')\n );\n const data = useGetTableData(props.interactive, props.results, props.refreshTable, ArrayHelper.first(sortBy));\n\n const selectedInteraction = props.selectedInteractionId &&\n getInteractionById(props.interactive, props.selectedInteractionId);\n\n function onSelectRow({ original: interaction }: Row<InteractionWithResultsSummary>): void {\n ScrollHelper.preventScrollTop();\n\n AppRouteHelper.updateParams(\n { interactionId: interaction.id },\n { merge: true }\n );\n }\n\n return (\n <div className='row'>\n <div className='col-6 flex-grow-1'>\n <Table\n key={props.selectedInteractionId}\n columns={getColumns(props.showAnswersInTable)}\n data={data}\n theme={props.theme}\n onSelectRow={onSelectRow}\n initialSelectedRowIds={selectedInteraction ? [selectedInteraction.id] : null}\n getRowId={(row: InteractionWithResultsSummary) => row.id}\n enableSort\n manualSort\n onSort={setSortBy}\n initialSortBy={sortBy}\n />\n </div>\n <div className='col-6 d-flex flex-column'>\n {!props.reportsStyling && props.selectedInteractionId && !!props.results.students?.length && (\n <QuestionResultsSummary\n interaction={selectedInteraction}\n results={props.results}\n />\n )}\n\n <div className='border border-light rounded flex-grow-1'>\n {!!selectedInteraction &&\n <InteractionResponseList\n interaction={selectedInteraction}\n results={props.results}\n markedAnswers={props.markedAnswers}\n addMarkedAnswers={props.addMarkedAnswers}\n submitMarkedAnswers={props.submitMarkedAnswers}\n imageCdnUrl={props.imageCdnUrl}\n anonymiseUsers={props.anonymiseUsers}\n emptyStateImageUrl={props.emptyStateImageUrl}\n markingRequiredImageUrl={props.markingRequiredImageUrl}\n correctImageUrl={props.correctImageUrl}\n incorrectImageUrl={props.incorrectImageUrl}\n skippedImageUrl={props.skippedImageUrl}\n reportsStyling={props.reportsStyling}\n isDemo={props.isDemo}\n />\n }\n {!selectedInteraction && <SelectedInteractionEmptyState emptyStateUrl={props.selectQuestionImageUrl} />}\n </div>\n </div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialInsights\":\"bk68v\"};","import React from 'react';\n\nimport styles from './partial-interactive-insights-questions.scss';\n\nexport function PartialInteractiveInsightsQuestions() {\n return (\n <div>\n <div className='row g-3 mb-5'>\n <div className='col-6'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n <div className='col-6'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { QuestionTable } from 'libs/shared/apps/analytics/components/questions-list/question-table/QuestionTable';\nimport { useMarkAnswers } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { SortStudentsBy } from 'libs/shared/apps/analytics/utils/StudentTableUtils';\nimport { ConfirmationPopup } from 'libs/shared/components/confirmation-popup/ConfirmationPopup';\nimport { TableTheme } from 'libs/shared/components/table/Table';\nimport { Config, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport { PartialInteractiveInsightsQuestions } from 'apps/insights/views/interactive/questions/partial-loading/PartialInteractiveInsightsQuestions';\n\n\nconst namespace = 'shared.interactiveInsightsQuestionsView';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst theme: TableTheme = {\n table: 'bg-white rounded border border-light h-100 pb-2',\n header: 'border-bottom px-3 py-2 mb-2',\n headerCell: 'd-flex align-items-center',\n cell: '',\n row: `px-3 py-2 bg-light-blue-hover`,\n selectedRow: 'bg-gray-100',\n sortIndicator: 'ms-2'\n};\n\ninterface InteractiveInsightsQuestionsProps {\n interactionId: string;\n interactive: Interactive;\n interactiveMetadata: InteractiveMetadata;\n results: InteractiveResultSet;\n isFetching: boolean;\n config: Config;\n hasDataLoaded: boolean;\n anonymiseUsers: boolean;\n sortBy: SortStudentsBy;\n isDemo?: boolean;\n}\n\nexport function InteractiveInsightsQuestions(props: InteractiveInsightsQuestionsProps) {\n const [ showMarkConfirmationPopup, setShowMarkConfirmationPopup ] = React.useState(false);\n\n const { markedAnswers, addMarkedAnswers, submitMarkedAnswers } = useMarkAnswers(\n props.interactive?.id,\n props.interactiveMetadata?.id,\n () => setShowMarkConfirmationPopup(false)\n );\n\n return (\n <>\n {!props.hasDataLoaded && <PartialInteractiveInsightsQuestions />}\n\n {props.hasDataLoaded &&\n <QuestionTable\n interactive={props.interactive}\n results={props.results}\n markedAnswers={markedAnswers}\n addMarkedAnswers={addMarkedAnswers}\n submitMarkedAnswers={() => setShowMarkConfirmationPopup(true)}\n imageCdnUrl={props.config.imageCdnUrl}\n selectedInteractionId={props.interactionId}\n refreshTable={props.isFetching}\n emptyStateImageUrl={ImageUrls.Insights.NO_RESPONSES}\n selectQuestionImageUrl={ImageUrls.Insights.NO_DATA}\n anonymiseUsers={props.anonymiseUsers}\n sortBy={props.sortBy}\n showAnswersInTable\n theme={theme}\n correctImageUrl={ImageUrls.Insights.JIGSAW}\n incorrectImageUrl={ImageUrls.Insights.RED_JIGSAW}\n skippedImageUrl={ImageUrls.Insights.SKIPPED}\n markingRequiredImageUrl={ImageUrls.Insights.CLIPBOARD}\n isDemo={props.isDemo}\n />\n }\n\n {showMarkConfirmationPopup &&\n <ConfirmationPopup\n title={getPhrase('markPopupTitle', { smartCount: Object.keys(markedAnswers).length ?? 0 })}\n closePopup={() => setShowMarkConfirmationPopup(false)}\n confirmButtonText={getPhrase('submit')}\n confirmButtonVariant='dark'\n onClickConfirm={submitMarkedAnswers}\n >\n <p>{getPhrase('markPopupBody')}</p>\n </ConfirmationPopup>\n }\n </>\n );\n}"],"names":["ScrollHelper","preventScrollTop","Radio","trigger","getPhrase","getClassName","props","className","showLabel","PendingIndicator","Indicator","title","spanHack","spanHackClassName","tooltipClassName","getSortStudents","sortBy","id","desc","shouldFilterStudent","filter","summary","awaitingMarking","percentCorrect","unanswered","ConfirmationPopup","showButtonSpinner","setShowButtonSpinner","closePopup","children","onClick","variant","cancelButtonVariant","text","cancelButtonText","onClickConfirm","confirmButtonText","confirmButtonVariant","showSpinner","disabled","disabledConfirmButton","defaultProps","namespace","InteractionResponseListFiltersEmptyStates","EmptyState","src","correctImageUrl","incorrectImageUrl","markingRequiredImageUrl","skippedImageUrl","getFilterEmptyStateImageUrl","Text","phrase","getFilterEmptyStatePhrase","InteractionResponseListFilters","getFilterClassName","filterButton","isFilterSelected","toggleFilter","LanguageService","InteractionResponseListHeader","suggestedResponse","interaction","data","InteractionLabel","iconClassName","SubmitMarkedAnswers","submit","InteractionResponseList","setFilter","responsesToMark","results","students","s","InteractiveCorrectnessHelper","InteractionCorrectness","reduce","acc","user","publicUser","profileId","numMarkedAnswers","Object","keys","markedAnswers","length","emptyStateImageUrl","size","filteredStudentResults","result","correctness","filterMap","correct","incorrect","marking_required","skipped","reportsStyling","Tooltip","isDemo","submitMarkedAnswers","selectedFilter","map","idx","anonymisedUserName","anonymiseUsers","markingRequired","key","InteractionResponse","studentResults","markedStatus","markInteraction","addMarkedAnswers","imageCdnUrl","showStudentDetails","showFeedback","responseComponentClass","InteractionResponseItem","QuestionTableMissingWord","str","sentence","split","part","index","match","replacement","actionableItems","find","answer","order","name","QuestionTableMultipleChoice","ArrayHelper","imageUrl","MultipleChoiceInteractionAnswers","showCorrectnessIcons","isDisplayOnly","option","isCorrect","indexToLetter","QuestionTableShortAnswer","QuestionTableTrueOrFalse","QuestionTableAnswers","QuestionTableAnswerComponent","typeId","getQuestionTableAnswerComponent","sortScore","rowA","rowB","columnId","cellA","cells","cell","column","value","cellB","CellWrapper","HeaderCell","isSorted","phraseKey","String","fromCharCode","charCodeAt","multipleChoiceSummary","questionsSummary","item","i","label","count","forEach","student","latestAttempts","attempts","response","answers","questionSummary","missingWordSummary","push","status","InteractiveAnswerStatus","markedSummary","pendingSummary","QuestionResultsSummary","summaryMethod","getQuestionSummary","maxResponseCount","getBarClassName","SvgContainer","svgName","S","style","width","height","SelectedInteractionEmptyState","emptyStateUrl","QuestionTable","showAnswersInTable","setSortBy","interactive","refreshData","flattenedInteractions","questionNumbers","interactions","questionNumber","resultsSummary","sorted","reverse","useGetTableData","refreshTable","selectedInteraction","selectedInteractionId","Table","columns","Header","accessor","Cell","row","original","disableSortBy","selectedRowIds","initialState","selectedRow","containerClassName","PercentageIndicator","percentage","layout","sortDescFirst","sortType","theme","onSelectRow","AppRouteHelper","interactionId","merge","initialSelectedRowIds","getRowId","enableSort","manualSort","onSort","initialSortBy","selectQuestionImageUrl","PartialInteractiveInsightsQuestions","table","header","headerCell","sortIndicator","InteractiveInsightsQuestions","showMarkConfirmationPopup","setShowMarkConfirmationPopup","interactiveMetadata","hasDataLoaded","config","isFetching","ImageUrls","smartCount"],"sourceRoot":""}
1
+ {"version":3,"file":"scripts/6802-2f25f55146-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/common/src/backbone/utils/ScrollHelper.ts","file:///app/packages/libs/shared/src/apps/analytics/components/pending-indicator/PendingIndicator.tsx","file:///app/packages/libs/shared/src/apps/analytics/utils/StudentTableUtils.ts","file:///app/packages/libs/shared/src/components/confirmation-popup/ConfirmationPopup.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListFilters.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListHeader.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/submit-marked-answers/SubmitMarkedAnswers.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/interaction-response-list.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseList.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMissingWord.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/question-table-answers.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMultipleChoice.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableShortAnswer.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableTrueOrFalse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/QuestionTableUtils.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummaryUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummary.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/selected-interaction-empty-state/SelectedInteractionEmptyState.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/QuestionTable.tsx","file:///app/packages/projects/lite/src/apps/insights/views/interactive/questions/partial-loading/partial-interactive-insights-questions.scss","file:///app/packages/projects/lite/src/apps/insights/views/interactive/questions/partial-loading/PartialInteractiveInsightsQuestions.tsx","file:///app/packages/projects/lite/src/apps/insights/components/interactive-insights-questions/InteractiveInsightsQuestions.tsx"],"sourcesContent":["import { Radio } from 'backbone';\n\nimport { CommonChannels } from '../constants/CommonChannels';\n\nexport const ScrollHelper = {\n // Will prevent scrolling to the top of the page when applinks are triggered\n preventScrollTop(): void {\n Radio.channel(CommonChannels.SHELL).trigger('prevent:scroll:top');\n }\n};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { PercentageIndicator } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\n\nconst namespace = 'interactives.pendingIndicator';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getClassName(props: PendingIndicatorProps): string {\n let className = 'd-flex align-items-center h-100';\n\n className += props.showLabel ? ' justify-content-between' : ' justify-content-center';\n\n if (props.className)\n className += ` ${props.className}`;\n\n return className;\n}\n\ninterface PendingIndicatorProps {\n title?: string;\n className?: string;\n showLabel?: boolean;\n tooltipClassName?: string;\n}\n\nexport function PendingIndicator(props: PendingIndicatorProps): JSX.Element {\n const Indicator = () => (\n <div className={getClassName(props)}>\n {!!props.showLabel &&\n <em>{getPhrase('pending')}</em>\n }\n <PercentageIndicator />\n </div>\n );\n\n if (!props.title)\n return <Indicator />;\n\n return (\n <Tooltip title={props.title} spanHack spanHackClassName={props.tooltipClassName || 'h-100 w-100 d-flex align-items-center'}>\n <Indicator />\n </Tooltip>\n );\n}","import { SortingRule } from 'react-table';\n\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { ScoreThresholdInsights } from 'libs/shared/constants/ScoreThresholds';\n\nexport type SortStudentsBy = 'score_desc' | 'score_asc';\n\nexport function getSortStudents(sortBy: SortStudentsBy, id: string): SortingRule<any>[] {\n switch (sortBy) {\n case 'score_desc': return [{ id, desc: true }];\n case 'score_asc': return [{ id, desc: false }];\n default: return [];\n }\n}\n\nexport type FilterStudentsBy = 'not_completed' | 'marking_required' | 'helping_hand';\n\nexport function shouldFilterStudent(filter: FilterStudentsBy, summary: ResultsSummary): boolean {\n if (filter === 'marking_required' && !summary.awaitingMarking)\n return true;\n\n if (filter === 'helping_hand' && summary.percentCorrect >= ScoreThresholdInsights.HIGH)\n return true;\n\n if (filter === 'not_completed' && !summary.unanswered)\n return true;\n \n return false;\n}\n\n","import * as React from 'react';\nimport { ButtonProps } from 'react-bootstrap';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { Popup } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { PopupViewProps } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.confirmationPopup';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ConfirmationPopupProps {\n title: string;\n onClickConfirm: () => void;\n confirmButtonText?: string;\n cancelButtonText?: string;\n confirmButtonVariant?: ButtonProps['variant'];\n cancelButtonVariant?: ButtonProps['variant'];\n disabledConfirmButton?: boolean;\n}\n\nConfirmationPopup.defaultProps = {\n confirmButtonVariant: 'primary',\n cancelButtonVariant: 'link'\n};\n\ntype PropTypes = React.PropsWithChildren<ConfirmationPopupProps & PopupViewProps>;\n\nexport function ConfirmationPopup(props: PropTypes): React.ReactElement {\n const [ showButtonSpinner, setShowButtonSpinner ] = React.useState(false);\n\n return (\n <Popup title={props.title} closePopup={props.closePopup}>\n <>\n {props.children}\n <PopupButtons>\n <PopupButtons.Cancel\n onClick={props.closePopup}\n variant={props.cancelButtonVariant}\n text={props.cancelButtonText || getPhrase('cancel')}\n />\n <PopupButtons.Submit\n onClick={() => { setShowButtonSpinner(true); props.onClickConfirm(); }}\n text={props.confirmButtonText || getPhrase('confirm')}\n variant={props.confirmButtonVariant}\n showSpinner={showButtonSpinner}\n disabled={props.disabledConfirmButton}\n />\n </PopupButtons>\n </>\n </Popup>\n );\n}","import React from 'react';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'shared.interactionResponseList';\n\nexport type InteractionResponseFilterType = 'marking_required' | 'correct' | 'incorrect' | 'skipped';\n\ninterface InteractionResponseListFiltersEmptyStatesProps {\n filter: InteractionResponseFilterType;\n markingRequiredImageUrl: string;\n correctImageUrl: string;\n incorrectImageUrl: string;\n skippedImageUrl: string;\n}\n\nexport function InteractionResponseListFiltersEmptyStates(props: InteractionResponseListFiltersEmptyStatesProps) {\n function getFilterEmptyStateImageUrl() {\n switch (props.filter) {\n case 'correct': return props.correctImageUrl;\n case 'incorrect': return props.incorrectImageUrl;\n case 'marking_required': return props.markingRequiredImageUrl;\n case 'skipped': return props.skippedImageUrl;\n }\n }\n\n function getFilterEmptyStatePhrase() {\n switch (props.filter) {\n case 'correct': return 'correctEmptyState';\n case 'incorrect': return 'incorrectEmptyState';\n case 'marking_required': return 'markingRequiredEmptyState';\n case 'skipped': return 'skippedEmptyState';\n }\n }\n\n return (\n <>\n <EmptyState className='m-4'>\n <EmptyState.Image src={getFilterEmptyStateImageUrl()} className='w-25 h-auto' />\n <EmptyState.Info>\n <Text namespace={namespace} phrase={getFilterEmptyStatePhrase()} />\n </EmptyState.Info>\n </EmptyState>\n </>\n );\n}\n\ninterface InteractionResponseListFiltersProps {\n filter: InteractionResponseFilterType;\n toggleFilter: (filter: InteractionResponseFilterType) => void\n}\n\nexport function InteractionResponseListFilters(props: InteractionResponseListFiltersProps) {\n function isFilterSelected(filterButton: InteractionResponseFilterType) {\n return filterButton === props.filter;\n }\n\n function getFilterClassName(filterButton: InteractionResponseFilterType) {\n return `rounded-pill bg-light ${isFilterSelected(filterButton) ? 'bg-dark text-white' : ''}`;\n }\n\n return (\n\n <div className='d-flex gap-2 m-3'>\n <button className={getFilterClassName('marking_required')} onClick={() => props.toggleFilter('marking_required')}>\n <Text namespace={namespace} phrase='markingRequired' />\n </button>\n <button className={getFilterClassName('correct')} onClick={() => props.toggleFilter('correct')}>\n <Text namespace={namespace} phrase='correct' />\n </button>\n <button className={getFilterClassName('incorrect')} onClick={() => props.toggleFilter('incorrect')}>\n <Text namespace={namespace} phrase='incorrect' />\n </button>\n <button className={getFilterClassName('skipped')} onClick={() => props.toggleFilter('skipped')}>\n <Text namespace={namespace} phrase='skipped' />\n </button>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { Interaction } from 'libs/shared/interfaces';\n\nconst namespace = 'interactives.interactionResponseListHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InteractionResponseListHeaderProps {\n interaction: Interaction;\n}\n\nexport function InteractionResponseListHeader(props: InteractionResponseListHeaderProps): JSX.Element {\n const suggestedResponse = props.interaction.data?.suggestedResponse;\n\n return (\n <div className='rounded bg-white'>\n <div className='p-2 position-relative'>\n <div className='d-flex'>\n <InteractionLabel\n interaction={props.interaction}\n iconClassName='flex-shrink-0'\n />\n </div>\n {!!suggestedResponse &&\n <div className='mt-2'>\n <strong>{getPhrase('suggestedResponse')}</strong>\n <p className='m-0'>{suggestedResponse}</p>\n </div>\n }\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nconst namespace = 'shared.submitMarkedAnswers';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SubmitMarkedAnswersProps {\n submit: () => void;\n disabled: boolean\n}\n\nexport function SubmitMarkedAnswers(props: SubmitMarkedAnswersProps): JSX.Element {\n return (\n <div className='d-flex justify-content-end'>\n <button\n className='btn btn-outline-dark'\n onClick={props.submit}\n disabled={props.disabled}\n >\n {getPhrase('submitAnswers')}\n </button>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"awaitingMarking\":\"PPNkp\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { InteractionResponseItem } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/InteractionResponseItem';\nimport { InteractionResponseFilterType, InteractionResponseListFilters, InteractionResponseListFiltersEmptyStates } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListFilters';\nimport { InteractionResponseListHeader } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListHeader';\nimport { SubmitMarkedAnswers } from 'libs/shared/apps/analytics/components/questions-list/submit-marked-answers/SubmitMarkedAnswers';\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { anonymiseUserName } from 'libs/shared/apps/analytics/utils/AnonymiseUserUtils';\nimport { getMarkedStatus } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { InteractionResponse } from 'libs/shared/components/interaction-response/InteractionResponse';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, InteractiveResultSet, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\nimport styles from './interaction-response-list.scss';\n\nconst namespace = 'shared.interactionResponseList';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getResponsesToMark(\n interaction: Interaction,\n studentResults: StudentResults[]\n): HashObject {\n const responsesToMark = studentResults.filter(s => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(\n interaction,\n getStudentResult(s)\n );\n return correctness === InteractionCorrectness.AwaitingMarking;\n });\n\n return responsesToMark.reduce((acc, s) => ({\n ...acc,\n [s.user?.id || s.publicUser?.profileId]: true\n }), {});\n}\n\ninterface InteractionResponseListProps {\n interaction: Interaction\n results: InteractiveResultSet;\n markedAnswers: MarkedAnswerHash;\n addMarkedAnswers: (answer: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n submitMarkedAnswers: () => void;\n imageCdnUrl: string;\n anonymiseUsers: boolean;\n reportsStyling?: boolean;\n emptyStateImageUrl: string;\n markingRequiredImageUrl: string;\n correctImageUrl: string;\n incorrectImageUrl: string;\n skippedImageUrl: string;\n isDemo?: boolean;\n}\n\nexport function InteractionResponseList(props: InteractionResponseListProps): JSX.Element {\n const [ filter, setFilter ] = React.useState<InteractionResponseFilterType>();\n\n const responsesToMark = getResponsesToMark(props.interaction, props.results.students);\n const numMarkedAnswers = Object.keys(props.markedAnswers).length;\n\n if (!props.results.students?.length)\n return (\n <div className='d-flex flex-column h-100'>\n <EmptyState className='bg-white rounded mt-2 py-5 flex-grow-1 justify-content-center'>\n <EmptyState.Image src={props.emptyStateImageUrl} size='small' />\n <EmptyState.Heading>\n {getPhrase('emptyStateHeading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('emptyStateDescription')}\n </EmptyState.Info>\n </EmptyState>\n </div>\n );\n\n\n function toggleFilter(selectedFilter: InteractionResponseFilterType) {\n setFilter(filter === selectedFilter ? null : selectedFilter);\n }\n\n function filterStudentResults() {\n return props.results.students.filter(s => {\n const result = getStudentResult(s);\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(props.interaction, result);\n\n const filterMap = {\n correct: InteractionCorrectness.Correct,\n incorrect: InteractionCorrectness.Incorrect,\n marking_required: InteractionCorrectness.AwaitingMarking,\n skipped: InteractionCorrectness.UnAnswered\n };\n\n return !filter || (filter in filterMap && correctness === filterMap[filter]);\n });\n }\n\n const filteredStudentResults = filterStudentResults();\n\n return (\n <>\n {props.reportsStyling && <InteractionResponseListHeader interaction={props.interaction} />}\n <div className={props.reportsStyling\n ? 'd-flex justify-content-end'\n : 'd-flex align-items-center justify-content-between border-bottom border-light px-3 py-2'\n }>\n {!props.reportsStyling && <p className='fw-semibold mb-0'><Text namespace={namespace} phrase='studentAnswers' /></p>}\n {!!Object.keys(responsesToMark).length &&\n <Tooltip id='submitAnswers' title={getPhrase('demoOnly')} spanHack={props.isDemo}>\n <div className={`${props.isDemo ? 'pointer-events-none' : ''} ${props.reportsStyling ? 'mt-2' : ''}`}>\n <SubmitMarkedAnswers submit={props.submitMarkedAnswers} disabled={!numMarkedAnswers} />\n </div>\n </Tooltip>\n }\n </div>\n <>\n {!props.reportsStyling && <InteractionResponseListFilters filter={filter} toggleFilter={toggleFilter} />}\n\n {!props.reportsStyling && !filteredStudentResults.length && filter && (\n <InteractionResponseListFiltersEmptyStates\n filter={filter}\n markingRequiredImageUrl={props.markingRequiredImageUrl}\n correctImageUrl={props.correctImageUrl}\n incorrectImageUrl={props.incorrectImageUrl}\n skippedImageUrl={props.skippedImageUrl}\n />\n )}\n \n {filteredStudentResults && (\n <ul className='list-unstyled mb-0'>\n {filteredStudentResults.map((s, idx) => {\n const anonymisedUserName = anonymiseUserName(s.user || s.publicUser, props.anonymiseUsers);\n const markingRequired = responsesToMark[s.user?.id || s.publicUser?.profileId];\n\n let className = props.reportsStyling ? 'bg-white p-2' : 'bg-white px-3 pt-3 pb-2';\n\n if (markingRequired)\n className += ` ${styles.awaitingMarking} my-1`;\n\n return (\n <li key={idx} className='border-bottom'>\n {props.reportsStyling ? (\n <InteractionResponse\n interaction={props.interaction}\n studentResults={s}\n markedStatus={getMarkedStatus(props.interaction.id, s, props.markedAnswers)}\n markInteraction={props.addMarkedAnswers}\n imageCdnUrl={props.imageCdnUrl}\n showStudentDetails\n anonymisedUserName={anonymisedUserName}\n className={className}\n showFeedback\n reportsStyling\n responseComponentClass='mx-n2'\n />\n ) : (\n <InteractionResponseItem\n interaction={props.interaction}\n studentResults={s}\n markedStatus={getMarkedStatus(props.interaction.id, s, props.markedAnswers)}\n markInteraction={props.addMarkedAnswers}\n imageCdnUrl={props.imageCdnUrl}\n showStudentDetails\n anonymisedUserName={anonymisedUserName}\n className={className}\n showFeedback\n />\n )}\n </li>\n );\n })}\n </ul>\n )}\n {props.reportsStyling && !!responsesToMark.length &&\n <div className='mt-2'>\n <SubmitMarkedAnswers submit={props.submitMarkedAnswers} disabled={!numMarkedAnswers} />\n </div>\n }\n </>\n </>\n );\n}","import React from 'react';\n\nimport { QuestionTableAnswersProps } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\n\nexport function QuestionTableMissingWord(props: QuestionTableAnswersProps) {\n const replacePlaceholders = (str: string) => {\n if (!str) return '';\n\n return str.split(/({\\d+})/).map((part, index) => {\n const match = part.match(/{(\\d+)}/);\n\n if (match) {\n const key = match[1];\n\n const replacement = props.interaction.actionableItems.find(answer => +answer.order === +key);\n\n\n if (replacement) {\n return <span className='bg-white border border-gray-300 rounded p-1 lh-lg' key={index}>{replacement.name}</span>;\n }\n }\n\n return part;\n });\n };\n\n return (\n <div>\n <p className='mb-0'>{replacePlaceholders(props.interaction.data.sentence)}</p>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"row\":\"fXno_\",\"answerImage\":\"pDAuW\",\"answerWidth\":\"YHK27\"};","import React from 'react';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { QuestionTableAnswersProps } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\nimport { MultipleChoiceInteractionAnswers } from 'libs/shared/components/interaction-answers/multiple-choice/MultipleChoiceInteractionAnswers';\n\nimport styles from './question-table-answers.scss';\n\nexport function QuestionTableMultipleChoice(props: QuestionTableAnswersProps) {\n const hasImages = !!ArrayHelper.first(props.interaction?.actionableItems).data?.imageUrl;\n\n if (!hasImages) {\n return (\n <ul className={`${styles.answerWidth} list-unstyled row g-2`}>\n {props.interaction.actionableItems.map(option => {\n return (\n <li key={option.id} className='col-12'>\n <div className={`${option.isCorrect ? 'bg-light-green border-green' : 'bg-light-red border-red'} rounded border py-1 px-2 m-0`}>\n <span className='fw-semibold'>{props.indexToLetter(option.order)}. </span>\n <span>{option.name}</span>\n </div>\n </li>\n );\n })}\n </ul>\n );\n }\n\n return (\n <div className={styles.answerWidth}>\n <MultipleChoiceInteractionAnswers\n interaction={props.interaction}\n size='sm'\n showFeedback={false}\n showCorrectnessIcons\n isDisplayOnly\n />\n </div>\n );\n}","import React from 'react';\n\nimport { QuestionTableAnswersProps } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport styles from './question-table-answers.scss';\n\nconst namespace = 'shared.questionTable';\n\nexport function QuestionTableShortAnswer(props: QuestionTableAnswersProps) {\n const suggestedResponse = props.interaction.data?.suggestedResponse;\n\n if (!suggestedResponse) return <></>;\n\n return (\n <div className={`${styles.answerWidth} bg-light-blue rounded p-2 mb-2`}>\n <div className='d-flex justify-content-between'>\n <p className='fw-semibold mb-2'>\n <Text namespace={namespace} phrase='suggestedResponse' />\n </p>\n </div>\n\n <p className='mb-0'>{suggestedResponse}</p>\n </div>\n );\n}","import React from 'react';\n\nimport { QuestionTableAnswersProps } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\n\n\nexport function QuestionTableTrueOrFalse(props: QuestionTableAnswersProps) {\n return (\n <ul className='list-unstyled d-flex gap-2'>\n {props.interaction.actionableItems.map(option => {\n return (\n <li\n key={option.id}\n className={`${option.isCorrect ? 'bg-light-green border-green' : 'bg-light-red border-red'} rounded border px-2 py-1 mb-2 w-50`}\n >\n <span className='fw-semibold'>{props.indexToLetter(option.order)}. </span>\n <span>{option.name}</span>\n </li>\n );\n })}\n </ul>\n );\n}","import React from 'react';\n\nimport { QuestionTableMissingWord } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMissingWord';\nimport { QuestionTableMultipleChoice } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMultipleChoice';\nimport { QuestionTableShortAnswer } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableShortAnswer';\nimport { QuestionTableTrueOrFalse } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableTrueOrFalse';\nimport { indexToLetter } from 'libs/shared/apps/analytics/components/questions-list/question-table/QuestionTableUtils';\nimport { Interaction, InteractionTypeId } from 'libs/shared/interfaces';\n\nexport interface QuestionTableAnswersProps {\n interaction: Interaction;\n indexToLetter?: (index: number) => string;\n}\n\nexport function QuestionTableAnswers(props: QuestionTableAnswersProps) {\n function getQuestionTableAnswerComponent(): JSX.Element {\n switch (props.interaction.typeId) {\n case InteractionTypeId.MultipleChoice:\n return <QuestionTableMultipleChoice interaction={props.interaction} indexToLetter={indexToLetter} />;\n case InteractionTypeId.TrueOrFalse:\n return <QuestionTableTrueOrFalse interaction={props.interaction} indexToLetter={indexToLetter} />;\n case InteractionTypeId.ShortAnswer:\n return <QuestionTableShortAnswer interaction={props.interaction} />;\n case InteractionTypeId.MissingWord:\n return <QuestionTableMissingWord interaction={props.interaction} />;\n default: return null;\n }\n }\n\n const QuestionTableAnswerComponent = getQuestionTableAnswerComponent();\n\n if (!QuestionTableAnswerComponent) return <></>;\n\n return (\n <div className='w-100 mt-3'>\n {QuestionTableAnswerComponent}\n </div>\n );\n}","import React from 'react';\nimport { Column, ColumnInstance, Row, SortingRule } from 'react-table';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { PendingIndicator } from 'libs/shared/apps/analytics/components/pending-indicator/PendingIndicator';\nimport { QuestionTableAnswers } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers';\nimport { InteractionWithResultsSummary } from 'libs/shared/apps/analytics/interfaces/InteractionWithResultsSummary';\nimport { getInteractionResultsSummary } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { PercentageIndicator, PercentageIndicatorLayout } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Interactive, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getInteractions } from 'libs/shared/utils/InteractiveHelper';\n\nconst namespace = 'shared.questionTable';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction sortScore(\n rowA: Row<InteractionWithResultsSummary>,\n rowB: Row<InteractionWithResultsSummary>,\n columnId: string\n): 1 | -1 {\n const cellA = rowA.cells.find(cell => cell.column.id === columnId).value;\n const cellB = rowB.cells.find(cell => cell.column.id === columnId).value;\n\n if (cellA.awaitingMarking)\n return -1;\n\n if (cellB.awaitingMarking)\n return 1;\n\n return cellA.percentCorrect >= cellB.percentCorrect\n ? 1\n : -1;\n}\ninterface CellWrapperProps {\n className?: string;\n}\n\nfunction CellWrapper(props: React.PropsWithChildren<CellWrapperProps>): JSX.Element {\n return (\n <div className={`d-flex ${props.className ?? ''}`}>\n {props.children}\n </div>\n );\n}\n\ninterface HeaderCellProps {\n column: ColumnInstance<InteractionWithResultsSummary>;\n phraseKey: string;\n}\n\nfunction HeaderCell(props: HeaderCellProps): JSX.Element {\n return (\n <CellWrapper className={props.column.isSorted && 'fw-bold'}>\n {getPhrase(props.phraseKey)}\n </CellWrapper>\n );\n}\n\nexport function getColumns(\n showAnswersInTable: boolean\n): Column<InteractionWithResultsSummary>[] {\n return [\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='#' />,\n accessor: 'questionNumber',\n id: 'index',\n Cell: ({ row: { original: { questionNumber } } }) => {\n return <CellWrapper>{questionNumber + 1}.</CellWrapper>;\n },\n width: 15,\n disableSortBy: true\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='question' />,\n accessor: 'data', // This isn't used but it's needed for the typings on row,\n Cell: ({ row: { original: interaction }, initialState: { selectedRowIds } }) => {\n const selectedRow = selectedRowIds?.[interaction?.id];\n\n return (\n <CellWrapper className='flex-column'>\n <div className={`${!selectedRow ? 'clamp-1' : ''} pe-2`}>\n <InteractionLabel interaction={interaction} containerClassName='d-flex' />\n </div>\n\n {showAnswersInTable && selectedRow && (\n <QuestionTableAnswers interaction={interaction} />\n )}\n </CellWrapper>\n );\n },\n disableSortBy: true\n },\n {\n Header: ({ column }) => <HeaderCell column={column} phraseKey='score' />,\n accessor: 'resultsSummary',\n id: 'correctlyAnswered',\n Cell: ({ value: { percentCorrect, awaitingMarking } }) => {\n if (awaitingMarking) {\n return (\n <PendingIndicator\n title={getPhrase('markingRequired')}\n className='flex-grow-1'\n tooltipClassName='d-block'\n showLabel\n />\n );\n }\n\n return (\n <PercentageIndicator\n percentage={percentCorrect}\n layout={PercentageIndicatorLayout.LabelBefore}\n />\n );\n },\n width: 60,\n sortDescFirst: true,\n sortType: sortScore\n }\n ];\n}\n\n/**\n * Returns memoized table data. To trigger a recalculation, toggle the value of `refreshData`.\n */\nexport function useGetTableData(\n interactive: Interactive,\n results: InteractiveResultSet,\n refreshData: boolean,\n sortBy?: SortingRule<InteractionWithResultsSummary>\n): InteractionWithResultsSummary[] {\n return React.useMemo(() => {\n const flattenedInteractions = getInteractions(interactive);\n const questionNumbers: HashObject = flattenedInteractions.reduce((acc, interaction, index) => ({\n ...acc, [interaction.id]: index\n }), {});\n\n const interactions = flattenedInteractions.map(i => ({\n ...i,\n questionNumber: questionNumbers[i.id],\n resultsSummary: getInteractionResultsSummary(i, results)\n }));\n\n if (sortBy?.id === 'correctlyAnswered') {\n const sorted = ArrayHelper.sortBy(interactions, interaction => {\n if (interaction.resultsSummary.awaitingMarking)\n return -1;\n\n return interaction.resultsSummary.percentCorrect;\n });\n\n return sortBy.desc ? sorted.reverse() : sorted;\n }\n\n return interactions;\n }, [ refreshData, sortBy ]);\n}\n\nexport function indexToLetter(index: number) {\n return String.fromCharCode(index + 'A'.charCodeAt(0));\n}","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { indexToLetter } from 'libs/shared/apps/analytics/components/questions-list/question-table/QuestionTableUtils';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, InteractionTypeId, InteractiveResultSet } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.questionTable';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface QuestionSummary {\n id?: string;\n count: number;\n isCorrect: boolean;\n label?: string | number;\n}\n\nexport function multipleChoiceSummary(\n interaction: Interaction,\n studentResults: InteractiveResultSet\n): QuestionSummary[] {\n const questionsSummary: QuestionSummary[] = interaction.actionableItems.map((item, i) => {\n return {\n id: item.id,\n label: interaction.typeId === InteractionTypeId.MultipleChoice ? indexToLetter(i) : item.name,\n isCorrect: item.isCorrect,\n count: 0\n };\n });\n\n studentResults.students.forEach(student => {\n const latestAttempts = ArrayHelper.last(student.results).attempts;\n const response = ArrayHelper.findWhere(latestAttempts, { id: interaction.id });\n\n if (!response) return;\n\n response.answers.forEach(answer => {\n const questionSummary = ArrayHelper.findWhere(questionsSummary, { id: answer.id });\n\n if (questionSummary)\n questionSummary.count++;\n });\n });\n\n return questionsSummary;\n}\n\nexport function missingWordSummary(interaction: Interaction, studentResults: InteractiveResultSet): QuestionSummary[] {\n const questionsSummary: QuestionSummary[] = interaction.actionableItems.map(item => {\n return {\n id: item.id,\n label: item.name,\n isCorrect: item.isCorrect,\n count: 0\n };\n });\n\n questionsSummary.push({\n label: getPhrase('incorrect'),\n count: 0,\n isCorrect: false\n });\n\n studentResults.students.forEach(student => {\n const latestAttempts = ArrayHelper.last(student.results).attempts;\n const response = ArrayHelper.findWhere(latestAttempts, { id: interaction.id });\n\n if (!response) return;\n\n response.answers.forEach(answer => {\n const questionSummary = ArrayHelper.findWhere(questionsSummary, { id: answer.id });\n\n if (questionSummary && answer.status === InteractiveAnswerStatus.Correct) {\n questionSummary.count++;\n } else {\n const incorrectSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('incorrect') });\n\n incorrectSummary.count++;\n }\n });\n });\n\n return questionsSummary;\n}\n\nexport function markedSummary(interaction: Interaction, studentResults: InteractiveResultSet): QuestionSummary[] {\n const questionsSummary: QuestionSummary[] = [\n {\n label: getPhrase('correct'),\n isCorrect: true,\n count: 0\n },\n {\n label: getPhrase('incorrect'),\n isCorrect: false,\n count: 0\n }\n ];\n\n studentResults.students.forEach(student => {\n const latestAttempts = ArrayHelper.last(student.results).attempts;\n const response = ArrayHelper.findWhere(latestAttempts, { id: interaction.id });\n\n if (!response) return;\n\n response.answers.forEach(answer => {\n if (answer.status === InteractiveAnswerStatus.Correct) {\n const correctSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('correct') });\n correctSummary.count++;\n }\n if (answer.status === InteractiveAnswerStatus.Incorrect) {\n const incorrectSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('incorrect') });\n incorrectSummary.count++;\n }\n if (answer.status === InteractiveAnswerStatus.PendingReview) {\n let pendingSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('pending') });\n\n if (!pendingSummary) {\n questionsSummary.push({\n label: getPhrase('pending'),\n count: 0,\n isCorrect: false\n });\n pendingSummary = ArrayHelper.findWhere(questionsSummary, { label: getPhrase('pending') });\n }\n\n pendingSummary.count++;\n }\n });\n });\n\n return questionsSummary;\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { markedSummary, missingWordSummary, multipleChoiceSummary, QuestionSummary } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummaryUtils';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Interaction, InteractionTypeId, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.questionTable';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface QuestionResultsSummaryProps {\n interaction: Interaction;\n results: InteractiveResultSet;\n}\n\nexport function QuestionResultsSummary(props: QuestionResultsSummaryProps) {\n const questionSummary = getQuestionSummary();\n const maxResponseCount = getMaxResponseCount();\n\n function getQuestionSummary(): QuestionSummary[] {\n if (!props.interaction || !props.results) return;\n\n let summaryMethod: (\n interaction: Interaction,\n results: InteractiveResultSet,\n interactionTypeId?: InteractionTypeId\n ) => QuestionSummary[];\n\n switch (props.interaction.typeId) {\n case InteractionTypeId.ShortAnswer:\n case InteractionTypeId.Illustration:\n summaryMethod = markedSummary;\n break;\n case InteractionTypeId.MissingWord:\n summaryMethod = missingWordSummary;\n break;\n case InteractionTypeId.MultipleChoice:\n case InteractionTypeId.TrueOrFalse:\n summaryMethod = multipleChoiceSummary;\n break;\n }\n\n return summaryMethod(props.interaction, props.results);\n }\n\n function getMaxResponseCount() {\n return questionSummary?.reduce((acc, summary) => summary.count > acc ? summary.count : acc, 0);\n }\n\n function getBarClassName(summary: QuestionSummary) {\n const className = 'border rounded me-2';\n\n if (!summary.count)\n return `${className} border-light bg-light px-1`;\n\n if (summary.label === getPhrase('pending'))\n return `${className} border-blue bg-light-blue`;\n\n if (summary.isCorrect)\n return `${className} border-green bg-light-green`;\n\n return `${className} border-red bg-light-red`;\n }\n\n return (\n <div className='border border-light rounded p-3 mb-3'>\n <div className='d-flex align-items-center gap-2 mb-3'>\n <div className='rounded-circle bg-light-teal text-teal'>\n <SvgContainer svgName={cvSvgLibrary.Lightbulb} size={SvgContainerSize.Large} />\n </div>\n <h2 className='h6 mb-0'>\n <span><Text namespace={namespace} phrase='questionSummary' /></span>\n </h2>\n </div>\n <div className='d-flex gap-2'>\n <div className='max-w-25'>\n {questionSummary?.map(summary => {\n return (\n <p key={summary.label} className='text-truncate mb-2'>{summary.label}</p>\n );\n })}\n </div>\n <div className='flex-grow-1'>\n {questionSummary?.map((summary, i) => {\n return (\n <div key={i} className='d-flex mb-2'>\n <div\n className={getBarClassName(summary)}\n style={{ width: `${(summary.count / maxResponseCount) * 100}%`, height: 20 }}>\n </div>\n <span>{summary.count}</span>\n </div>\n );\n })}\n </div>\n </div>\n </div>\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';\n\nconst namespace = 'shared.selectedInteractionEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SelectedInteractionEmptyStateProps {\n emptyStateUrl: string;\n}\n\nexport function SelectedInteractionEmptyState(props: SelectedInteractionEmptyStateProps): JSX.Element {\n return (\n <EmptyState className='rounded h-100 bg-white justify-content-center py-4'>\n <EmptyState.Image\n src={props.emptyStateUrl}\n size='small'\n />\n <EmptyState.Info className='w-100'>\n {getPhrase('emptyStateText')}\n </EmptyState.Info>\n </EmptyState>\n );\n}","import React from 'react';\nimport { Row, SortingRule } from 'react-table';\n\nimport { ScrollHelper } from 'libs/common/backbone/utils/ScrollHelper';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { InteractionResponseList } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseList';\nimport { QuestionResultsSummary } from 'libs/shared/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummary';\nimport { SelectedInteractionEmptyState } from 'libs/shared/apps/analytics/components/questions-list/selected-interaction-empty-state/SelectedInteractionEmptyState';\nimport { InteractionWithResultsSummary } from 'libs/shared/apps/analytics/interfaces/InteractionWithResultsSummary';\nimport { getInteractionById } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { getSortStudents, SortStudentsBy } from 'libs/shared/apps/analytics/utils/StudentTableUtils';\nimport { Table, TableTheme } from 'libs/shared/components/table/Table';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interactive, InteractiveResultSet, StudentAnswer } from 'libs/shared/interfaces';\nimport { AppRouteHelper } from 'libs/shared/utils/AppRouteHelper';\n\nimport { getColumns, useGetTableData } from './QuestionTableUtils';\n\ninterface QuestionTableProps {\n interactive: Interactive;\n results: InteractiveResultSet;\n markedAnswers: { [id: string]: StudentAnswer };\n addMarkedAnswers: (answer: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n submitMarkedAnswers: () => void;\n editSuggestedResponse?: () => void;\n imageCdnUrl: string;\n selectQuestionImageUrl: string;\n anonymiseUsers: boolean;\n sortBy?: SortStudentsBy;\n emptyStateImageUrl: string;\n markingRequiredImageUrl?: string;\n correctImageUrl?: string;\n incorrectImageUrl?: string;\n skippedImageUrl?: string;\n\n /**\n * As the table data is memoized, it must be prompted to recalculate.\n * Toggle `refreshTable` to do so.\n */\n refreshTable: boolean;\n selectedInteractionId?: string;\n showAnswersInTable?: boolean;\n theme: TableTheme;\n reportsStyling?: boolean;\n isDemo?: boolean;\n}\n\nexport function QuestionTable(props: QuestionTableProps): JSX.Element {\n const [ sortBy, setSortBy ] = React.useState<SortingRule<InteractionWithResultsSummary>[]>(\n getSortStudents(props.sortBy, 'correctlyAnswered')\n );\n const data = useGetTableData(props.interactive, props.results, props.refreshTable, ArrayHelper.first(sortBy));\n\n const selectedInteraction = props.selectedInteractionId &&\n getInteractionById(props.interactive, props.selectedInteractionId);\n\n function onSelectRow({ original: interaction }: Row<InteractionWithResultsSummary>): void {\n ScrollHelper.preventScrollTop();\n\n AppRouteHelper.updateParams(\n { interactionId: interaction.id },\n { merge: true }\n );\n }\n\n return (\n <div className='row'>\n <div className='col-6 flex-grow-1'>\n <Table\n key={props.selectedInteractionId}\n columns={getColumns(props.showAnswersInTable)}\n data={data}\n theme={props.theme}\n onSelectRow={onSelectRow}\n initialSelectedRowIds={selectedInteraction ? [selectedInteraction.id] : null}\n getRowId={(row: InteractionWithResultsSummary) => row.id}\n enableSort\n manualSort\n onSort={setSortBy}\n initialSortBy={sortBy}\n />\n </div>\n <div className='col-6 d-flex flex-column'>\n {!props.reportsStyling && props.selectedInteractionId && !!props.results.students?.length && (\n <QuestionResultsSummary\n interaction={selectedInteraction}\n results={props.results}\n />\n )}\n\n <div className='border border-light rounded flex-grow-1'>\n {!!selectedInteraction &&\n <InteractionResponseList\n interaction={selectedInteraction}\n results={props.results}\n markedAnswers={props.markedAnswers}\n addMarkedAnswers={props.addMarkedAnswers}\n submitMarkedAnswers={props.submitMarkedAnswers}\n imageCdnUrl={props.imageCdnUrl}\n anonymiseUsers={props.anonymiseUsers}\n emptyStateImageUrl={props.emptyStateImageUrl}\n markingRequiredImageUrl={props.markingRequiredImageUrl}\n correctImageUrl={props.correctImageUrl}\n incorrectImageUrl={props.incorrectImageUrl}\n skippedImageUrl={props.skippedImageUrl}\n reportsStyling={props.reportsStyling}\n isDemo={props.isDemo}\n />\n }\n {!selectedInteraction && <SelectedInteractionEmptyState emptyStateUrl={props.selectQuestionImageUrl} />}\n </div>\n </div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialInsights\":\"bk68v\"};","import React from 'react';\n\nimport styles from './partial-interactive-insights-questions.scss';\n\nexport function PartialInteractiveInsightsQuestions() {\n return (\n <div>\n <div className='row g-3 mb-5'>\n <div className='col-6'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n <div className='col-6'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { QuestionTable } from 'libs/shared/apps/analytics/components/questions-list/question-table/QuestionTable';\nimport { useMarkAnswers } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { SortStudentsBy } from 'libs/shared/apps/analytics/utils/StudentTableUtils';\nimport { ConfirmationPopup } from 'libs/shared/components/confirmation-popup/ConfirmationPopup';\nimport { TableTheme } from 'libs/shared/components/table/Table';\nimport { Config, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport { PartialInteractiveInsightsQuestions } from 'apps/insights/views/interactive/questions/partial-loading/PartialInteractiveInsightsQuestions';\n\n\nconst namespace = 'shared.interactiveInsightsQuestionsView';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst theme: TableTheme = {\n table: 'bg-white rounded border border-light h-100 pb-2',\n header: 'border-bottom px-3 py-2 mb-2',\n headerCell: 'd-flex align-items-center',\n cell: '',\n row: `px-3 py-2 bg-light-blue-hover`,\n selectedRow: 'bg-gray-100',\n sortIndicator: 'ms-2'\n};\n\ninterface InteractiveInsightsQuestionsProps {\n interactionId: string;\n interactive: Interactive;\n interactiveMetadata: InteractiveMetadata;\n results: InteractiveResultSet;\n isFetching: boolean;\n config: Config;\n hasDataLoaded: boolean;\n anonymiseUsers: boolean;\n sortBy: SortStudentsBy;\n isDemo?: boolean;\n}\n\nexport function InteractiveInsightsQuestions(props: InteractiveInsightsQuestionsProps) {\n const [ showMarkConfirmationPopup, setShowMarkConfirmationPopup ] = React.useState(false);\n\n const { markedAnswers, addMarkedAnswers, submitMarkedAnswers } = useMarkAnswers(\n props.interactive?.id,\n props.interactiveMetadata?.id,\n () => setShowMarkConfirmationPopup(false)\n );\n\n return (\n <>\n {!props.hasDataLoaded && <PartialInteractiveInsightsQuestions />}\n\n {props.hasDataLoaded &&\n <QuestionTable\n interactive={props.interactive}\n results={props.results}\n markedAnswers={markedAnswers}\n addMarkedAnswers={addMarkedAnswers}\n submitMarkedAnswers={() => setShowMarkConfirmationPopup(true)}\n imageCdnUrl={props.config.imageCdnUrl}\n selectedInteractionId={props.interactionId}\n refreshTable={props.isFetching}\n emptyStateImageUrl={ImageUrls.Insights.NO_RESPONSES}\n selectQuestionImageUrl={ImageUrls.Insights.NO_DATA}\n anonymiseUsers={props.anonymiseUsers}\n sortBy={props.sortBy}\n showAnswersInTable\n theme={theme}\n correctImageUrl={ImageUrls.Insights.JIGSAW}\n incorrectImageUrl={ImageUrls.Insights.RED_JIGSAW}\n skippedImageUrl={ImageUrls.Insights.SKIPPED}\n markingRequiredImageUrl={ImageUrls.Insights.CLIPBOARD}\n isDemo={props.isDemo}\n />\n }\n\n {showMarkConfirmationPopup &&\n <ConfirmationPopup\n title={getPhrase('markPopupTitle', { smartCount: Object.keys(markedAnswers).length ?? 0 })}\n closePopup={() => setShowMarkConfirmationPopup(false)}\n confirmButtonText={getPhrase('submit')}\n confirmButtonVariant='dark'\n onClickConfirm={submitMarkedAnswers}\n >\n <p>{getPhrase('markPopupBody')}</p>\n </ConfirmationPopup>\n }\n </>\n );\n}"],"names":["ScrollHelper","preventScrollTop","Radio","trigger","getPhrase","getClassName","props","className","showLabel","PendingIndicator","Indicator","title","spanHack","spanHackClassName","tooltipClassName","getSortStudents","sortBy","id","desc","shouldFilterStudent","filter","summary","awaitingMarking","percentCorrect","unanswered","ConfirmationPopup","showButtonSpinner","setShowButtonSpinner","closePopup","children","onClick","variant","cancelButtonVariant","text","cancelButtonText","onClickConfirm","confirmButtonText","confirmButtonVariant","showSpinner","disabled","disabledConfirmButton","defaultProps","namespace","InteractionResponseListFiltersEmptyStates","EmptyState","src","correctImageUrl","incorrectImageUrl","markingRequiredImageUrl","skippedImageUrl","getFilterEmptyStateImageUrl","Text","phrase","getFilterEmptyStatePhrase","InteractionResponseListFilters","getFilterClassName","filterButton","isFilterSelected","toggleFilter","LanguageService","InteractionResponseListHeader","suggestedResponse","interaction","data","InteractionLabel","iconClassName","SubmitMarkedAnswers","submit","InteractionResponseList","setFilter","responsesToMark","results","students","s","InteractiveCorrectnessHelper","InteractionCorrectness","reduce","acc","user","publicUser","profileId","numMarkedAnswers","Object","keys","markedAnswers","length","emptyStateImageUrl","size","filteredStudentResults","result","correctness","filterMap","correct","incorrect","marking_required","skipped","reportsStyling","Tooltip","isDemo","submitMarkedAnswers","selectedFilter","map","idx","anonymisedUserName","anonymiseUsers","markingRequired","key","InteractionResponse","studentResults","markedStatus","markInteraction","addMarkedAnswers","imageCdnUrl","showStudentDetails","showFeedback","responseComponentClass","InteractionResponseItem","QuestionTableMissingWord","str","sentence","split","part","index","match","replacement","actionableItems","find","answer","order","name","QuestionTableMultipleChoice","ArrayHelper","imageUrl","MultipleChoiceInteractionAnswers","showCorrectnessIcons","isDisplayOnly","option","isCorrect","indexToLetter","QuestionTableShortAnswer","QuestionTableTrueOrFalse","QuestionTableAnswers","QuestionTableAnswerComponent","typeId","getQuestionTableAnswerComponent","sortScore","rowA","rowB","columnId","cellA","cells","cell","column","value","cellB","CellWrapper","HeaderCell","isSorted","phraseKey","String","fromCharCode","charCodeAt","multipleChoiceSummary","questionsSummary","item","i","label","count","forEach","student","latestAttempts","attempts","response","answers","questionSummary","missingWordSummary","push","status","InteractiveAnswerStatus","markedSummary","pendingSummary","QuestionResultsSummary","summaryMethod","getQuestionSummary","maxResponseCount","getBarClassName","SvgContainer","svgName","S","style","width","height","SelectedInteractionEmptyState","emptyStateUrl","QuestionTable","showAnswersInTable","setSortBy","interactive","refreshData","flattenedInteractions","questionNumbers","interactions","questionNumber","resultsSummary","sorted","reverse","useGetTableData","refreshTable","selectedInteraction","selectedInteractionId","Table","columns","Header","accessor","Cell","row","original","disableSortBy","selectedRowIds","initialState","selectedRow","containerClassName","PercentageIndicator","percentage","layout","sortDescFirst","sortType","theme","onSelectRow","AppRouteHelper","interactionId","merge","initialSelectedRowIds","getRowId","enableSort","manualSort","onSort","initialSortBy","selectQuestionImageUrl","PartialInteractiveInsightsQuestions","table","header","headerCell","sortIndicator","InteractiveInsightsQuestions","showMarkConfirmationPopup","setShowMarkConfirmationPopup","interactiveMetadata","hasDataLoaded","config","isFetching","ImageUrls","smartCount"],"sourceRoot":""}
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[7033],{9570:(e,t,r)=>{r.d(t,{d:()=>S});var n=r(32735),a=r(40424),s=r(23481),i=r(75896),o=r(83914),c=r(8246),u=r(35223);function l(e){var t=e.answer;return n.createElement("div",{key:t.id,className:"".concat(function(e){switch(e){case c.N.Correct:return"bg-light-green";case c.N.Incorrect:return"bg-light-red";case c.N.PendingReview:return"bg-light-blue"}}(t.status)," rounded p-2 mb-2")},n.createElement("div",{className:"d-flex align-items-center gap-2"},t.status===c.N.Correct&&n.createElement(o.x,{svgName:u.vn.Check,className:"svg-container flex-shrink-0 text-success"}),t.status===c.N.Incorrect&&n.createElement(o.x,{svgName:u.vn.Close,className:"svg-container flex-shrink-0 text-danger"}),!e.customAnswer&&n.createElement("span",{className:e.textClassName},t.text)),e.children)}var m=s.T.encloseNamespace("shared.interactionResponses");function d(e){return d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},d(e)}function f(e,t,r){return(t=function(e){var t=function(e){if("object"!=d(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=d(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==d(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var v=function(){return n.createElement(n.Fragment,null)},g=f(f(f(f(f(f(f({},a.Z9.Annotation,v),a.Z9.Image,v),a.Z9.MissingWord,(function(e){return e.answers.length?n.createElement("ul",{className:"list-unstyled"},e.answers.map((function(e){return n.createElement("li",{key:e.id},n.createElement(l,{answer:e,textClassName:"bg-white p-1 border border-gray-300 rounded"}))}))):n.createElement(n.Fragment,null)})),a.Z9.MultipleChoice,(function(e){return e.answers.length?n.createElement("ul",{className:"list-unstyled"},e.answers.map((function(e){return n.createElement("li",{key:e.id},n.createElement(l,{answer:e}))}))):n.createElement(n.Fragment,null)})),a.Z9.TrueOrFalse,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t}):n.createElement(n.Fragment,null)})),a.Z9.ShortAnswer,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t},e.children):n.createElement(n.Fragment,null)})),a.Z9.Illustration,(function(e){var t=i.m.first(e.answers);return t?n.createElement(l,{answer:t,customAnswer:!0},n.createElement("div",{className:"ratio ratio-16x9"},n.createElement("img",{className:"img-fluid bg-white border rounded h-100 w-100",src:t.text,alt:"".concat(m("illustrationAlt"),": ").concat(e.interaction.name)})),e.children):n.createElement(n.Fragment,null)})),y=r(20789),p=r(44526),w=r(56151),h=r(3894),b=r(69737),E=r(83140),I=r(80845),k=r(64818);const C={avatarContainer:"O7oaA"};function S(e){var t,r,a,s,i,o,c=g[e.interaction.typeId];if(!c)return n.createElement(n.Fragment,null);var u=(0,I.j_)(e.studentResults),l=(0,I.f6)(e.interaction.id,u),m=E.A.isInteractionCorrect(e.interaction,u);return n.createElement("div",{className:"position-relative"},n.createElement("div",{className:"rounded ".concat(null!==(t=e.className)&&void 0!==t?t:"")},n.createElement("div",{className:"d-flex"},!!e.showStudentDetails&&n.createElement("div",{className:"me-2"},n.createElement("div",{className:C.avatarContainer},n.createElement(y.q,{imageCdnUrl:e.imageCdnUrl,initials:e.anonymisedUserName?k.l.getInitialsFromFullName(e.anonymisedUserName):k.l.getInitials(null===(r=e.studentResults.user)||void 0===r?void 0:r.name,null===(a=e.studentResults.user)||void 0===a?void 0:a.surname),imageUrl:e.anonymisedUserName?null:null===(i=null===(s=e.studentResults.user)||void 0===s?void 0:s.avatar)||void 0===i?void 0:i.url,showAnonymousUser:!!(null===(o=e.studentResults)||void 0===o?void 0:o.publicUser)}))),n.createElement("div",{className:"flex-grow-1"},!!e.showStudentDetails&&n.createElement(w.U,{studentResults:e.studentResults,correctness:m,anonymisedUserName:e.anonymisedUserName}),n.createElement("div",{className:"d-flex justify-content-between"},n.createElement("div",{className:"flex-grow-1 mb-2 ".concat(e.responseComponentClass?e.responseComponentClass:"")},l?n.createElement(c,{interaction:e.interaction,answers:l.answers,imageCdnUrl:e.imageCdnUrl,user:e.studentResults.user,showFeedback:e.showFeedback,showAvatar:e.showAvatar},n.createElement(h.Z,{studentAttempt:l,correctness:m,markInteraction:e.markInteraction,markedStatus:e.markedStatus})):n.createElement(b.R,null)),!e.showStudentDetails&&n.createElement(p.Y,{correctness:m}))))))}},71553:(e,t,r)=>{r.d(t,{I:()=>i});var n=r(99940),a=r(62875);function s(e,t){return{currentUserId:e.id,currentCustomerId:e.customerId,dateRange:{start:t.start,end:t.end},userIds:t.userId,classroomsAndGroups:t.groupId}}var i={interactiveResultSet:function(e,t,r,i,o,c,u,l){return{url:o?"/api/domain/v3/analytics/interactives/".concat(e,"/metadata/").concat(t):"/api/domain/v2/analytics/interactives/".concat(e,"/metadata/").concat(t),key:(0,a.H)("interactive:result:set:".concat(e,":").concat(t),i),data:s(r,i),type:n.k.POST,normalize:!1,formatData:function(e){return Object.assign(Object.assign({},e),{students:e.students.map((function(e){return e.name&&e.profileId?Object.assign(Object.assign({},e),{publicUser:{profileId:e.profileId,name:e.name}}):e}))})},success:c,error:u,always:l}},mark:function(e,t,r,a,s,i,o){return{url:"/api/domain/v1/analytics/answers/".concat(r),key:"mark:answer:".concat(r,":").concat(a.resultId),type:n.k.PUT,data:a,normalize:!1,invalidationKeys:"interactive:result:set:".concat(e,":").concat(t),success:s,error:i,always:o}},pendingReviews:function(e){return{url:"/api/domain/v1/analytics/interactives/pending-reviews/summary",key:"interactives:pending:reviews",type:n.k.POST,data:e}},interactiveResultsReport:function(e){return{url:"{gateway}/v2/analytics/interactives/report",key:"interactive:results:report",data:e,type:n.k.POST,normalize:!1}}}},9193:(e,t,r)=>{r.d(t,{D:()=>f});var n=r(32735),a=r(70680),s=r(23481),i=r(20354),o=r(71553),c=r(39157),u=r(69883);function l(e){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},l(e)}function m(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var d=s.T.encloseNamespace("reportsShared.dataHooks"),f=function(e,t,r){var s,f,v=(s=(0,n.useState)({}),f=2,function(e){if(Array.isArray(e))return e}(s)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,s,i,o=[],c=!0,u=!1;try{if(s=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=s.call(r)).done)&&(o.push(n.value),o.length!==t);c=!0);}catch(e){u=!0,a=e}finally{try{if(!c&&null!=r.return&&(i=r.return(),Object(i)!==i))return}finally{if(u)throw a}}return o}}(s,f)||function(e,t){if(e){if("string"==typeof e)return m(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?m(e,t):void 0}}(s,f)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),g=v[0],y=v[1],p=(0,a.I0)(),w=(0,u.Z)();return{markedAnswers:g,addMarkedAnswers:function(e,t){e.forEach((function(e){y((function(r){return Object.assign(Object.assign({},r),function(e,t,r){return(t=function(e){var t=function(e){if("object"!=l(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,"string");if("object"!=l(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==l(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}({},(0,c.UU)(e),Object.assign(Object.assign({},e),{status:t})))}))}))},submitMarkedAnswers:function(){var n=Object.keys(g).map((function(e){return g[e]}));if(n.length){var a=0,s=0;n.forEach((function(r){var n=r.id,a=r.resultId,s=r.questionId,l=r.status;i.a.fetch(p,o.I.mark(e,t,n,{id:n,resultId:a,questionId:s,status:l},c,null,u))}))}function c(){s++}function u(){var e,t;++a===n.length&&(e="",t=!1,0===s&&(e=d("error",{smartCount:n.length}),t=!0),s<a&&(e=d("success",{smartCount:s})+" ".concat(d("partialError",{smartCount:a-s}))),s===a&&(e=d("success",{smartCount:s})),t?w.error(e):w.success(e),y({}),r&&r())}}}}},39157:(e,t,r)=>{r.d(t,{HI:()=>d,R6:()=>u,Rt:()=>v,UU:()=>m,Zs:()=>l,nq:()=>f});var n=r(75896),a=r(94892),s=r(28972),i=r(8246),o=r(83140),c=r(80845);function u(e,t,r){var s={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},i=(0,c.Q)(e).length;t.students.forEach((function(t){var o=Object.assign(Object.assign({},t),{summary:v(e,t)});o.summary.awaitingMarking?s.markingRequired.push(o):n.m.last(t.results).attempts.length===i?(s.completed.push(o),o.summary.percentCorrect>=((null==r?void 0:r.HIGH)||a.i.HIGH)&&s.highScore.push(o),o.summary.percentCorrect<((null==r?void 0:r.MODERATE)||a.i.MODERATE)&&s.lowScore.push(o)):s.notCompleted.push(o)}));var o=n.m.sortBy(s.lowScore,(function(e){return e.summary.percentCorrect})),u=n.m.sortBy(s.highScore,(function(e){return-e.summary.percentCorrect}));return Object.assign(Object.assign({},s),{lowScore:o,highScore:u})}function l(e,t){return(0,c.Wn)(e).find((function(e){return e.id.toString()===t.toString()}))}function m(e){return"".concat(e.questionId,":").concat(e.resultId)}function d(e,t,r){var n=(0,c.j_)(t),a=(0,c.f6)(e,n);return(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=r[m(e)])||void 0===t?void 0:t.status)===i.N.Correct})))?i.N.Correct:(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=r[m(e)])||void 0===t?void 0:t.status)===i.N.Incorrect})))?i.N.Incorrect:void 0}function f(e,t){var r=t.students.length,n=0,a=0,i=0,u=0,l=0;return t.students.forEach((function(t){var r=(0,c.j_)(t);if(r){l+=t.results.length;var m=o.A.isInteractionCorrect(e,r);m===s.w.Correct&&n++,m===s.w.UnAnswered&&i++,m===s.w.AwaitingMarking&&u++,m!==s.w.UnAnswered&&a++}})),{percentCorrect:r>0?n/r:0,correct:n,answered:a,unanswered:i,awaitingMarking:u,attempts:l}}function v(e,t){var r=(0,c.j_)(t),n=(0,c.Q)(e),a=n.length,i=0,u=0;n.forEach((function(e){var t=o.A.isInteractionCorrect(e,r);t===s.w.Correct&&i++,t===s.w.AwaitingMarking&&u++}));var l=a>0?i/a:0,m=new Set(n.map((function(e){return e.id}))),d=r.attempts.filter((function(e){var t;return!!m.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)})).length;return{answered:r.attempts.length,attempts:t.results.length,unanswered:a-d,percentCorrect:l,correct:i,awaitingMarking:u}}},93322:(e,t,r)=>{r.d(t,{F:()=>s});var n=r(32735),a=r(13126);function s(){n.useEffect((function(){return a.e.lockContentWidth(),function(){return a.e.unlockContentWidth()}}),[])}},62875:(e,t,r)=>{function n(e,t,r){var n="".concat(e,":").concat(t.start,":").concat(t.end),a=Array.isArray(t.userId)?t.userId.sort().join(":"):t.userId,s=Array.isArray(t.groupId)?t.groupId.sort().join(":"):t.groupId;return a&&(n+=":".concat(a)),s&&(n+=":".concat(s)),r&&(n+=":".concat(r)),n}r.d(t,{H:()=>n})}}]);
2
+ //# sourceMappingURL=7033-6ab57dea83-lite.chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts/7033-6ab57dea83-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/IllustrationResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/MissingWordResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/MultipleChoiceResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/TrueOrFalseResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/ShortAnswerResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/interaction-response-item.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/InteractionResponseItem.tsx","file:///app/packages/libs/shared/src/apps/analytics/flight-requests/InteractiveResultsRequests.ts","file:///app/packages/libs/shared/src/apps/analytics/hooks/UseMarkAnswers.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/InteractiveUtils.ts","file:///app/packages/libs/shared/src/hooks/useLockContentWidth.ts","file:///app/packages/libs/shared/src/utils/AnalyticsRequestUtils.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?.publicUser}\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 { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Flight } from 'libs/common/react/index';\n\nimport { MarkInteractiveAnswer } from 'libs/shared/apps/analytics/interfaces/MarkInteractiveAnswer';\nimport { InteractiveResultsReport } from 'libs/shared/apps/analytics/interfaces/requests/InteractiveResultsReport';\nimport { InteractivesPendingReviewsRequest } from 'libs/shared/apps/analytics/interfaces/requests/InteractivesPendingReviewsRequest';\nimport { AnalyticsRequestFilter, CurrentUser, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getAnalyticsRequestKey } from 'libs/shared/utils/AnalyticsRequestUtils';\n\ninterface InteractiveResultFilters {\n currentUserId: string;\n currentCustomerId: string;\n dateRange?: { start: string, end: string }\n userIds?: string | string[];\n classroomsAndGroups?: string | string[];\n}\n\nfunction getInteractiveResultFilters(\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter\n): InteractiveResultFilters {\n return {\n currentUserId: currentUser.id,\n currentCustomerId: currentUser.customerId,\n dateRange: { start: filter.start, end: filter.end },\n userIds: filter.userId,\n classroomsAndGroups: filter.groupId\n };\n}\n\nexport const InteractiveResultsRequests = {\n /** \n * This endpoint returns data with a lot of duplicated ids,\n * e.g. student answers to the same question will have the same id.\n * Because of that, we don't normalize.\n */\n interactiveResultSet(\n interactiveId: string,\n interactiveMetadataId: string,\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter,\n includePublicResults: boolean,\n success?: (data: InteractiveResultSet) => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: includePublicResults ?\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}`, filter),\n data: getInteractiveResultFilters(currentUser, filter),\n type: HttpVerbs.POST,\n normalize: false,\n formatData: (data: any) => {\n return {\n ...data,\n students: data.students.map((student: any) => {\n if (!student.name || !student.profileId)\n return student;\n\n return {\n ...student,\n publicUser: {\n profileId: student.profileId,\n name: student.name\n }\n };\n })\n };\n },\n success,\n error,\n always\n };\n },\n \n /**\n * As the response from `interactiveResultSet` isn't normalised, we need to invalidate the cache\n * to update the results data.\n */\n mark(\n interactiveId: string,\n interactiveMetadataId: string,\n answerId: string,\n data: MarkInteractiveAnswer,\n success?: () => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v1/analytics/answers/${answerId}`,\n key: `mark:answer:${answerId}:${data.resultId}`,\n type: HttpVerbs.PUT,\n data,\n normalize: false,\n invalidationKeys: `interactive:result:set:${interactiveId}:${interactiveMetadataId}`,\n success,\n error,\n always\n };\n },\n\n pendingReviews(data: InteractivesPendingReviewsRequest): Flight.Request {\n return {\n url: `/api/domain/v1/analytics/interactives/pending-reviews/summary`,\n key: `interactives:pending:reviews`,\n type: HttpVerbs.POST,\n data\n };\n },\n\n interactiveResultsReport(data: InteractiveResultsReport): Flight.Request {\n return {\n url: '{gateway}/v2/analytics/interactives/report',\n key: 'interactive:results:report',\n data,\n type: HttpVerbs.POST,\n normalize: false\n };\n }\n};","import { useState } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { InteractiveResultsRequests } from 'libs/shared/apps/analytics/flight-requests/InteractiveResultsRequests';\nimport { getMarkedAnswerId } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { StudentAnswer } from 'libs/shared/interfaces';\n\nconst getPhrase = LanguageService.encloseNamespace('reportsShared.dataHooks');\n\nexport type MarkedAnswerHash = { [id: string]: StudentAnswer };\n\n/**\n * This hook manages the storing of a marked answer hash in state and then the submitting\n * of those answers via an api call.\n */\nexport const useMarkAnswers = (interactiveId: string, interactiveMetadataId: string, onDone?: () => void) => {\n const [ markedAnswers, setMarkedAnswers ] = useState<MarkedAnswerHash>({});\n\n const dispatch = useDispatch();\n const alerts = useAlerts();\n\n function addMarkedAnswers(answers: StudentAnswer[], status: InteractiveAnswerStatus): void {\n answers.forEach(a => {\n setMarkedAnswers(m => ({ ...m, [getMarkedAnswerId(a)]: { ...a, status } }));\n });\n }\n\n function submitMarkedAnswers(): void {\n const answers = Object.keys(markedAnswers).map(key => markedAnswers[key]);\n\n if (!answers.length)\n return;\n\n let completeCount = 0;\n let successCount = 0;\n\n function onSuccess(): void {\n successCount++;\n }\n\n function onAlways(): void {\n completeCount++;\n\n if (completeCount === answers.length)\n onComplete();\n }\n\n function onComplete(): void {\n let alertMessage = '';\n let useErrorAlert = false;\n\n if (successCount === 0) {\n alertMessage = getPhrase('error', { smartCount: answers.length });\n useErrorAlert = true;\n }\n\n if (successCount < completeCount) {\n alertMessage = getPhrase('success', { smartCount: successCount })\n + ` ${getPhrase('partialError', { smartCount: completeCount - successCount })}`;\n }\n\n if (successCount === completeCount) {\n alertMessage = getPhrase('success', { smartCount: successCount });\n }\n\n useErrorAlert\n ? alerts.error(alertMessage)\n : alerts.success(alertMessage);\n\n setMarkedAnswers({});\n\n onDone && onDone();\n }\n\n answers.forEach(({ id, resultId, questionId, status }) => {\n Flight.fetch(dispatch, InteractiveResultsRequests.mark(\n interactiveId,\n interactiveMetadataId,\n id,\n { id, resultId, questionId, status },\n onSuccess,\n null,\n onAlways\n ));\n });\n }\n\n return {\n markedAnswers,\n addMarkedAnswers,\n submitMarkedAnswers\n };\n};","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { Interactive, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { flattenInteractions, getInteractions, getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\ninterface StudentGroups {\n markingRequired: StudentResultsWithSummary[];\n lowScore: StudentResultsWithSummary[];\n highScore: StudentResultsWithSummary[];\n completed: StudentResultsWithSummary[];\n notCompleted: StudentResultsWithSummary[];\n}\n\nexport function groupStudents(\n interactive: Interactive,\n results: InteractiveResultSet,\n scoreThreshold?: ScoreThresholds\n): StudentGroups {\n const groups: StudentGroups = {\n markingRequired: [],\n lowScore: [],\n highScore: [],\n completed: [],\n notCompleted: []\n };\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n \n results.students.forEach(s => {\n const withSummary = {\n ...s,\n summary: getStudentResultsSummary(interactive, s)\n };\n \n if (withSummary.summary.awaitingMarking) {\n groups.markingRequired.push(withSummary);\n return;\n }\n\n if (ArrayHelper.last(s.results).attempts.length === numInteractions) {\n groups.completed.push(withSummary);\n } else {\n groups.notCompleted.push(withSummary);\n return;\n }\n \n if (withSummary.summary.percentCorrect >= (scoreThreshold?.HIGH || ScoreThresholdDefaults.HIGH))\n groups.highScore.push(withSummary);\n \n if (withSummary.summary.percentCorrect < (scoreThreshold?.MODERATE || ScoreThresholdDefaults.MODERATE))\n groups.lowScore.push(withSummary);\n });\n \n const sortedLowScore = ArrayHelper.sortBy(groups.lowScore, s => s.summary.percentCorrect);\n const sortedHighScore = ArrayHelper.sortBy(groups.highScore, s => -s.summary.percentCorrect);\n \n return {\n ...groups,\n lowScore: sortedLowScore,\n highScore: sortedHighScore\n };\n}\n\nexport function getInteractionById(interactive: Interactive, interactionId: string): Interaction {\n const flattenedInteractions = flattenInteractions(interactive);\n return flattenedInteractions.find(i => i.id.toString() === interactionId.toString());\n}\n\n/**\n * We need to use the question and result ids as a list of one student's responses\n * to multiple questions will all have the same result id and a list of multiple\n * students responses to one question will all have the same questionId.\n */\nexport function getMarkedAnswerId(answer: StudentAnswer): string {\n return `${answer.questionId}:${answer.resultId}`;\n}\n\nexport function getMarkedStatus(\n interactionId: string,\n studentResults: StudentResults,\n markedAnswers: MarkedAnswerHash\n): InteractiveAnswerStatus {\n const result = getStudentResult(studentResults);\n const studentResponse = getStudentAttempt(interactionId, result);\n\n const isMarkedCorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Correct;\n });\n\n if (isMarkedCorrect)\n return InteractiveAnswerStatus.Correct;\n\n const isMarkedIncorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Incorrect;\n });\n\n if (isMarkedIncorrect)\n return InteractiveAnswerStatus.Incorrect;\n}\n\nexport function getInteractionResultsSummary(\n interaction: Interaction,\n results: InteractiveResultSet\n): ResultsSummary {\n const numStudents = results.students.length;\n let numCorrect = 0;\n let answered = 0;\n let unanswered = 0;\n let awaitingMarking = 0;\n let attempts = 0;\n\n results.students.forEach(s => {\n const result = getStudentResult(s);\n\n if (!result)\n return;\n\n attempts = attempts + s.results.length;\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(interaction, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.UnAnswered)\n unanswered++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n\n if (correctness !== InteractionCorrectness.UnAnswered)\n answered++;\n });\n\n\n const percentCorrect = numStudents > 0\n ? numCorrect / numStudents\n : 0;\n\n return {\n percentCorrect,\n correct: numCorrect,\n answered,\n unanswered,\n awaitingMarking,\n attempts\n };\n}\n\nexport function getStudentResultsSummary(interactive: Interactive, studentResults: StudentResults): ResultsSummary {\n const result = getStudentResult(studentResults);\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n\n let numCorrect = 0;\n let awaitingMarking = 0;\n\n interactions.forEach(i => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(i, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n });\n\n const percentCorrect = numInteractions > 0 ? numCorrect / numInteractions : 0;\n\n /**\n * Our interactions list has images and annotations filtered out.\n * We built a map of valid questions, so that we can calculate the unswered accurately.\n * We're doing this because of a bug that caused annotations and images to record answers in the player.\n * - Sha\n */\n const interactionIds = new Set(interactions.map(i => i.id));\n const answeredInteractions = result.attempts.filter(a => !!interactionIds.has(a?.answers[0]?.questionId)).length;\n\n return {\n answered: result.attempts.length,\n attempts: studentResults.results.length,\n unanswered: numInteractions - answeredInteractions,\n percentCorrect,\n correct: numCorrect,\n awaitingMarking\n };\n}","import React from 'react';\n\nimport { LayoutHelper } from 'libs/shared/utils/LayoutHelper';\n\nexport function useLockContentWidth(): void {\n React.useEffect(() => {\n LayoutHelper.lockContentWidth();\n return () => LayoutHelper.unlockContentWidth();\n }, []);\n}","import { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\nexport function getAnalyticsRequestKey(baseKey: string, filter: AnalyticsRequestFilter, sharerId?: string): string {\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\n if (userIdKey)\n key += `:${userIdKey}`;\n\n if (groupIdKey)\n key += `:${groupIdKey}`;\n\n if (sharerId)\n key += `:${sharerId}`;\n\n return key;\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","publicUser","InteractionStudentDetailsHeader","responseComponentClass","showFeedback","showAvatar","MarkResponse","markInteraction","markedStatus","NoResponse","InteractionResponseCorrectness","getInteractiveResultFilters","currentUser","filter","currentUserId","currentCustomerId","customerId","dateRange","start","end","userIds","userId","classroomsAndGroups","groupId","InteractiveResultsRequests","interactiveResultSet","interactiveId","interactiveMetadataId","includePublicResults","success","error","always","data","type","normalize","formatData","students","student","profileId","mark","answerId","resultId","invalidationKeys","pendingReviews","interactiveResultsReport","useMarkAnswers","onDone","useState","markedAnswers","setMarkedAnswers","dispatch","alerts","addMarkedAnswers","forEach","a","m","submitMarkedAnswers","Object","keys","completeCount","successCount","questionId","I","onSuccess","onAlways","alertMessage","useErrorAlert","smartCount","groupStudents","interactive","results","scoreThreshold","groups","markingRequired","lowScore","highScore","completed","notCompleted","numInteractions","s","withSummary","summary","getStudentResultsSummary","awaitingMarking","push","attempts","percentCorrect","HIGH","MODERATE","sortedLowScore","sortedHighScore","getInteractionById","interactionId","find","i","toString","getMarkedAnswerId","getMarkedStatus","studentResponse","every","getInteractionResultsSummary","numStudents","numCorrect","answered","unanswered","correct","interactions","interactionIds","Set","answeredInteractions","has","useLockContentWidth","getAnalyticsRequestKey","baseKey","sharerId","userIdKey","Array","isArray","sort","join","groupIdKey"],"sourceRoot":""}