@clickview/lite 0.57.2-dev.2 → 0.57.2-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/scripts/1057-3c48d4553a-lite.chunk.js +2 -0
  3. package/dist/scripts/1057-3c48d4553a-lite.chunk.js.map +1 -0
  4. package/dist/scripts/1734-bbca52585c-lite.chunk.js +2 -0
  5. package/dist/scripts/1734-bbca52585c-lite.chunk.js.map +1 -0
  6. package/dist/scripts/7237-86c18f2701-lite.chunk.js +2 -0
  7. package/dist/scripts/7237-86c18f2701-lite.chunk.js.map +1 -0
  8. package/dist/scripts/8095-777a5c5ddf-lite.chunk.js +2 -0
  9. package/dist/scripts/8095-777a5c5ddf-lite.chunk.js.map +1 -0
  10. package/dist/scripts/8489-6e8c4dd60f-lite.chunk.js +3 -0
  11. package/dist/scripts/8489-6e8c4dd60f-lite.chunk.js.map +1 -0
  12. package/dist/scripts/9201-899c885914-lite.chunk.js +2 -0
  13. package/dist/scripts/9201-899c885914-lite.chunk.js.map +1 -0
  14. package/dist/scripts/{bundle-33a0223ac5.min.js → bundle-4b58e56927.min.js} +3 -3
  15. package/dist/scripts/bundle-4b58e56927.min.js.map +1 -0
  16. package/package.json +1 -1
  17. package/dist/scripts/1057-80dd5a1be7-lite.chunk.js +0 -2
  18. package/dist/scripts/1057-80dd5a1be7-lite.chunk.js.map +0 -1
  19. package/dist/scripts/1734-4a7f3b5c3e-lite.chunk.js +0 -2
  20. package/dist/scripts/1734-4a7f3b5c3e-lite.chunk.js.map +0 -1
  21. package/dist/scripts/7237-bf0cded690-lite.chunk.js +0 -2
  22. package/dist/scripts/7237-bf0cded690-lite.chunk.js.map +0 -1
  23. package/dist/scripts/8095-85db09f5b2-lite.chunk.js +0 -2
  24. package/dist/scripts/8095-85db09f5b2-lite.chunk.js.map +0 -1
  25. package/dist/scripts/8489-d9860267ec-lite.chunk.js +0 -3
  26. package/dist/scripts/8489-d9860267ec-lite.chunk.js.map +0 -1
  27. package/dist/scripts/9201-58ea2d1161-lite.chunk.js +0 -2
  28. package/dist/scripts/9201-58ea2d1161-lite.chunk.js.map +0 -1
  29. package/dist/scripts/bundle-33a0223ac5.min.js.map +0 -1
  30. /package/dist/scripts/{8489-d9860267ec-lite.chunk.js.LICENSE.txt → 8489-6e8c4dd60f-lite.chunk.js.LICENSE.txt} +0 -0
  31. /package/dist/scripts/{bundle-33a0223ac5.min.js.LICENSE.txt → bundle-4b58e56927.min.js.LICENSE.txt} +0 -0
@@ -1,2 +0,0 @@
1
- "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[9201],{72915:(e,t,r)=>{r.d(t,{d:()=>I});var n=r(32735),a=r(35561),s=r(40424),i=r(83914),o=r(8246),c=r(35223);function u(e){var t=e.answer;return n.createElement("div",{key:t.id,className:"".concat(function(e){switch(e){case o.N.Correct:return"bg-light-green";case o.N.Incorrect:return"bg-light-red";case o.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===o.N.Correct&&n.createElement(i.x,{svgName:c.vn.Check,className:"svg-container flex-shrink-0 text-success"}),t.status===o.N.Incorrect&&n.createElement(i.x,{svgName:c.vn.Close,className:"svg-container flex-shrink-0 text-danger"}),n.createElement("span",{className:e.textClassName},t.text)),e.children)}var l=r(75896);function m(e){return m="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},m(e)}function d(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=m(e)||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,"string");if("object"!=m(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==m(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)},f=d(d(d(d(d(d(d({},s.Z9.Annotation,v),s.Z9.Image,v),s.Z9.MissingWord,(function(e){return e.answers.length?n.createElement("ul",{className:"list-unstyled"},e.answers.map((function(e){return n.createElement(u,{key:e.id,answer:e,textClassName:"bg-white p-1 border border-gray-300 rounded"})}))):n.createElement(n.Fragment,null)})),s.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(u,{answer:e}))}))):n.createElement(n.Fragment,null)})),s.Z9.TrueOrFalse,(function(e){var t=l.m.first(e.answers);return t?n.createElement(u,{answer:t}):n.createElement(n.Fragment,null)})),s.Z9.ShortAnswer,(function(e){var t=l.m.first(e.answers);return t?n.createElement(u,{answer:t},e.children):n.createElement(n.Fragment,null)})),s.Z9.Illustration,a.O),g=r(20789),y=r(44526),p=r(56151),w=r(3894),h=r(69737),b=r(83140),S=r(80845),E=r(64818);const k={avatarContainer:"O7oaA"};function I(e){var t,r,a,s,i,o=f[e.interaction.typeId];if(!o)return n.createElement(n.Fragment,null);var c=(0,S.j_)(e.studentResults),u=(0,S.f6)(e.interaction.id,c),l=b.A.isInteractionCorrect(e.interaction,c);return n.createElement("div",{className:"rounded ".concat(null!==(t=e.className)&&void 0!==t?t:"")},n.createElement("div",{className:"d-flex"},!!e.showStudentDetails&&n.createElement("div",{className:"me-2"},n.createElement("div",{className:k.avatarContainer},n.createElement(g.q,{imageCdnUrl:e.imageCdnUrl,initials:e.anonymisedUserName?E.l.getInitialsFromFullName(e.anonymisedUserName):E.l.getInitials(null===(r=e.studentResults.user)||void 0===r?void 0:r.name,null===(a=e.studentResults.user)||void 0===a?void 0:a.surname),imageUrl:e.anonymisedUserName?null:null===(i=null===(s=e.studentResults.user)||void 0===s?void 0:s.avatar)||void 0===i?void 0:i.url}))),n.createElement("div",{className:"flex-grow-1"},!!e.showStudentDetails&&n.createElement(p.U,{studentResults:e.studentResults,correctness:l,anonymisedUserName:e.anonymisedUserName}),n.createElement("div",{className:"d-flex justify-content-between"},n.createElement("div",{className:"flex-grow-1 mb-2 ".concat(e.responseComponentClass?e.responseComponentClass:"")},u?n.createElement(o,{interaction:e.interaction,answers:u.answers,imageCdnUrl:e.imageCdnUrl,user:e.studentResults.user,showFeedback:e.showFeedback,showAvatar:e.showAvatar},n.createElement(w.Z,{studentAttempt:u,correctness:l,markInteraction:e.markInteraction,markedStatus:e.markedStatus})):n.createElement(h.R,null)),!e.showStudentDetails&&n.createElement(y.Y,{correctness:l})))))}},71553:(e,t,r)=>{r.d(t,{I:()=>i});var n=r(99940),a=r(62875);function s(e,t){return{currentUserId:e.id,currentCustomerId:e.customerId,dateRange:{start:t.start,end:t.end},userIds:t.userId,classroomsAndGroups:t.groupId}}var i={interactiveResultSet:function(e,t,r,i,o,c,u){return{url:"/api/domain/v3/analytics/interactives/".concat(e,"/metadata/").concat(t),key:(0,a.H)("interactive:result:set:".concat(e,":").concat(t),i),data:s(r,i),formatData:function(e){return e.students=e.students.map((function(e){return Object.assign(Object.assign({},e),{user:e.user||{name:e.name,id:e.profileId}})})),e},type:n.k.POST,normalize:!1,success:o,error:c,always:u}},mark:function(e,t,r,a,s,i,o){return{url:"/api/domain/v1/analytics/answers/".concat(r),key:"mark:answer:".concat(r,":").concat(a.resultId),type:n.k.PUT,data:a,normalize:!1,invalidationKeys:"interactive:result:set:".concat(e,":").concat(t),success:s,error:i,always:o}},pendingReviews:function(e){return{url:"/api/domain/v1/analytics/interactives/pending-reviews/summary",key:"interactives:pending:reviews",type:n.k.POST,data:e}},interactiveResultsReport:function(e){return{url:"{gateway}/v2/analytics/interactives/report",key:"interactive:results:report",data:e,type:n.k.POST,normalize:!1}}}},41196:(e,t,r)=>{r.d(t,{W:()=>o});var n=r(20354),a=r(71553),s=r(20768),i=r(31949);function o(e,t){var r,o=n.a.useBasicFetch(i.N.currentUser()),c=n.a.useBasicFetch(!!e&&s.b.interactiveMetadata(e)),u=n.a.useBasicFetch(!!(null===(r=c.data)||void 0===r?void 0:r.interactiveId)&&s.b.interactive(c.data.interactiveId)),l=!!o.data&&!!u.data&&!!t;return n.a.useBasicFetch(l&&a.I.interactiveResultSet(c.data.interactiveId,c.data.id,o.data,t))}},9193:(e,t,r)=>{r.d(t,{D:()=>v});var n=r(32735),a=r(70680),s=r(23481),i=r(20354),o=r(71553),c=r(39157),u=r(69883);function l(e){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},l(e)}function m(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=Array(t);r<t;r++)n[r]=e[r];return n}var d=s.T.encloseNamespace("reportsShared.dataHooks"),v=function(e,t,r){var s,v,f=(s=(0,n.useState)({}),v=2,function(e){if(Array.isArray(e))return e}(s)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,a,s,i,o=[],c=!0,u=!1;try{if(s=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;c=!1}else for(;!(c=(n=s.call(r)).done)&&(o.push(n.value),o.length!==t);c=!0);}catch(e){u=!0,a=e}finally{try{if(!c&&null!=r.return&&(i=r.return(),Object(i)!==i))return}finally{if(u)throw a}}return o}}(s,v)||function(e,t){if(e){if("string"==typeof e)return m(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?m(e,t):void 0}}(s,v)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()),g=f[0],y=f[1],p=(0,a.I0)(),w=(0,u.Z)();return{markedAnswers:g,addMarkedAnswers:function(e,t){e.forEach((function(e){y((function(r){return Object.assign(Object.assign({},r),function(e,t,r){return(t=function(e){var t=function(e,t){if("object"!=l(e)||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,"string");if("object"!=l(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==l(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}({},(0,c.UU)(e),Object.assign(Object.assign({},e),{status:t})))}))}))},submitMarkedAnswers:function(){var n=Object.keys(g).map((function(e){return g[e]}));if(n.length){var a=0,s=0;n.forEach((function(r){var n=r.id,a=r.resultId,s=r.questionId,l=r.status;i.a.fetch(p,o.I.mark(e,t,n,{id:n,resultId:a,questionId:s,status:l},c,null,u))}))}function c(){s++}function u(){var e,t;++a===n.length&&(e="",t=!1,0===s&&(e=d("error",{smartCount:n.length}),t=!0),s<a&&(e=d("success",{smartCount:s})+" ".concat(d("partialError",{smartCount:a-s}))),s===a&&(e=d("success",{smartCount:s})),t?w.error(e):w.success(e),y({}),r&&r())}}}}},39157:(e,t,r)=>{r.d(t,{HI:()=>d,R6:()=>u,Rt:()=>f,UU:()=>m,Zs:()=>l,nq:()=>v});var n=r(75896),a=r(94892),s=r(28972),i=r(8246),o=r(83140),c=r(80845);function u(e,t){var r={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},s=(0,c.Q)(e).length;t.students.forEach((function(t){var i=Object.assign(Object.assign({},t),{summary:f(e,t)});i.summary.awaitingMarking?r.markingRequired.push(i):n.m.last(t.results).attempts.length===s?(r.completed.push(i),i.summary.percentCorrect>=a.i.HIGH&&r.highScore.push(i),i.summary.percentCorrect<a.i.MODERATE&&r.lowScore.push(i)):r.notCompleted.push(i)}));var i=n.m.sortBy(r.lowScore,(function(e){return e.summary.percentCorrect})),o=n.m.sortBy(r.highScore,(function(e){return e.summary.percentCorrect})).reverse();return Object.assign(Object.assign({},r),{lowScore:i,highScore:o})}function l(e,t){return(0,c.Wn)(e).find((function(e){return e.id.toString()===t.toString()}))}function m(e){return"".concat(e.questionId,":").concat(e.resultId)}function d(e,t,r){var n=(0,c.j_)(t),a=(0,c.f6)(e,n);return(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=r[m(e)])||void 0===t?void 0:t.status)===i.N.Correct})))?i.N.Correct:(null==a?void 0:a.answers.every((function(e){var t;return(null===(t=r[m(e)])||void 0===t?void 0:t.status)===i.N.Incorrect})))?i.N.Incorrect:void 0}function v(e,t){var r=t.students.length,n=0,a=0,i=0,u=0,l=0;return t.students.forEach((function(t){var r=(0,c.j_)(t);if(r){l+=t.results.length;var m=o.A.isInteractionCorrect(e,r);m===s.w.Correct&&n++,m===s.w.UnAnswered&&i++,m===s.w.AwaitingMarking&&u++,m!==s.w.UnAnswered&&a++}})),{percentCorrect:r>0?n/r:0,correct:n,answered:a,unanswered:i,awaitingMarking:u,attempts:l}}function f(e,t){var r=(0,c.j_)(t),n=(0,c.Q)(e),a=n.length,i=0,u=0;n.forEach((function(e){var t=o.A.isInteractionCorrect(e,r);t===s.w.Correct&&i++,t===s.w.AwaitingMarking&&u++}));var l=a>0?i/a:0,m=new Set(n.map((function(e){return e.id}))),d=r.attempts.filter((function(e){var t;return!!m.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)})).length;return{answered:r.attempts.length,attempts:t.results.length,unanswered:a-d,percentCorrect:l,correct:i,awaitingMarking:u}}}}]);
2
- //# sourceMappingURL=9201-58ea2d1161-lite.chunk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scripts/9201-58ea2d1161-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/ResponseItemComponentLookup.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/MissingWordResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/MultipleChoiceResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/TrueOrFalseResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/components/ShortAnswerResponse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/interaction-response-item.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-item/InteractionResponseItem.tsx","file:///app/packages/libs/shared/src/apps/analytics/flight-requests/InteractiveResultsRequests.ts","file:///app/packages/libs/shared/src/apps/analytics/hooks/UseFetchInteractiveResults.ts","file:///app/packages/libs/shared/src/apps/analytics/hooks/UseMarkAnswers.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/InteractiveUtils.ts"],"sourcesContent":["import React from 'react';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { StudentAnswer } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\ninterface AnswerContainerProps extends React.PropsWithChildren {\n answer: StudentAnswer;\n textClassName?: string;\n}\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 <span className={props.textClassName}>{answer.text}</span>\n </div>\n {props.children}\n </div>\n );\n}","import React from 'react';\n\nimport { IllustrationResponse } from 'libs/shared/components/interaction-response/response-types/IllustrationResponse';\nimport { Interaction, InteractionTypeId, StudentAnswer, User } from 'libs/shared/interfaces';\n\nimport { MissingWordResponse } from './components/MissingWordResponse';\nimport { MultipleChoiceResponse } from './components/MultipleChoiceResponse';\nimport { ShortAnswerResponse } from './components/ShortAnswerResponse';\nimport { TrueOrFalseResponse } from './components/TrueOrFalseResponse';\n\nexport interface ResponseItemComponentProps extends React.PropsWithChildren {\n interaction: Interaction;\n answers: StudentAnswer[];\n imageCdnUrl: string;\n user: User;\n showFeedback?: boolean;\n showAvatar?: boolean;\n anonymisedUserName?: string;\n}\nconst NoResponseRequired = () => <></>;\n\nexport const ResponseItemComponentLookup: {\n [typeId: number]: (props: ResponseItemComponentProps) => JSX.Element\n} = {\n [InteractionTypeId.Annotation]: NoResponseRequired,\n [InteractionTypeId.Image]: NoResponseRequired,\n [InteractionTypeId.MissingWord]: MissingWordResponse,\n [InteractionTypeId.MultipleChoice]: MultipleChoiceResponse,\n [InteractionTypeId.TrueOrFalse]: TrueOrFalseResponse,\n [InteractionTypeId.ShortAnswer]: ShortAnswerResponse,\n [InteractionTypeId.Illustration]: IllustrationResponse\n};","import React from 'react';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\n\nexport function MissingWordResponse(props: ResponseItemComponentProps) {\n if (!props.answers.length) return <></>;\n\n return (\n <ul className='list-unstyled'>\n {props.answers.map(answer => (\n <AnswerContainer\n key={answer.id}\n answer={answer}\n textClassName='bg-white p-1 border border-gray-300 rounded'\n />\n ))}\n </ul>\n );\n}","import React from 'react';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function MultipleChoiceResponse(props: ResponseItemComponentProps) {\n if (!props.answers.length) return <></>;\n\n return (\n <ul className='list-unstyled'>\n {props.answers.map(answer => (\n <li key={answer.id}>\n <AnswerContainer answer={answer} />\n </li>\n ))}\n </ul>\n );\n}","import React from 'react';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function TrueOrFalseResponse(props: ResponseItemComponentProps) {\n const answer = ArrayHelper.first(props.answers);\n\n if (!answer)\n return <></>;\n\n return (\n <AnswerContainer answer={answer} />\n );\n}","import React from 'react';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { AnswerContainer } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/components/AnswerContainer';\nimport { ResponseItemComponentProps } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\n\nexport function ShortAnswerResponse(props: ResponseItemComponentProps): JSX.Element {\n const answer = ArrayHelper.first(props.answers);\n\n if (!answer)\n return <></>;\n\n return (\n <AnswerContainer answer={answer}>\n {props.children}\n </AnswerContainer>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"avatarContainer\":\"O7oaA\"};","import React from 'react';\n\nimport { ResponseItemComponentLookup } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/ResponseItemComponentLookup';\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { InteractionResponseCorrectness } from 'libs/shared/components/interaction-response/InteractionResponseCorrectness';\nimport { InteractionStudentDetailsHeader } from 'libs/shared/components/interaction-response/InteractionStudentDetailsHeader';\nimport { MarkResponse } from 'libs/shared/components/interaction-response/MarkResponse';\nimport { NoResponse } from 'libs/shared/components/interaction-response/response-types/NoResponse';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from './interaction-response-item.scss';\n\ninterface InteractionResponseProps {\n interaction: Interaction;\n studentResults: StudentResults;\n imageCdnUrl: string;\n markInteraction: (answers: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n markedStatus?: InteractiveAnswerStatus;\n showStudentDetails?: boolean;\n className?: string;\n showFeedback?: boolean;\n showAvatar?: boolean;\n anonymisedUserName?: string;\n responseComponentClass?: string;\n}\n\nexport function InteractionResponseItem(props: InteractionResponseProps): JSX.Element {\n const ResponseItemComponent = ResponseItemComponentLookup[props.interaction.typeId];\n\n if (!ResponseItemComponent)\n return <></>;\n\n const result = getStudentResult(props.studentResults);\n\n const studentAttempt = getStudentAttempt(props.interaction.id, result);\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(props.interaction, result);\n\n return (\n <div className={`rounded ${props.className ?? ''}`}>\n <div className='d-flex'>\n {!!props.showStudentDetails &&\n <div className='me-2'>\n <div className={styles.avatarContainer}>\n <Avatar\n imageCdnUrl={props.imageCdnUrl}\n initials={props.anonymisedUserName\n ? UserHelper.getInitialsFromFullName(props.anonymisedUserName)\n : UserHelper.getInitials(props.studentResults.user?.name, props.studentResults.user?.surname)\n }\n imageUrl={props.anonymisedUserName ? null : props.studentResults.user?.avatar?.url}\n />\n </div>\n </div>\n }\n <div className='flex-grow-1'>\n {!!props.showStudentDetails &&\n <InteractionStudentDetailsHeader\n studentResults={props.studentResults}\n correctness={correctness}\n anonymisedUserName={props.anonymisedUserName}\n />\n }\n <div className='d-flex justify-content-between'>\n <div className={`flex-grow-1 mb-2 ${props.responseComponentClass ? props.responseComponentClass : ''}`}>\n {studentAttempt\n ? <ResponseItemComponent\n interaction={props.interaction}\n answers={studentAttempt.answers}\n imageCdnUrl={props.imageCdnUrl}\n user={props.studentResults.user}\n showFeedback={props.showFeedback}\n showAvatar={props.showAvatar}\n >\n <MarkResponse\n studentAttempt={studentAttempt}\n correctness={correctness}\n markInteraction={props.markInteraction}\n markedStatus={props.markedStatus}\n />\n </ResponseItemComponent>\n : <NoResponse />\n }\n </div>\n {!props.showStudentDetails &&\n <InteractionResponseCorrectness correctness={correctness} />\n }\n </div>\n </div>\n </div>\n </div>\n );\n}","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Flight } from 'libs/common/react/index';\n\nimport { MarkInteractiveAnswer } from 'libs/shared/apps/analytics/interfaces/MarkInteractiveAnswer';\nimport { InteractiveResultsReport } from 'libs/shared/apps/analytics/interfaces/requests/InteractiveResultsReport';\nimport { InteractivesPendingReviewsRequest } from 'libs/shared/apps/analytics/interfaces/requests/InteractivesPendingReviewsRequest';\nimport { AnalyticsRequestFilter, CurrentUser, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { getAnalyticsRequestKey } from 'libs/shared/utils/AnalyticsRequestUtils';\n\ninterface InteractiveResultFilters {\n currentUserId: string;\n currentCustomerId: string;\n dateRange?: { start: string, end: string }\n userIds?: string | string[];\n classroomsAndGroups?: string | string[];\n}\n\nfunction getInteractiveResultFilters(\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter\n): InteractiveResultFilters {\n return {\n currentUserId: currentUser.id,\n currentCustomerId: currentUser.customerId,\n dateRange: { start: filter.start, end: filter.end },\n userIds: filter.userId,\n classroomsAndGroups: filter.groupId\n };\n}\n\nexport const InteractiveResultsRequests = {\n /** \n * This endpoint returns data with a lot of duplicated ids,\n * e.g. student answers to the same question will have the same id.\n * Because of that, we don't normalize.\n */\n interactiveResultSet(\n interactiveId: string,\n interactiveMetadataId: string,\n currentUser: CurrentUser,\n filter: AnalyticsRequestFilter,\n success?: (data: InteractiveResultSet) => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v3/analytics/interactives/${interactiveId}/metadata/${interactiveMetadataId}`,\n key: getAnalyticsRequestKey(`interactive:result:set:${interactiveId}:${interactiveMetadataId}`, filter),\n data: getInteractiveResultFilters(currentUser, filter),\n formatData: (data: any) => {\n data.students = data.students.map((d: any) => {\n return {\n ...d,\n user: d.user || {\n name: d.name,\n id: d.profileId\n }\n };\n });\n return data;\n },\n type: HttpVerbs.POST,\n normalize: false,\n success,\n error,\n always\n };\n },\n \n /**\n * As the response from `interactiveResultSet` isn't normalised, we need to invalidate the cache\n * to update the results data.\n */\n mark(\n interactiveId: string,\n interactiveMetadataId: string,\n answerId: string,\n data: MarkInteractiveAnswer,\n success?: () => void,\n error?: (data: any) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: `/api/domain/v1/analytics/answers/${answerId}`,\n key: `mark:answer:${answerId}:${data.resultId}`,\n type: HttpVerbs.PUT,\n data,\n normalize: false,\n invalidationKeys: `interactive:result:set:${interactiveId}:${interactiveMetadataId}`,\n success,\n error,\n always\n };\n },\n\n pendingReviews(data: InteractivesPendingReviewsRequest): Flight.Request {\n return {\n url: `/api/domain/v1/analytics/interactives/pending-reviews/summary`,\n key: `interactives:pending:reviews`,\n type: HttpVerbs.POST,\n data\n };\n },\n\n interactiveResultsReport(data: InteractiveResultsReport): Flight.Request {\n return {\n url: '{gateway}/v2/analytics/interactives/report',\n key: 'interactive:results:report',\n data,\n type: HttpVerbs.POST,\n normalize: false\n };\n }\n};","import { Flight } from 'libs/common/flight';\n\nimport { InteractiveResultsRequests } from 'libs/shared/apps/analytics/flight-requests/InteractiveResultsRequests';\nimport { InteractiveRequests } from 'libs/shared/flight-requests/InteractiveRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { AnalyticsRequestFilter, CurrentUser, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nexport function useFetchInteractiveResults(\n interactiveMetadataId: string,\n requestFilter: AnalyticsRequestFilter\n): Flight.Response<InteractiveResultSet> {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(!!interactiveMetadataId &&\n InteractiveRequests.interactiveMetadata(interactiveMetadataId));\n\n const interactive = Flight.useBasicFetch<Interactive>(!!interactiveMetadata.data?.interactiveId &&\n InteractiveRequests.interactive(interactiveMetadata.data.interactiveId));\n\n const shouldFetchResults = !!currentUser.data && !!interactive.data && (!!requestFilter);\n\n return Flight.useBasicFetch<InteractiveResultSet>(shouldFetchResults &&\n InteractiveResultsRequests.interactiveResultSet(\n interactiveMetadata.data.interactiveId,\n interactiveMetadata.data.id,\n currentUser.data,\n requestFilter\n ));\n}","import { useState } from 'react';\nimport { useDispatch } from 'react-redux';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { InteractiveResultsRequests } from 'libs/shared/apps/analytics/flight-requests/InteractiveResultsRequests';\nimport { getMarkedAnswerId } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { StudentAnswer } from 'libs/shared/interfaces';\n\nconst getPhrase = LanguageService.encloseNamespace('reportsShared.dataHooks');\n\nexport type MarkedAnswerHash = { [id: string]: StudentAnswer };\n\n/**\n * This hook manages the storing of a marked answer hash in state and then the submitting\n * of those answers via an api call.\n */\nexport const useMarkAnswers = (interactiveId: string, interactiveMetadataId: string, onDone?: () => void) => {\n const [ markedAnswers, setMarkedAnswers ] = useState<MarkedAnswerHash>({});\n\n const dispatch = useDispatch();\n const alerts = useAlerts();\n\n function addMarkedAnswers(answers: StudentAnswer[], status: InteractiveAnswerStatus): void {\n answers.forEach(a => {\n setMarkedAnswers(m => ({ ...m, [getMarkedAnswerId(a)]: { ...a, status } }));\n });\n }\n\n function submitMarkedAnswers(): void {\n const answers = Object.keys(markedAnswers).map(key => markedAnswers[key]);\n\n if (!answers.length)\n return;\n\n let completeCount = 0;\n let successCount = 0;\n\n function onSuccess(): void {\n successCount++;\n }\n\n function onAlways(): void {\n completeCount++;\n\n if (completeCount === answers.length)\n onComplete();\n }\n\n function onComplete(): void {\n let alertMessage = '';\n let useErrorAlert = false;\n\n if (successCount === 0) {\n alertMessage = getPhrase('error', { smartCount: answers.length });\n useErrorAlert = true;\n }\n\n if (successCount < completeCount) {\n alertMessage = getPhrase('success', { smartCount: successCount })\n + ` ${getPhrase('partialError', { smartCount: completeCount - successCount })}`;\n }\n\n if (successCount === completeCount) {\n alertMessage = getPhrase('success', { smartCount: successCount });\n }\n\n useErrorAlert\n ? alerts.error(alertMessage)\n : alerts.success(alertMessage);\n\n setMarkedAnswers({});\n\n onDone && onDone();\n }\n\n answers.forEach(({ id, resultId, questionId, status }) => {\n Flight.fetch(dispatch, InteractiveResultsRequests.mark(\n interactiveId,\n interactiveMetadataId,\n id,\n { id, resultId, questionId, status },\n onSuccess,\n null,\n onAlways\n ));\n });\n }\n\n return {\n markedAnswers,\n addMarkedAnswers,\n submitMarkedAnswers\n };\n};","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { ScoreThresholdDefaults } 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(interactive: Interactive, results: InteractiveResultSet): 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 >= ScoreThresholdDefaults.HIGH)\n groups.highScore.push(withSummary);\n \n if (withSummary.summary.percentCorrect < 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).reverse();\n \n return {\n ...groups,\n lowScore: sortedLowScore,\n highScore: sortedHighScore\n };\n}\n\nexport function getInteractionById(interactive: Interactive, interactionId: string): Interaction {\n const flattenedInteractions = flattenInteractions(interactive);\n return flattenedInteractions.find(i => i.id.toString() === interactionId.toString());\n}\n\n/**\n * We need to use the question and result ids as a list of one student's responses\n * to multiple questions will all have the same result id and a list of multiple\n * students responses to one question will all have the same questionId.\n */\nexport function getMarkedAnswerId(answer: StudentAnswer): string {\n return `${answer.questionId}:${answer.resultId}`;\n}\n\nexport function getMarkedStatus(\n interactionId: string,\n studentResults: StudentResults,\n markedAnswers: MarkedAnswerHash\n): InteractiveAnswerStatus {\n const result = getStudentResult(studentResults);\n const studentResponse = getStudentAttempt(interactionId, result);\n\n const isMarkedCorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Correct;\n });\n\n if (isMarkedCorrect)\n return InteractiveAnswerStatus.Correct;\n\n const isMarkedIncorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Incorrect;\n });\n\n if (isMarkedIncorrect)\n return InteractiveAnswerStatus.Incorrect;\n}\n\nexport function getInteractionResultsSummary(\n interaction: Interaction,\n results: InteractiveResultSet\n): ResultsSummary {\n const numStudents = results.students.length;\n let numCorrect = 0;\n let answered = 0;\n let unanswered = 0;\n let awaitingMarking = 0;\n let attempts = 0;\n\n results.students.forEach(s => {\n const result = getStudentResult(s);\n\n if (!result)\n return;\n\n attempts = attempts + s.results.length;\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(interaction, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.UnAnswered)\n unanswered++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n\n if (correctness !== InteractionCorrectness.UnAnswered)\n answered++;\n });\n\n\n const percentCorrect = numStudents > 0\n ? numCorrect / numStudents\n : 0;\n\n return {\n percentCorrect,\n correct: numCorrect,\n answered,\n unanswered,\n awaitingMarking,\n attempts\n };\n}\n\nexport function getStudentResultsSummary(interactive: Interactive, studentResults: StudentResults): ResultsSummary {\n const result = getStudentResult(studentResults);\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n\n let numCorrect = 0;\n let awaitingMarking = 0;\n\n interactions.forEach(i => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(i, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n });\n\n const percentCorrect = numInteractions > 0 ? numCorrect / numInteractions : 0;\n\n /**\n * Our interactions list has images and annotations filtered out.\n * We built a map of valid questions, so that we can calculate the unswered accurately.\n * We're doing this because of a bug that caused annotations and images to record answers in the player.\n * - Sha\n */\n const interactionIds = new Set(interactions.map(i => i.id));\n const answeredInteractions = result.attempts.filter(a => !!interactionIds.has(a?.answers[0]?.questionId)).length;\n\n return {\n answered: result.attempts.length,\n attempts: studentResults.results.length,\n unanswered: numInteractions - answeredInteractions,\n percentCorrect,\n correct: numCorrect,\n awaitingMarking\n };\n}"],"names":["AnswerContainer","props","answer","key","id","className","status","InteractiveAnswerStatus","getBgColour","SvgContainer","svgName","textClassName","text","children","NoResponseRequired","ResponseItemComponentLookup","answers","length","map","ArrayHelper","IllustrationResponse","InteractionResponseItem","ResponseItemComponent","interaction","typeId","result","studentResults","studentAttempt","correctness","InteractiveCorrectnessHelper","showStudentDetails","Avatar","imageCdnUrl","initials","anonymisedUserName","UserHelper","user","name","surname","imageUrl","avatar","url","InteractionStudentDetailsHeader","responseComponentClass","showFeedback","showAvatar","MarkResponse","markInteraction","markedStatus","NoResponse","InteractionResponseCorrectness","getInteractiveResultFilters","currentUser","filter","currentUserId","currentCustomerId","customerId","dateRange","start","end","userIds","userId","classroomsAndGroups","groupId","InteractiveResultsRequests","interactiveResultSet","interactiveId","interactiveMetadataId","success","error","always","data","formatData","students","d","profileId","type","normalize","mark","answerId","resultId","invalidationKeys","pendingReviews","interactiveResultsReport","useFetchInteractiveResults","requestFilter","interactiveMetadata","interactive","shouldFetchResults","I","getPhrase","useMarkAnswers","onDone","useState","markedAnswers","setMarkedAnswers","dispatch","alerts","addMarkedAnswers","forEach","a","m","submitMarkedAnswers","Object","keys","completeCount","successCount","questionId","onSuccess","onAlways","alertMessage","useErrorAlert","smartCount","groupStudents","results","groups","markingRequired","lowScore","highScore","completed","notCompleted","numInteractions","s","withSummary","summary","getStudentResultsSummary","awaitingMarking","push","attempts","percentCorrect","sortedLowScore","sortedHighScore","reverse","getInteractionById","interactionId","find","i","toString","getMarkedAnswerId","getMarkedStatus","studentResponse","every","getInteractionResultsSummary","numStudents","numCorrect","answered","unanswered","correct","interactions","interactionIds","Set","answeredInteractions","has"],"sourceRoot":""}