@clickview/lite 0.70.1-dev.5 → 0.70.1-dev.6

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 (136) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/css/{9583-lite-9eda71423d.chunk.css → 3878-lite-877e596a24.chunk.css} +3 -0
  3. package/dist/css/{5797-lite-1dfd2c337d.chunk.css → 5099-lite-7d7c063e62.chunk.css} +3 -0
  4. package/dist/css/{8191-lite-ee877f2ecd.chunk.css → 6984-lite-53c3fa4d18.chunk.css} +3 -0
  5. package/dist/css/{8723-lite-676baa8218.chunk.css → 7103-lite-ee0c975440.chunk.css} +3 -0
  6. package/dist/css/{7783-lite-1dfd2c337d.chunk.css → 7394-lite-7d7c063e62.chunk.css} +3 -0
  7. package/dist/css/7502-lite-9b2ed5bd56.chunk.css +4 -0
  8. package/dist/css/{5721-lite-9eda71423d.chunk.css → 7548-lite-877e596a24.chunk.css} +3 -0
  9. package/dist/css/{549-lite-b49bde8e4d.chunk.css → 7657-lite-ad909396f3.chunk.css} +3 -1
  10. package/dist/css/{6783-lite-e85973335b.chunk.css → 829-lite-27b58d07b3.chunk.css} +3 -0
  11. package/dist/css/{5635-lite-ee877f2ecd.chunk.css → 9673-lite-53c3fa4d18.chunk.css} +3 -0
  12. package/dist/scripts/1107-0fb4769540-lite.chunk.js +2 -0
  13. package/dist/scripts/1107-0fb4769540-lite.chunk.js.map +1 -0
  14. package/dist/scripts/1437-658ad1fe2b-lite.chunk.js +2 -0
  15. package/dist/scripts/1437-658ad1fe2b-lite.chunk.js.map +1 -0
  16. package/dist/scripts/1710-ef798f1e0d-lite.chunk.js +2 -0
  17. package/dist/scripts/1710-ef798f1e0d-lite.chunk.js.map +1 -0
  18. package/dist/scripts/2024-4fec8f175b-lite.chunk.js +2 -0
  19. package/dist/scripts/2024-4fec8f175b-lite.chunk.js.map +1 -0
  20. package/dist/scripts/2435-a846651e83-lite.chunk.js +2 -0
  21. package/dist/scripts/2435-a846651e83-lite.chunk.js.map +1 -0
  22. package/dist/scripts/2809-84ce060e14-lite.chunk.js +2 -0
  23. package/dist/scripts/2809-84ce060e14-lite.chunk.js.map +1 -0
  24. package/dist/scripts/3878-45fd0861cc-lite.chunk.js +2 -0
  25. package/dist/scripts/3878-45fd0861cc-lite.chunk.js.map +1 -0
  26. package/dist/scripts/4096-c834372efb-lite.chunk.js +2 -0
  27. package/dist/scripts/4096-c834372efb-lite.chunk.js.map +1 -0
  28. package/dist/scripts/4456-ada4977b41-lite.chunk.js +2 -0
  29. package/dist/scripts/4456-ada4977b41-lite.chunk.js.map +1 -0
  30. package/dist/scripts/4806-a05a2a3012-lite.chunk.js +2 -0
  31. package/dist/scripts/4806-a05a2a3012-lite.chunk.js.map +1 -0
  32. package/dist/scripts/5099-297f8cd028-lite.chunk.js +2 -0
  33. package/dist/scripts/5099-297f8cd028-lite.chunk.js.map +1 -0
  34. package/dist/scripts/5829-903613bbf0-lite.chunk.js +3 -0
  35. package/dist/scripts/5829-903613bbf0-lite.chunk.js.map +1 -0
  36. package/dist/scripts/5925-937fec8a93-lite.chunk.js +2 -0
  37. package/dist/scripts/5925-937fec8a93-lite.chunk.js.map +1 -0
  38. package/dist/scripts/6459-ac139cb154-lite.chunk.js +2 -0
  39. package/dist/scripts/6459-ac139cb154-lite.chunk.js.map +1 -0
  40. package/dist/scripts/6629-4edaed39c8-lite.chunk.js +3 -0
  41. package/dist/scripts/6629-4edaed39c8-lite.chunk.js.map +1 -0
  42. package/dist/scripts/6984-9d8b378bcc-lite.chunk.js +2 -0
  43. package/dist/scripts/6984-9d8b378bcc-lite.chunk.js.map +1 -0
  44. package/dist/scripts/7103-ef79582538-lite.chunk.js +2 -0
  45. package/dist/scripts/7103-ef79582538-lite.chunk.js.map +1 -0
  46. package/dist/scripts/7394-5448807e14-lite.chunk.js +2 -0
  47. package/dist/scripts/7394-5448807e14-lite.chunk.js.map +1 -0
  48. package/dist/scripts/7502-78b085caad-lite.chunk.js +2 -0
  49. package/dist/scripts/7502-78b085caad-lite.chunk.js.map +1 -0
  50. package/dist/scripts/7548-5eb0d3b7a0-lite.chunk.js +2 -0
  51. package/dist/scripts/7548-5eb0d3b7a0-lite.chunk.js.map +1 -0
  52. package/dist/scripts/7593-cc4e09c847-lite.chunk.js +2 -0
  53. package/dist/scripts/7593-cc4e09c847-lite.chunk.js.map +1 -0
  54. package/dist/scripts/7657-e302fda4f2-lite.chunk.js +2 -0
  55. package/dist/scripts/7657-e302fda4f2-lite.chunk.js.map +1 -0
  56. package/dist/scripts/8057-431c6be34c-lite.chunk.js +2 -0
  57. package/dist/scripts/8057-431c6be34c-lite.chunk.js.map +1 -0
  58. package/dist/scripts/8224-b9b5d3b1a5-lite.chunk.js +2 -0
  59. package/dist/scripts/8224-b9b5d3b1a5-lite.chunk.js.map +1 -0
  60. package/dist/scripts/829-aff9937989-lite.chunk.js +3 -0
  61. package/dist/scripts/829-aff9937989-lite.chunk.js.map +1 -0
  62. package/dist/scripts/{9250-ec244ab17a-lite.chunk.js → 8723-708f2373d6-lite.chunk.js} +3 -3
  63. package/dist/scripts/{9250-ec244ab17a-lite.chunk.js.map → 8723-708f2373d6-lite.chunk.js.map} +1 -1
  64. package/dist/scripts/8960-c159492ba3-lite.chunk.js +2 -0
  65. package/dist/scripts/8960-c159492ba3-lite.chunk.js.map +1 -0
  66. package/dist/scripts/9673-8a2740611a-lite.chunk.js +2 -0
  67. package/dist/scripts/9673-8a2740611a-lite.chunk.js.map +1 -0
  68. package/dist/scripts/9882-f1a9cc55ec-lite.chunk.js +2 -0
  69. package/dist/scripts/9882-f1a9cc55ec-lite.chunk.js.map +1 -0
  70. package/dist/scripts/{bundle-d2cf17c78d.min.js → bundle-5a89651ec2.min.js} +3 -3
  71. package/dist/scripts/{bundle-d2cf17c78d.min.js.map → bundle-5a89651ec2.min.js.map} +1 -1
  72. package/package.json +1 -1
  73. package/dist/css/7428-lite-e2d7497beb.chunk.css +0 -8
  74. package/dist/scripts/1565-ba78a2a25c-lite.chunk.js +0 -2
  75. package/dist/scripts/1565-ba78a2a25c-lite.chunk.js.map +0 -1
  76. package/dist/scripts/2024-abf6cf1842-lite.chunk.js +0 -2
  77. package/dist/scripts/2024-abf6cf1842-lite.chunk.js.map +0 -1
  78. package/dist/scripts/2072-50b656cb3b-lite.chunk.js +0 -2
  79. package/dist/scripts/2072-50b656cb3b-lite.chunk.js.map +0 -1
  80. package/dist/scripts/2574-02faf4a2d2-lite.chunk.js +0 -2
  81. package/dist/scripts/2574-02faf4a2d2-lite.chunk.js.map +0 -1
  82. package/dist/scripts/396-2ffc09cc70-lite.chunk.js +0 -2
  83. package/dist/scripts/396-2ffc09cc70-lite.chunk.js.map +0 -1
  84. package/dist/scripts/4377-001a8ee263-lite.chunk.js +0 -2
  85. package/dist/scripts/4377-001a8ee263-lite.chunk.js.map +0 -1
  86. package/dist/scripts/4806-c2dce3650d-lite.chunk.js +0 -2
  87. package/dist/scripts/4806-c2dce3650d-lite.chunk.js.map +0 -1
  88. package/dist/scripts/4948-30af9a446d-lite.chunk.js +0 -2
  89. package/dist/scripts/4948-30af9a446d-lite.chunk.js.map +0 -1
  90. package/dist/scripts/549-2d591052e3-lite.chunk.js +0 -2
  91. package/dist/scripts/549-2d591052e3-lite.chunk.js.map +0 -1
  92. package/dist/scripts/5635-6e2559f04d-lite.chunk.js +0 -2
  93. package/dist/scripts/5635-6e2559f04d-lite.chunk.js.map +0 -1
  94. package/dist/scripts/5679-80c1d8434e-lite.chunk.js +0 -2
  95. package/dist/scripts/5679-80c1d8434e-lite.chunk.js.map +0 -1
  96. package/dist/scripts/5721-2141ed4fb6-lite.chunk.js +0 -2
  97. package/dist/scripts/5721-2141ed4fb6-lite.chunk.js.map +0 -1
  98. package/dist/scripts/5797-f84ce545b9-lite.chunk.js +0 -2
  99. package/dist/scripts/5797-f84ce545b9-lite.chunk.js.map +0 -1
  100. package/dist/scripts/581-fe733617bd-lite.chunk.js +0 -2
  101. package/dist/scripts/581-fe733617bd-lite.chunk.js.map +0 -1
  102. package/dist/scripts/5829-689f5be5d1-lite.chunk.js +0 -3
  103. package/dist/scripts/5829-689f5be5d1-lite.chunk.js.map +0 -1
  104. package/dist/scripts/6046-5652117548-lite.chunk.js +0 -2
  105. package/dist/scripts/6046-5652117548-lite.chunk.js.map +0 -1
  106. package/dist/scripts/6629-910e316a83-lite.chunk.js +0 -3
  107. package/dist/scripts/6629-910e316a83-lite.chunk.js.map +0 -1
  108. package/dist/scripts/6783-7efd15103a-lite.chunk.js +0 -3
  109. package/dist/scripts/6783-7efd15103a-lite.chunk.js.map +0 -1
  110. package/dist/scripts/7064-f5e8bc71bc-lite.chunk.js +0 -2
  111. package/dist/scripts/7064-f5e8bc71bc-lite.chunk.js.map +0 -1
  112. package/dist/scripts/7428-546d62999f-lite.chunk.js +0 -2
  113. package/dist/scripts/7428-546d62999f-lite.chunk.js.map +0 -1
  114. package/dist/scripts/7482-9016f79093-lite.chunk.js +0 -2
  115. package/dist/scripts/7482-9016f79093-lite.chunk.js.map +0 -1
  116. package/dist/scripts/7757-9b72774917-lite.chunk.js +0 -2
  117. package/dist/scripts/7757-9b72774917-lite.chunk.js.map +0 -1
  118. package/dist/scripts/7783-18da4064c0-lite.chunk.js +0 -2
  119. package/dist/scripts/7783-18da4064c0-lite.chunk.js.map +0 -1
  120. package/dist/scripts/8191-ff27deee6c-lite.chunk.js +0 -2
  121. package/dist/scripts/8191-ff27deee6c-lite.chunk.js.map +0 -1
  122. package/dist/scripts/8672-094d54cbbd-lite.chunk.js +0 -2
  123. package/dist/scripts/8672-094d54cbbd-lite.chunk.js.map +0 -1
  124. package/dist/scripts/8723-c3aaa1643a-lite.chunk.js +0 -2
  125. package/dist/scripts/8723-c3aaa1643a-lite.chunk.js.map +0 -1
  126. package/dist/scripts/9583-3b2623e754-lite.chunk.js +0 -2
  127. package/dist/scripts/9583-3b2623e754-lite.chunk.js.map +0 -1
  128. /package/dist/css/{4377-lite-856c02f000.chunk.css → 1107-lite-856c02f000.chunk.css} +0 -0
  129. /package/dist/css/{581-lite-a1cdc302ab.chunk.css → 1437-lite-a1cdc302ab.chunk.css} +0 -0
  130. /package/dist/css/{7757-lite-856c02f000.chunk.css → 4456-lite-856c02f000.chunk.css} +0 -0
  131. /package/dist/css/{9250-lite-37216d4207.chunk.css → 8723-lite-37216d4207.chunk.css} +0 -0
  132. /package/dist/scripts/{5829-689f5be5d1-lite.chunk.js.LICENSE.txt → 5829-903613bbf0-lite.chunk.js.LICENSE.txt} +0 -0
  133. /package/dist/scripts/{6629-910e316a83-lite.chunk.js.LICENSE.txt → 6629-4edaed39c8-lite.chunk.js.LICENSE.txt} +0 -0
  134. /package/dist/scripts/{6783-7efd15103a-lite.chunk.js.LICENSE.txt → 829-aff9937989-lite.chunk.js.LICENSE.txt} +0 -0
  135. /package/dist/scripts/{9250-ec244ab17a-lite.chunk.js.LICENSE.txt → 8723-708f2373d6-lite.chunk.js.LICENSE.txt} +0 -0
  136. /package/dist/scripts/{bundle-d2cf17c78d.min.js.LICENSE.txt → bundle-5a89651ec2.min.js.LICENSE.txt} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts/2809-84ce060e14-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/pending-indicator/PendingIndicator.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/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/hooks/UseMarkAnswers.ts","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/components/percentage-indicator/PercentageIndicator.tsx","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicatorUtils.ts","file:///app/packages/libs/shared/src/constants/DragOverlayStyles.ts","file:///app/packages/libs/shared/src/components/table/TableUtils.ts","file:///app/packages/libs/shared/src/components/table/table.scss","file:///app/packages/libs/shared/src/components/table/Table.tsx","file:///app/packages/libs/shared/src/hooks/useLockContentWidth.ts","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/my-shares/components/interactive-insights-questions/partial-loading/partial-interactive-insights-questions.scss","file:///app/packages/projects/lite/src/apps/my-shares/components/interactive-insights-questions/partial-loading/PartialInteractiveInsightsQuestions.tsx","file:///app/packages/projects/lite/src/apps/my-shares/components/interactive-insights-questions/InteractiveInsightsQuestions.tsx","file:///app/packages/libs/shared/src/components/percentage-indicator/percentage-indicator.scss"],"sourcesContent":["import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { PercentageIndicator } from 'libs/shared/components/percentage-indicator/PercentageIndicator';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\n\nconst namespace = 'interactives.pendingIndicator';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getClassName(props: PendingIndicatorProps): string {\n let className = 'd-flex align-items-center h-100';\n\n className += props.showLabel ? ' justify-content-between' : ' justify-content-center';\n\n if (props.className)\n className += ` ${props.className}`;\n\n return className;\n}\n\ninterface PendingIndicatorProps {\n title?: string;\n className?: string;\n showLabel?: boolean;\n tooltipClassName?: string;\n}\n\nexport function PendingIndicator(props: PendingIndicatorProps): JSX.Element {\n const Indicator = () => (\n <div className={getClassName(props)}>\n {!!props.showLabel &&\n <em>{getPhrase('pending')}</em>\n }\n <PercentageIndicator />\n </div>\n );\n\n if (!props.title)\n return <Indicator />;\n\n return (\n <Tooltip title={props.title} spanHack spanHackClassName={props.tooltipClassName || 'h-100 w-100 d-flex align-items-center'}>\n <Indicator />\n </Tooltip>\n );\n}","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?.sessionId}\n />\n </div>\n \n </div>\n }\n <div className='flex-grow-1'>\n {!!props.showStudentDetails &&\n <InteractionStudentDetailsHeader\n studentResults={props.studentResults}\n correctness={correctness}\n anonymisedUserName={props.anonymisedUserName}\n />\n }\n <div className='d-flex justify-content-between'>\n <div className={`flex-grow-1 mb-2 ${props.responseComponentClass ? props.responseComponentClass : ''}`}>\n {studentAttempt\n ? <ResponseItemComponent\n interaction={props.interaction}\n answers={studentAttempt.answers}\n imageCdnUrl={props.imageCdnUrl}\n user={props.studentResults.user}\n showFeedback={props.showFeedback}\n showAvatar={props.showAvatar}\n >\n <MarkResponse\n studentAttempt={studentAttempt}\n correctness={correctness}\n markInteraction={props.markInteraction}\n markedStatus={props.markedStatus}\n />\n </ResponseItemComponent>\n : <NoResponse />\n }\n </div>\n {!props.showStudentDetails &&\n <InteractionResponseCorrectness correctness={correctness} />\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n}","import { 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 { 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 { ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport {\n getCircleClassName,\n getCircleContainerClassName,\n getCircleRadius,\n getColouredLabelClassName,\n getFormattedPercentage,\n getPercentageToFixed,\n isPending,\n ProgressCircleSize\n} from './PercentageIndicatorUtils';\n\nimport styles from './percentage-indicator.scss';\n\ninterface ProgressCircleProps {\n size: ProgressCircleSize;\n scoreThresholds?: ScoreThresholds;\n percentage?: number;\n}\n\nfunction ProgressCircle(props: ProgressCircleProps): JSX.Element {\n const ref = React.useCallback((circle: SVGCircleElement) => {\n if (!circle)\n return;\n\n const radius = circle.r.baseVal.value;\n const circumference = 2 * Math.PI * radius;\n const offset = circumference - props.percentage * circumference;\n\n circle.style.strokeDasharray = `${circumference} ${circumference}`;\n circle.style.strokeDashoffset = offset.toString();\n }, [props.percentage]);\n\n return (\n <svg>\n <circle r={getCircleRadius(props.size)} className={styles.backgroundCircle} />\n {!isPending(props.percentage) &&\n <circle\n ref={ref}\n r={getCircleRadius(props.size)}\n className={getCircleClassName(props.percentage, props.scoreThresholds)}\n />\n }\n </svg>\n );\n}\n\nexport enum PercentageIndicatorLayout {\n CircleOnly = 'circle_only',\n LabelOnly = 'label_only',\n LabelBefore = 'label_before',\n LabelInside = 'label_inside'\n}\n\ninterface PercentageIndicatorProps {\n layout: PercentageIndicatorLayout;\n percentage?: number; // Between 0 and 1 or undefined for pending\n className?: string;\n customLabel?: string;\n scoreThresholds?: ScoreThresholds;\n size?: ProgressCircleSize;\n}\n\nPercentageIndicator.defaultProps = {\n layout: PercentageIndicatorLayout.CircleOnly\n};\n\nexport function PercentageIndicator(props: PercentageIndicatorProps): JSX.Element {\n const percentageToFixed = getPercentageToFixed(props.percentage);\n\n const size = props.size ||\n (props.layout === PercentageIndicatorLayout.LabelInside\n ? ProgressCircleSize.Large\n : ProgressCircleSize.Small\n );\n\n const label = props.customLabel || getFormattedPercentage(percentageToFixed);\n\n if (props.layout === PercentageIndicatorLayout.LabelOnly)\n return (\n <span className={getColouredLabelClassName(percentageToFixed)}>\n {label}\n </span>\n );\n\n return (\n <div className={`d-flex align-items-center justify-content-between ${props.className ?? ''}`}>\n {props.layout === PercentageIndicatorLayout.LabelBefore &&\n <span className='me-2'>\n {label}\n </span>\n }\n <div className={getCircleContainerClassName(size, percentageToFixed)}>\n <ProgressCircle percentage={percentageToFixed} size={size} scoreThresholds={props.scoreThresholds} />\n {props.layout === PercentageIndicatorLayout.LabelInside &&\n <span className={styles.centredPercentageText}>\n {label}\n </span>\n }\n </div>\n </div>\n );\n}","import { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport styles from './percentage-indicator.scss';\n\n/**\n * Values for width and strokeWidth are taken from progress-circle.scss.\n * If either are changed, they must be updated in both places.\n */\nconst CIRCLE_WIDTH = 2; // rem\nconst CIRCLE_WIDTH_LG = 5.8; // rem\nconst CIRCLE_STROKE_WIDTH = 0.2; // rem\nconst CIRCLE_STROKE_WIDTH_LG = 0.36; // rem\n \nexport enum ProgressCircleSize {\n Small = 'small',\n Large = 'large',\n ExtraSmall = 'extraSmall'\n}\n\nconst ProgressCircleSizeMap = {\n [ProgressCircleSize.ExtraSmall]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Small]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Large]: {\n size: CIRCLE_WIDTH_LG\n }\n};\n\n/**\n * radius = width / 2 - strokeWidth * 2\n */\nexport function getCircleRadius(size: ProgressCircleSize): string {\n const width = ProgressCircleSizeMap[size].size;\n const strokeWidth = size === ProgressCircleSize.Large ? CIRCLE_STROKE_WIDTH_LG : CIRCLE_STROKE_WIDTH;\n return `${width / 2 - strokeWidth * 2}rem`;\n}\n \nexport function getCircleClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return styles.circleSuccess;\n \n if (percentage >= scoreThresholds.MODERATE)\n return styles.circleWarning;\n \n return styles.circleDanger;\n}\n \nexport function getColouredLabelClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return 'text-success';\n \n if (percentage >= scoreThresholds.MODERATE)\n return 'text-warning';\n \n return 'text-danger';\n}\n \nexport function getCircleContainerClassName(size: ProgressCircleSize, percentage?: number): string {\n let className = `d-inline-block ${styles.circleContainer}`;\n \n if (size === ProgressCircleSize.Large)\n className += ` ${styles.lgCircleContainer}`;\n\n if (size === ProgressCircleSize.ExtraSmall)\n className += ` ${styles.xsCircleContainer}`;\n\n if (isPending(percentage))\n className += ` ${styles.pendingCircle}`;\n \n return className;\n}\n\nexport function getPercentageToFixed(percentage?: number): number | undefined {\n if (isPending(percentage))\n return;\n \n return +percentage.toFixed(2);\n}\n \nexport function getFormattedPercentage(percentage?: number): string {\n if (isPending(percentage))\n return `--%`;\n\n return `${Math.round(percentage * 100)}%`;\n}\n\nexport function isPending(percentage?: number): boolean {\n return typeof percentage !== 'number';\n}","export const DragOverlayStyles = { opacity: '0.8', cursor: 'grabbing' };","import React from 'react';\nimport { PluginHook, useBlockLayout, useFilters, useFlexLayout, useGlobalFilter, useRowSelect, useSortBy } from 'react-table';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\ninterface PluginOptions {\n allowFiltering?: boolean;\n allowGlobalFiltering?: boolean;\n layout?: 'flex' | 'block';\n}\n\nexport function getPlugins<T extends HashObject>(props: PluginOptions): PluginHook<T>[] {\n let plugins: PluginHook<T>[] = [\n useSortBy,\n useRowSelect,\n props.layout === 'flex' ? useFlexLayout : useBlockLayout\n ];\n\n if (props.allowFiltering)\n plugins = [\n ...plugins,\n useFilters\n ];\n\n if (props.allowGlobalFiltering)\n plugins = [\n ...plugins,\n useGlobalFilter\n ];\n\n return plugins;\n}\n\nexport function getSelectedRowIds(ids: string[]): Record<string, boolean> {\n const idHash: Record<string, boolean> = {};\n\n ids.forEach(id => idHash[id] = true);\n\n return idHash;\n}\n\ninterface TableScrollState {\n canScrollLeft: boolean;\n canScrollRight: boolean;\n}\n\nfunction calculateScrollState(ref: React.MutableRefObject<HTMLDivElement>): TableScrollState {\n const canScrollLeft = ref.current?.scrollLeft > 0;\n const canScrollRight = (ref.current?.scrollLeft + 1) < ref.current?.scrollWidth - ref.current?.clientWidth;\n\n return { canScrollLeft, canScrollRight };\n}\n\ninterface UseTableScroll {\n ref: (el: HTMLDivElement) => void;\n scrollState: TableScrollState;\n scroll: (scrollBy: number) => void;\n}\n\nexport function useTableScroll(): UseTableScroll {\n const elRef = React.useRef<HTMLDivElement>(null);\n const [ scrollState, setScrollState ] = React.useState<TableScrollState>(calculateScrollState(elRef));\n\n function onScroll(): void {\n setScrollState(calculateScrollState(elRef));\n }\n\n function scroll(scrollBy: number): void {\n elRef.current?.scrollBy({ left: scrollBy, top: 0, behavior: 'smooth' });\n }\n\n const throttledOnScroll = FunctionHelper.throttle(onScroll, 200);\n\n const ref = React.useCallback((el: HTMLDivElement) => {\n if (elRef.current) {\n elRef.current?.removeEventListener('scroll', throttledOnScroll);\n }\n\n if (el) {\n setScrollState(calculateScrollState(elRef));\n el.addEventListener('scroll', throttledOnScroll);\n }\n\n elRef.current = el;\n }, []);\n\n React.useEffect(() => {\n if (elRef?.current) {\n setScrollState(calculateScrollState(elRef));\n }\n }, [elRef]);\n\n return { ref, scrollState, scroll };\n}","// extracted by mini-css-extract-plugin\nexport default {\"sortIndicator\":\"gFhu0\",\"scrollContainer\":\"sWUp9\",\"scrollbarTrack\":\"Vn2qM\"};","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\nimport {\n Cell,\n Column as BaseColumn,\n HeaderGroup,\n HeaderProps as BaseHeaderProps,\n IdType,\n Row,\n SortingRule,\n TableOptions,\n TableRowProps,\n useTable } from 'react-table';\nimport { DragEndEvent } from '@dnd-kit/core';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SortableContainerWrapper } from 'libs/shared/components/sortable/SortableContainerWrapper';\nimport { PropsWithSortableItemProps, SortableItemWrapper } from 'libs/shared/components/sortable/SortableItemWrapper';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetButton, WidgetButtonDirection } from 'libs/shared/components/widgets/widget-button/WidgetButton';\nimport { DragOverlayStyles } from 'libs/shared/constants/DragOverlayStyles';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { getPlugins, getSelectedRowIds, useTableScroll } from './TableUtils';\n\nimport styles from './table.scss';\n\nexport interface TableTheme {\n table?: string;\n header?: string;\n headerRow?: string;\n headerCell?: string;\n body?: string;\n row?: string | ((row: Row<any>) => string);\n selectedRow?: string;\n cell?: string | ((row?: Row<any>, cell?: Cell<any, any>) => string);\n sortIndicator?: string;\n}\n\nexport type HeaderProps<T extends HashObject> = BaseHeaderProps<T> & {\n renderSortIndicator: () => void;\n}\n\nexport type Column<T extends HashObject> = BaseColumn<T> & {\n hideSortIndicator?: boolean;\n}\n\ninterface SortIndicatorProps<T extends HashObject> {\n column: HeaderGroup<T>;\n theme?: TableTheme;\n}\n\nfunction SortIndicator<T extends HashObject>(props: SortIndicatorProps<T>): JSX.Element {\n if (!props.column.canSort)\n return <></>;\n\n return (\n <span\n className={\n `${styles.sortIndicator}\n ${!props.column.isSorted ? 'text-secondary' : ''}\n ${props.theme?.sortIndicator ?? ''}`\n }\n >\n <SvgContainer\n svgName={(props.column.isSortedDesc || !props.column.isSorted)\n ? cvSvgLibrary.ArrowRight\n : cvSvgLibrary.ArrowLeft\n }\n size={SvgContainerSize.Small}\n />\n </span>\n );\n}\n\ninterface BaseTableProps<T extends HashObject> {\n /**\n * Must be memoized.\n */\n data: T[];\n\n /**\n * Must be memoized.\n * \n * For documentation on Column Options, see https://react-table.tanstack.com/docs/api/useTable#column-options\n */\n columns: Column<T>[];\n\n theme?: TableTheme;\n\n onSelectRow?: (row: Row<T>) => void;\n\n onSelectCell?: (cell: Cell<T>) => void;\n\n onRowMouseOver?: (row: Row<T>) => void;\n\n onRowMouseLeave?: (row: Row<T>) => void;\n\n allowSelectMultipleRows?: boolean;\n\n initialSelectedRowIds?: string[];\n\n getRowId?: (row: T) => string;\n\n getRowAppLink?: (row: Row<T>) => Core.AppLink;\n\n enableSort?: boolean;\n\n manualSort?: boolean;\n\n onSort?: (sortingRule: SortingRule<T>[]) => void;\n \n // Opt-in to utilise react-table's useFilter hook.\n allowFiltering?: boolean;\n\n // Opt-in to utilise react-table's useGlobalFilter hook.\n allowGlobalFiltering?: boolean;\n\n // Use either a flex layout or a block layout. Default is flex.\n layout?: 'flex' | 'block';\n\n // Used by useGlobalFilter hook, needs to be enabled by prop above.\n globalFilter?: string;\n\n // Set initial state of hidden columns in react-table.\n hiddenColumns?: IdType<T>[];\n\n // Determine whether hidden columns should be preserved on a table update event.\n autoResetHiddenColumns?: boolean;\n\n // Determine whether sort order state should be preserved on a table update event.\n autoResetSortBy?: boolean;\n\n // Determine whether rows are sortable by drag and drop\n enableSortableRows?: boolean;\n\n onSortingRowsEnd?: (event: DragEndEvent) => void;\n\n // Set initial state of sorting in react-table\n initialSortBy?: SortingRule<T>[];\n}\n \ntype SortableRowProps = PropsWithSortableItemProps<TableRowProps>;\n\nfunction BaseTable<T extends HashObject>(props: BaseTableProps<T>): JSX.Element {\n const tableOptions: TableOptions<T> = {\n columns: props.columns,\n data: props.data,\n disableSortBy: !props.enableSort,\n manualSortBy: props.manualSort,\n autoResetHiddenColumns: props.autoResetHiddenColumns,\n autoResetSortBy: props.autoResetSortBy,\n initialState: {\n sortBy: props.initialSortBy || []\n }\n };\n\n if (props.initialSelectedRowIds)\n tableOptions.initialState = { selectedRowIds: getSelectedRowIds(props.initialSelectedRowIds) };\n\n if (props.getRowId)\n tableOptions.getRowId = props.getRowId;\n\n const {\n getTableProps,\n getTableBodyProps,\n headerGroups,\n rows,\n prepareRow,\n toggleAllRowsSelected,\n setGlobalFilter,\n setHiddenColumns,\n state: { sortBy }\n } = useTable<T>(tableOptions, ...getPlugins<T>({ ...props }));\n\n function getTableRowsClass(row: Row<T>) {\n let className = FunctionHelper.isFunction(props.theme?.row)\n ? props.theme.row(row)\n : props.theme?.row ?? '';\n\n if (row.isSelected && props.theme?.selectedRow)\n className += ` ${props.theme?.selectedRow}`;\n\n if (props.onSelectRow)\n className += ' cursor-pointer';\n\n if (props.enableSortableRows)\n className += ' cursor-grab';\n\n return className;\n }\n\n function renderTableRows(): JSX.Element[] {\n return rows.map(row => {\n prepareRow(row);\n \n const className = getTableRowsClass(row);\n const rowAppLink = !!props.getRowAppLink && props.getRowAppLink(row);\n\n function onClickRow(): void {\n if (!props.onSelectRow)\n return;\n\n if (!props.allowSelectMultipleRows)\n toggleAllRowsSelected(false);\n \n props.onSelectRow(row);\n row.toggleRowSelected(true);\n }\n\n function getSortableProps(props: TableRowProps | PropsWithSortableItemProps<TableRowProps>, ref?: any) {\n if ('dragAttributes' in props && 'dragListeners' in props) {\n return {\n ...props.dragAttributes,\n ...props.dragListeners,\n 'aria-roledescription': 'Sortable row',\n ref\n };\n }\n\n return {};\n }\n\n function renderRow(props: TableRowProps | PropsWithSortableItemProps<TableRowProps>, ref?: any): JSX.Element {\n const sortableProps = getSortableProps(props, ref);\n\n if (rowAppLink) {\n return (\n <div\n role='row'\n key={row.id}\n >\n <AppLink\n {...props}\n {...sortableProps}\n className={className}\n appLink={rowAppLink}\n >\n {renderCells(row)}\n </AppLink>\n </div>\n );\n }\n\n return (\n <div\n {...props}\n {...sortableProps}\n key={row.id}\n role='row'\n className={className}\n onClick={onClickRow}\n >\n {renderCells(row)}\n </div>\n );\n }\n\n const rowProps = row.getRowProps();\n\n if (props.enableSortableRows) {\n return (\n <SortableItemWrapper\n id={row.original.id}\n key={row.id}\n childProps={rowProps}\n childComponent={React.forwardRef(\n (props: SortableRowProps, ref: React.LegacyRef<HTMLDivElement>) => (renderRow(props, ref))\n )}\n />\n );\n }\n\n return renderRow(rowProps);\n });\n }\n\n function getDragOverlayClassName(theme: TableTheme): string {\n let className = 'g-0 ';\n\n if (theme)\n className += theme.row;\n\n return className;\n }\n\n function getDragOverlay(id: string) {\n const rowIndex = rows.findIndex(item => item.original.id === id);\n const row = rows[rowIndex];\n \n return (\n <div\n {...props}\n className={getDragOverlayClassName(props.theme)}\n style={DragOverlayStyles}\n >\n {renderCells(row)}\n </div>\n );\n }\n\n function getCellClassName(row: Row<T>, cell: Cell<T>): string {\n let cellClassName = '';\n\n if (typeof props.theme?.cell === 'function')\n cellClassName = props.theme.cell(row, cell);\n\n if (typeof props.theme?.cell === 'string')\n cellClassName = props.theme.cell;\n\n if (props.onSelectCell)\n cellClassName += ' cursor-pointer';\n\n return cellClassName;\n }\n\n function renderCells(row: Row<T>): JSX.Element[] {\n return row.cells.map(cell => {\n const cellClassName = getCellClassName(row, cell);\n\n function onClickCell(): void {\n props.onSelectCell && props.onSelectCell(cell);\n }\n\n return (\n <div key={cell.column.id} {...cell.getCellProps()} className={cellClassName} onClick={onClickCell} >\n {cell.render('Cell')}\n </div>\n );\n });\n }\n\n React.useEffect(() => {\n if (!props.onSort)\n return;\n\n props.onSort(sortBy);\n }, [sortBy]);\n\n React.useEffect(() => {\n if (!props.globalFilter)\n return;\n\n setGlobalFilter(props.globalFilter);\n }, [props.globalFilter]);\n\n React.useEffect(() => {\n if (!props.hiddenColumns)\n return;\n\n setHiddenColumns(props.hiddenColumns);\n }, [props.hiddenColumns && props.hiddenColumns.length]);\n\n return (\n <div {...getTableProps()} className={props.theme?.table ?? ''}>\n <div className={props.theme?.header ?? ''}>\n {headerGroups.map(headerGroup => (\n <div {...headerGroup.getHeaderGroupProps()} className={props.theme?.headerRow ?? ''}>\n {headerGroup.headers.map(column => (\n <div {...column.getHeaderProps(column.getSortByToggleProps())} className={props.theme?.headerCell ?? ''}>\n {column.render('Header', { renderSortIndicator: () => <SortIndicator column={column} theme={props.theme} /> })}\n {!(column as Column<T>).hideSortIndicator &&\n <SortIndicator column={column} theme={props.theme} />\n }\n </div>\n ))}\n </div>\n ))}\n </div>\n <div {...getTableBodyProps()} className={props.theme?.body ?? ''}>\n { props.enableSortableRows ? (\n <SortableContainerWrapper\n ids={rows.map(row => row.original.id)}\n getDragOverlay={getDragOverlay}\n onSortEnd={props.onSortingRowsEnd}\n >\n {renderTableRows()}\n </SortableContainerWrapper>\n ) : (\n renderTableRows()\n )}\n </div>\n </div>\n );\n}\n\ninterface TableProps<T extends HashObject> extends BaseTableProps<T> {\n enableSlider?: boolean;\n scrollIncrement?: number;\n scrollContainerClassName?: string;\n scrollable?: boolean;\n initialSortBy?: SortingRule<T>[];\n}\n\nTable.defaultProps = {\n scrollIncrement: 250,\n scrollable: false,\n layout: 'flex'\n};\n\nexport function Table<T extends HashObject>(props: TableProps<T>): JSX.Element {\n const { enableSlider, scrollIncrement, scrollable, ...tableProps } = props;\n\n const { ref, scrollState, scroll } = useTableScroll();\n\n if (scrollable) {\n return (\n <Scrollbars\n renderTrackHorizontal={() => <div className={styles.scrollbarTrack} />}\n autoHeightMax={10000}\n autoHeight\n >\n <BaseTable {...tableProps} />\n </Scrollbars>\n );\n }\n\n if (!enableSlider)\n return <BaseTable {...tableProps} />;\n\n function onClickScroll(direction: 'left' | 'right'): void {\n scroll(scrollIncrement * (direction === 'right' ? 1 : -1));\n }\n\n return (\n <div className='mx-n4 overflow-x-hidden overflow-y-hidden'>\n <div className='px-4'>\n <div className='position-relative'>\n <WidgetButton\n direction={WidgetButtonDirection.Left}\n onClick={() => onClickScroll('left')}\n hide={!scrollState.canScrollLeft}\n />\n <div className={`${styles.scrollContainer} ${props.scrollContainerClassName}`} ref={ref}>\n <BaseTable {...tableProps } />\n </div>\n <WidgetButton\n direction={WidgetButtonDirection.Right}\n onClick={() => onClickScroll('right')}\n hide={!scrollState.canScrollRight}\n />\n </div>\n </div>\n </div>\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 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 { AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { anonymiseUserName, getUserOrAnonSession } 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.sessionId]: 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 anonSessions?: AnonSessions;\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 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(\n getUserOrAnonSession(s, props.anonSessions),\n props.anonymiseUsers\n );\n const markingRequired = responsesToMark[s.user?.id || s.sessionId];\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={props.reportsStyling ? '' : '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 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 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={`${props.interaction.id}${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 { AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\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 anonSessions?: AnonSessions;\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={`rounded flex-grow-1 ${props.reportsStyling ? '' : 'border'}`}>\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 anonSessions={props.anonSessions}\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\":\"mhxg4\"};","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 { AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\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/my-shares/components/interactive-insights-questions/partial-loading/PartialInteractiveInsightsQuestions';\n\n\nconst namespace = 'shared.interactiveInsightsQuestions';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst theme: TableTheme = {\n table: 'bg-white rounded border 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 anonSessions?: AnonSessions;\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 anonSessions={props.anonSessions}\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}","// extracted by mini-css-extract-plugin\nexport default {\"circleContainer\":\"p8Vgz\",\"backgroundCircle\":\"asGGE\",\"circleSuccess\":\"PXLNj\",\"circleWarning\":\"ZckRN\",\"circleDanger\":\"slBRg\",\"lgCircleContainer\":\"N8KCI\",\"xsCircleContainer\":\"RPqZ2\",\"pendingCircle\":\"DKrcq\",\"centredPercentageText\":\"tpmLR\"};"],"names":["getPhrase","getClassName","props","className","showLabel","PendingIndicator","Indicator","title","spanHack","spanHackClassName","tooltipClassName","AnswerContainer","answer","key","id","status","InteractiveAnswerStatus","getBgColour","SvgContainer","svgName","customAnswer","textClassName","text","children","LanguageService","NoResponseRequired","ResponseItemComponentLookup","answers","length","map","ArrayHelper","src","alt","interaction","name","InteractionResponseItem","ResponseItemComponent","typeId","result","studentResults","studentAttempt","correctness","InteractiveCorrectnessHelper","showStudentDetails","Avatar","imageCdnUrl","initials","anonymisedUserName","UserHelper","user","surname","imageUrl","avatar","url","showAnonymousUser","sessionId","InteractionStudentDetailsHeader","responseComponentClass","showFeedback","showAvatar","MarkResponse","markInteraction","markedStatus","NoResponse","InteractionResponseCorrectness","useMarkAnswers","interactiveId","interactiveMetadataId","onDone","useState","markedAnswers","setMarkedAnswers","dispatch","alerts","addMarkedAnswers","forEach","a","m","submitMarkedAnswers","Object","keys","completeCount","successCount","resultId","questionId","I","onSuccess","onAlways","alertMessage","useErrorAlert","smartCount","error","success","getSortStudents","sortBy","desc","shouldFilterStudent","filter","summary","awaitingMarking","percentCorrect","unanswered","ConfirmationPopup","showButtonSpinner","setShowButtonSpinner","closePopup","onClick","variant","cancelButtonVariant","cancelButtonText","onClickConfirm","confirmButtonText","confirmButtonVariant","showSpinner","disabled","disabledConfirmButton","defaultProps","PercentageIndicatorLayout","ProgressCircle","ref","circle","radius","r","baseVal","value","circumference","Math","PI","offset","percentage","style","strokeDasharray","strokeDashoffset","toString","size","scoreThresholds","PercentageIndicator","percentageToFixed","layout","LabelInside","label","customLabel","LabelOnly","LabelBefore","CircleOnly","ProgressCircleSize","CIRCLE_STROKE_WIDTH","CIRCLE_STROKE_WIDTH_LG","ProgressCircleSizeMap","ExtraSmall","Small","Large","getCircleRadius","width","strokeWidth","getCircleClassName","HIGH","MODERATE","getColouredLabelClassName","getCircleContainerClassName","isPending","getPercentageToFixed","toFixed","getFormattedPercentage","round","DragOverlayStyles","opacity","cursor","calculateScrollState","canScrollLeft","current","scrollLeft","canScrollRight","scrollWidth","clientWidth","SortIndicator","column","canSort","isSorted","theme","sortIndicator","isSortedDesc","S","BaseTable","ids","idHash","tableOptions","columns","data","disableSortBy","enableSort","manualSortBy","manualSort","autoResetHiddenColumns","autoResetSortBy","initialState","initialSortBy","initialSelectedRowIds","selectedRowIds","getRowId","useTable","plugins","useSortBy","useRowSelect","useFlexLayout","useBlockLayout","allowFiltering","useFilters","allowGlobalFiltering","useGlobalFilter","getPlugins","getTableProps","getTableBodyProps","headerGroups","rows","prepareRow","toggleAllRowsSelected","setGlobalFilter","setHiddenColumns","state","renderTableRows","row","FunctionHelper","isSelected","selectedRow","onSelectRow","enableSortableRows","getTableRowsClass","rowAppLink","getRowAppLink","onClickRow","allowSelectMultipleRows","toggleRowSelected","renderRow","sortableProps","dragAttributes","dragListeners","getSortableProps","role","AppLink","appLink","renderCells","rowProps","getRowProps","SortableItemWrapper","original","childProps","childComponent","cells","cell","cellClassName","onSelectCell","getCellClassName","getCellProps","render","onSort","globalFilter","hiddenColumns","table","header","headerGroup","getHeaderGroupProps","headerRow","headers","getHeaderProps","getSortByToggleProps","headerCell","renderSortIndicator","hideSortIndicator","body","SortableContainerWrapper","getDragOverlay","rowIndex","findIndex","item","onSortEnd","onSortingRowsEnd","Table","enableSlider","scrollIncrement","scrollable","tableProps","elRef","scrollState","setScrollState","throttledOnScroll","el","removeEventListener","addEventListener","scroll","scrollBy","left","top","behavior","useTableScroll","renderTrackHorizontal","autoHeightMax","autoHeight","onClickScroll","direction","WidgetButton","W","hide","scrollContainerClassName","useLockContentWidth","namespace","InteractionResponseListFiltersEmptyStates","EmptyState","correctImageUrl","incorrectImageUrl","markingRequiredImageUrl","skippedImageUrl","getFilterEmptyStateImageUrl","Text","phrase","getFilterEmptyStatePhrase","InteractionResponseListFilters","getFilterClassName","filterButton","isFilterSelected","toggleFilter","InteractionResponseListHeader","suggestedResponse","InteractionLabel","iconClassName","SubmitMarkedAnswers","submit","InteractionResponseList","setFilter","responsesToMark","results","students","s","InteractionCorrectness","reduce","acc","numMarkedAnswers","emptyStateImageUrl","filteredStudentResults","filterMap","correct","incorrect","marking_required","skipped","reportsStyling","Tooltip","isDemo","selectedFilter","idx","anonSessions","anonymiseUsers","markingRequired","InteractionResponse","QuestionTableMissingWord","str","sentence","split","part","index","match","replacement","actionableItems","find","order","QuestionTableMultipleChoice","MultipleChoiceInteractionAnswers","showCorrectnessIcons","isDisplayOnly","option","isCorrect","indexToLetter","QuestionTableShortAnswer","QuestionTableTrueOrFalse","QuestionTableAnswers","QuestionTableAnswerComponent","getQuestionTableAnswerComponent","sortScore","rowA","rowB","columnId","cellA","cellB","CellWrapper","HeaderCell","phraseKey","String","fromCharCode","charCodeAt","multipleChoiceSummary","questionsSummary","i","count","student","latestAttempts","attempts","response","questionSummary","missingWordSummary","push","markedSummary","pendingSummary","QuestionResultsSummary","summaryMethod","getQuestionSummary","maxResponseCount","getBarClassName","height","SelectedInteractionEmptyState","emptyStateUrl","QuestionTable","showAnswersInTable","setSortBy","interactive","refreshData","flattenedInteractions","questionNumbers","interactions","questionNumber","resultsSummary","sorted","reverse","useGetTableData","refreshTable","selectedInteraction","selectedInteractionId","Header","accessor","Cell","containerClassName","sortDescFirst","sortType","ScrollHelper","AppRouteHelper","interactionId","merge","selectQuestionImageUrl","PartialInteractiveInsightsQuestions","InteractiveInsightsQuestions","showMarkConfirmationPopup","setShowMarkConfirmationPopup","interactiveMetadata","hasDataLoaded","config","isFetching","ImageUrls"],"sourceRoot":""}
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[3878],{38307:(e,t,n)=>{n.d(t,{c:()=>h,l:()=>f});var a=n(32735),r=n(232),i=n.n(r),s=n(8604),o=n(83345);const c={heatMap:"epapa",legend:"uhH4p"};function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=Array(t);n<t;n++)a[n]=e[n];return a}var u="shared.engagementHeatMap",d="#f1f1f1",m=i().scale(["#daf07d","#08bd1a"]),v=[0,.01,.25,.5,.75,1];function g(e,t){return e?m(e/t).hex():d}function p(e,t){for(var n=[],a=0;a<e.length;a++){var r=a>0&&e[a-1],i=e[a],s=a<e.length-1&&e[a+1];i===r&&i===s||n.push("".concat(g(i,t)," ").concat(100/e.length*a,"%"))}return"linear-gradient(to right, ".concat(n.join(","),")")}function f(){var e=Math.max.apply(Math,v),t=100/v.length;return a.createElement("div",{className:"d-flex justify-content-between w-100"},a.createElement(o.x,{namespace:u,phrase:"less"}),a.createElement("div",{className:"d-flex mx-1 flex-grow-1 ".concat(c.legend)},v.map((function(n,r){return a.createElement("div",{key:r,style:{width:"".concat(t,"%"),backgroundColor:g(n,e)}})}))),a.createElement(o.x,{namespace:u,phrase:"more"}))}function h(e){var t,n,r,i=(0,s.O)(e.engagement),o=null!==(t=e.max)&&void 0!==t?t:Math.max.apply(Math,function(e){if(Array.isArray(e))return l(e)}(r=i)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(r)||function(e,t){if(e){if("string"==typeof e)return l(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(e,t):void 0}}(r)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());return a.createElement("div",{className:"border rounded ".concat(c.heatMap," ").concat(null!==(n=e.className)&&void 0!==n?n:""),style:{background:p(i,o)}})}},26136:(e,t,n)=>{n.d(t,{B2:()=>o,DV:()=>l,jP:()=>c});var a=n(76198),r=n(23481),i=n(64818),s=r.T.encloseNamespace("shared.analyticsUtils");function o(e,t){return e?t?(0,a._8)((n="sessionId"in e?e.sessionName:e.id,r=+"".concat(n).concat(Math.floor((new Date).getMinutes()/5)),{dictionaries:[a.O9,a.yd],separator:" ",length:2,style:"capital",seed:r})):"sessionId"in e?e.sessionName:i.l.getFullName(e):"";var n,r}function c(e,t){var n={sessionId:e,sessionName:s("anonymousUser")};return e&&t&&t[e]||n}function l(e,t){return e.user?e.user:c(e.sessionId,t)}},8604:(e,t,n)=>{function a(e){return new Array(Math.ceil(e.videoDuration)).fill(null).map((function(t,n){return e.heatMap[n]||0}))}n.d(t,{O:()=>a})},39157:(e,t,n)=>{n.d(t,{HI:()=>m,R6:()=>l,Rt:()=>g,UU:()=>d,Zs:()=>u,nq:()=>v});var a=n(75896),r=n(94892),i=n(28972),s=n(8246),o=n(83140),c=n(80845);function l(e,t,n){var i={markingRequired:[],lowScore:[],highScore:[],completed:[],notCompleted:[]},s=(0,c.Q)(e).length;t.students.forEach((function(t){var o=Object.assign(Object.assign({},t),{summary:g(e,t)});o.summary.awaitingMarking?i.markingRequired.push(o):a.m.last(t.results).attempts.length===s?(i.completed.push(o),o.summary.percentCorrect>=((null==n?void 0:n.HIGH)||r.i.HIGH)&&i.highScore.push(o),o.summary.percentCorrect<((null==n?void 0:n.MODERATE)||r.i.MODERATE)&&i.lowScore.push(o)):i.notCompleted.push(o)}));var o=a.m.sortBy(i.lowScore,(function(e){return e.summary.percentCorrect})),l=a.m.sortBy(i.highScore,(function(e){return-e.summary.percentCorrect}));return Object.assign(Object.assign({},i),{lowScore:o,highScore:l})}function u(e,t){return(0,c.Wn)(e).find((function(e){return e.id.toString()===t.toString()}))}function d(e){return"".concat(e.questionId,":").concat(e.resultId)}function m(e,t,n){var a=(0,c.j_)(t),r=(0,c.f6)(e,a);return(null==r?void 0:r.answers.every((function(e){var t;return(null===(t=n[d(e)])||void 0===t?void 0:t.status)===s.N.Correct})))?s.N.Correct:(null==r?void 0:r.answers.every((function(e){var t;return(null===(t=n[d(e)])||void 0===t?void 0:t.status)===s.N.Incorrect})))?s.N.Incorrect:void 0}function v(e,t){var n=t.students.length,a=0,r=0,s=0,l=0,u=0;return t.students.forEach((function(t){var n=(0,c.j_)(t);if(n){u+=t.results.length;var d=o.A.isInteractionCorrect(e,n);d===i.w.Correct&&a++,d===i.w.UnAnswered&&s++,d===i.w.AwaitingMarking&&l++,d!==i.w.UnAnswered&&r++}})),{percentCorrect:n>0?a/n:0,correct:a,answered:r,unanswered:s,awaitingMarking:l,attempts:u}}function g(e,t){var n=(0,c.j_)(t),a=(0,c.Q)(e),r=a.length,s=0,l=0;a.forEach((function(e){var t=o.A.isInteractionCorrect(e,n);t===i.w.Correct&&s++,t===i.w.AwaitingMarking&&l++}));var u=r>0?s/r:0,d=new Set(a.map((function(e){return e.id}))),m=n.attempts.filter((function(e){var t;return!!d.has(null===(t=null==e?void 0:e.answers[0])||void 0===t?void 0:t.questionId)})).length;return{answered:n.attempts.length,attempts:t.results.length,unanswered:r-m,percentCorrect:u,correct:s,awaitingMarking:l}}},40782:(e,t,n)=>{n.d(t,{I:()=>a,O:()=>c});var a,r=n(32735),i=n(2606),s=n(362);function o(e){var t=r.useCallback((function(t){if(t){var n=t.r.baseVal.value,a=2*Math.PI*n,r=a-e.percentage*a;t.style.strokeDasharray="".concat(a," ").concat(a),t.style.strokeDashoffset=r.toString()}}),[e.percentage]);return r.createElement("svg",null,r.createElement("circle",{r:(0,i.pu)(e.size),className:s.Z.backgroundCircle}),!(0,i.zR)(e.percentage)&&r.createElement("circle",{ref:t,r:(0,i.pu)(e.size),className:(0,i.V4)(e.percentage,e.scoreThresholds)}))}function c(e){var t,n=(0,i.Ki)(e.percentage),c=e.size||(e.layout===a.LabelInside?i.Mk.Large:i.Mk.Small),l=e.customLabel||(0,i.DV)(n);return e.layout===a.LabelOnly?r.createElement("span",{className:(0,i.IA)(n)},l):r.createElement("div",{className:"d-flex align-items-center justify-content-between ".concat(null!==(t=e.className)&&void 0!==t?t:"")},e.layout===a.LabelBefore&&r.createElement("span",{className:"me-2"},l),r.createElement("div",{className:(0,i.tw)(c,n)},r.createElement(o,{percentage:n,size:c,scoreThresholds:e.scoreThresholds}),e.layout===a.LabelInside&&r.createElement("span",{className:s.Z.centredPercentageText},l)))}!function(e){e.CircleOnly="circle_only",e.LabelOnly="label_only",e.LabelBefore="label_before",e.LabelInside="label_inside"}(a||(a={})),c.defaultProps={layout:a.CircleOnly}},2606:(e,t,n)=>{n.d(t,{DV:()=>f,IA:()=>v,Ki:()=>p,Mk:()=>o,V4:()=>m,pu:()=>d,tw:()=>g,zR:()=>h});var a=n(94892),r=n(362);function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function s(e,t,n){return(t=function(e){var t=function(e){if("object"!=i(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=i(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==i(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var o,c=.2,l=.36;!function(e){e.Small="small",e.Large="large",e.ExtraSmall="extraSmall"}(o||(o={}));var u=s(s(s({},o.ExtraSmall,{size:2}),o.Small,{size:2}),o.Large,{size:5.8});function d(e){var t=u[e].size,n=e===o.Large?l:c;return"".concat(t/2-2*n,"rem")}function m(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:a.i;return e>=t.HIGH?r.Z.circleSuccess:e>=t.MODERATE?r.Z.circleWarning:r.Z.circleDanger}function v(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:a.i;return e>=t.HIGH?"text-success":e>=t.MODERATE?"text-warning":"text-danger"}function g(e,t){var n="d-inline-block ".concat(r.Z.circleContainer);return e===o.Large&&(n+=" ".concat(r.Z.lgCircleContainer)),e===o.ExtraSmall&&(n+=" ".concat(r.Z.xsCircleContainer)),h(t)&&(n+=" ".concat(r.Z.pendingCircle)),n}function p(e){if(!h(e))return+e.toFixed(2)}function f(e){return h(e)?"--%":"".concat(Math.round(100*e),"%")}function h(e){return"number"!=typeof e}},94892:(e,t,n)=>{n.d(t,{T:()=>r,i:()=>a});var a={HIGH:.75,MODERATE:.5},r={HIGH:.7,MODERATE:.7}},54405:(e,t,n)=>{n.d(t,{X:()=>a});var a={interactive:function(){return{url:"/mocks/insights/interactive.json",key:"demo:interactive",normalize:!1}},interactiveMetadata:function(){return{url:"/mocks/insights/interactive-metadata.json",key:"demo:interactive:metadata",normalize:!1}},interactiveResults:function(){return{url:"/mocks/insights/interactive-results.json",key:"demo:interactive:results",normalize:!1}},videoViews:function(){return{url:"/mocks/insights/video-views.json",key:"demo:video:views",normalize:!1}},users:function(){return{url:"/mocks/insights/users.json",key:"demo:users",normalize:!1}},individualHeatmap:function(){return{url:"/mocks/insights/individual-heatmap.json",key:"demo:individual:heatmap",normalize:!1}},aggregateHeatmap:function(){return{url:"/mocks/insights/aggregate-heatmap.json",key:"demo:aggregate:heatmap",normalize:!1}}}},93322:(e,t,n)=>{n.d(t,{F:()=>i});var a=n(32735),r=n(13126);function i(){a.useEffect((function(){return r.e.lockContentWidth(),function(){return r.e.unlockContentWidth()}}),[])}},9566:(e,t,n)=>{n.d(t,{G:()=>u,V:()=>m});var a=n(23481),r=n(110),i=n(35223),s=n(14070),o=n(97291),c=n(93975),l=a.T.encloseNamespace("myShares.demoInsights"),u={share:{shareId:"demo-insights",type:c.y.Link},sharedObject:null,shareRecipients:null,dateShared:r.O.subtract(new Date,7,"days").toISOString(),viewCount:23},d={application:o.O.MY_SHARES,action:s.e.MyShares.INTERACTIVE_OVERVIEW_DEMO},m={svgName:i.vn.Analytics,label:l("demoInsights"),appLink:d,group:"insights",className:"btn btn-outline-dark"}},30475:(e,t,n)=>{n.r(t),n.d(t,{InteractiveInsightsOverviewDemoView:()=>_});var a=n(32735),r=n(23481),i=n(2948),s=n(20354),o=n(75896),c=n(26025),l=n(38143),u=n(39151),d=n(54405),m=n(31949),v=n(93322),g=n(79612),p=n(88630),f=n(53936),h=n(54948),y=n(82602),E=n(65853),b=n(91693),S=n(83345),w=n(36532),k=n(49080),I=n(35223),A=n(86099),C=n(24758),M=n(9566),N="insights.shareInfoDemo",O=r.T.encloseNamespace(N);function x(e){var t=e.video&&E.R.getIconAndText({entity:e.video,entityTypeId:e.video.typeId,hasStudentExp:!1,isPasswordProtected:null,linkExpireDate:null,privacy:{privacy:"public",overrideRestrictions:!1},status:k.F.Active,yearGroups:null});return a.createElement("div",{className:"mb-4"},a.createElement("h2",{className:"h4"},a.createElement(S.x,{namespace:N,phrase:"shareInfo"})),a.createElement("div",{className:"d-flex border p-3 rounded-3 align-items-center justify-content-between"},a.createElement("div",{className:"d-flex align-items-center gap-2"},a.createElement(C.A,{shareRecipients:null,imageCdnUrl:e.imageCdnUrl,hasShareLink:!0,maxAvatars:4,shareLinkText:null==t?void 0:t.text}),"·",a.createElement("p",{className:"mb-0"},(0,y.WU)(M.G.dateShared)),"·",a.createElement("p",{className:"mb-0"},a.createElement(S.x,{namespace:N,phrase:"views",options:{count:M.G.viewCount}}))),a.createElement(w.u,{id:"shareButton",title:O("demoOnly"),spanHack:!0},a.createElement(b.h,{appLink:(0,A.YK)(e.video),svgName:I.vn.Share,className:"btn btn-outline-dark pointer-events-none"},a.createElement(S.x,{namespace:N,phrase:"share"})))))}var T=n(10447),R=n(14070),j=n(97291);function D(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=Array(t);n<t;n++)a[n]=e[n];return a}var L=r.T.encloseNamespace("insights.interactiveInsightsOverviewView");function _(){var e,t,n,r,y,E,b,S=(E=(0,i.D)(l.g.ANONYMISE_USERS),b=1,function(e){if(Array.isArray(e))return e}(E)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var a,r,i,s,o=[],c=!0,l=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(a=i.call(n)).done)&&(o.push(a.value),o.length!==t);c=!0);}catch(e){l=!0,r=e}finally{try{if(!c&&null!=n.return&&(s=n.return(),Object(s)!==s))return}finally{if(l)throw r}}return o}}(E,b)||function(e,t){if(e){if("string"==typeof e)return D(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?D(e,t):void 0}}(E,b)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())[0];(0,v.F)();var w=s.a.useBasicFetch(m.N.currentUser()),k=s.a.useBasicFetch(u.L.config()),I=s.a.useBasicFetch(d.X.interactiveMetadata()),A=s.a.useBasicFetch(d.X.interactive()),C=c.B.getAudienceAppLinkParams(),M=c.B.getDateRangeAppLinkParams(),N=s.a.useBasicFetch(d.X.interactiveResults()),O=1===(null===(e=C.classrooms)||void 0===e?void 0:e.length)&&!(null===(t=C.classroomGroups)||void 0===t?void 0:t.length),_=s.a.useBasicFetch(O&&p.F.getClassroomStudents(o.m.first(C.classrooms))),H=s.a.useBasicFetch(d.X.aggregateHeatmap()),V=s.a.useBasicFetch(d.X.videoViews());(0,g.M)({title:I.data?L("pageTitle",{video:null===(n=I.data)||void 0===n?void 0:n.name}):null});var z=w.data&&k.data&&I.data&&A.data&&N.data&&(!O||_.data)&&H.data&&!!V.data,U=Object.assign(Object.assign({},C),M),B=function(e,t){return{resultsAppLink:{application:j.O.MY_SHARES,action:R.e.MyShares.INTERACTIVE_STUDENTS_DEMO,args:[""],params:t},questionsAppLink:{application:j.O.MY_SHARES,action:R.e.MyShares.INTERACTIVE_QUESTIONS_DEMO,args:[""],params:t},heatmapAppLink:{application:j.O.MY_SHARES,action:R.e.MyShares.INTERACTIVE_HEATMAP_DEMO,args:[""],params:t}}}(0,U);return a.createElement("div",{className:"px-3"},a.createElement(f.j,{video:I.data,tabs:(0,T.aq)(null===(r=I.data)||void 0===r?void 0:r.id,"insights",U),dateRangeAppLinkParams:M,isDemo:!0}),a.createElement(x,{video:I.data,imageCdnUrl:null===(y=k.data)||void 0===y?void 0:y.imageCdnUrl}),a.createElement(h.m,{aggregateEngagement:H.data,interactive:A.data,interactiveMetadata:I.data,classroomStudents:_.data,results:N.data,videoViews:V.data,config:k.data,interactiveInsightsAppLinks:B,classroomFilterOnly:!1,anonymiseUsers:S,params:U,hasDataLoaded:z,hasShared:!0}))}},362:(e,t,n)=>{n.d(t,{Z:()=>a});const a={circleContainer:"p8Vgz",backgroundCircle:"asGGE",circleSuccess:"PXLNj",circleWarning:"ZckRN",circleDanger:"slBRg",lgCircleContainer:"N8KCI",xsCircleContainer:"RPqZ2",pendingCircle:"DKrcq",centredPercentageText:"tpmLR"}}}]);
2
+ //# sourceMappingURL=3878-45fd0861cc-lite.chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts/3878-45fd0861cc-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/engagement-heat-map.scss","file:///app/packages/libs/shared/src/apps/analytics/components/engagement-heat-map/EngagementHeatMap.tsx","file:///app/packages/libs/shared/src/apps/analytics/utils/AnonymiseUserUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/EngagementUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/utils/InteractiveUtils.ts","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicator.tsx","file:///app/packages/libs/shared/src/components/percentage-indicator/PercentageIndicatorUtils.ts","file:///app/packages/libs/shared/src/constants/ScoreThresholds.ts","file:///app/packages/libs/shared/src/flight-requests/InsightsDemoRequests.ts","file:///app/packages/libs/shared/src/hooks/useLockContentWidth.ts","file:///app/packages/projects/lite/src/apps/my-shares/constants/MySharesDemoInsights.ts","file:///app/packages/projects/lite/src/apps/my-shares/components/share-info/ShareInfoDemo.tsx","file:///app/packages/projects/lite/src/apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoView.tsx","file:///app/packages/projects/lite/src/apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoUtils.ts","file:///app/packages/libs/shared/src/components/percentage-indicator/percentage-indicator.scss"],"sourcesContent":["// extracted by mini-css-extract-plugin\nexport default {\"heatMap\":\"epapa\",\"legend\":\"uhH4p\"};","import React from 'react';\nimport chroma from 'chroma-js';\n\nimport { getFullHeatMap } from 'libs/shared/apps/analytics/utils/EngagementUtils';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Engagement } from 'libs/shared/interfaces';\n\nimport styles from './engagement-heat-map.scss';\n\nconst namespace = 'shared.engagementHeatMap';\n\nconst ZERO_COLOUR = '#f1f1f1';\nconst MIN_COLOUR = '#daf07d';\nconst MAX_COLOUR = '#08bd1a';\n\nconst COLOUR_SCALE = chroma.scale([ MIN_COLOUR, MAX_COLOUR ]);\n\nconst LEGEND_VALUES = [ 0, 0.01, 0.25, 0.5, 0.75, 1 ];\n\nfunction getBackgroundColor(value: number, max: number): string {\n if (!value)\n return ZERO_COLOUR;\n\n return COLOUR_SCALE(value / max).hex();\n}\n\nfunction getGradient(data: number[], max: number): string {\n const gradient: string[] = [];\n\n for (let i = 0; i < data.length; i++) {\n const previousValue = i > 0 && data[i - 1];\n const currentValue = data[i];\n const nextValue = i < data.length - 1 && data[i + 1];\n\n /**\n * We want to capture colour changes but if a value has the same value\n * of both of its neighbours, we can skip it.\n */\n if (currentValue === previousValue && currentValue === nextValue)\n continue;\n\n gradient.push(`${getBackgroundColor(currentValue, max)} ${100 / data.length * i}%`);\n }\n\n return `linear-gradient(to right, ${gradient.join(',')})`;\n}\n\nexport function EngagementHeatMapLegend(): JSX.Element {\n const max = Math.max(...LEGEND_VALUES);\n const legendSquareWidthPercentage = 100 / LEGEND_VALUES.length;\n\n return (\n <div className='d-flex justify-content-between w-100'>\n <Text namespace={namespace} phrase='less' />\n <div className={`d-flex mx-1 flex-grow-1 ${styles.legend}`}>\n {LEGEND_VALUES.map((val, idx) => (\n <div\n key={idx}\n style={{\n width: `${legendSquareWidthPercentage}%`,\n backgroundColor: getBackgroundColor(val, max)\n }}\n />\n ))}\n </div>\n <Text namespace={namespace} phrase='more' />\n </div>\n );\n}\n\ninterface EngagementHeatMapProps {\n engagement: Engagement;\n max?: number;\n className?: string;\n}\n\nexport function EngagementHeatMap(props: EngagementHeatMapProps): JSX.Element {\n const heatMap = getFullHeatMap(props.engagement);\n const max = props.max ?? Math.max(...heatMap);\n\n return (\n <div\n className={`border rounded ${styles.heatMap} ${props.className ?? ''}`}\n style={{\n background: getGradient(heatMap, max)\n }}\n />\n );\n}","import { animals, colors, Config as UniqueNamesConfig, uniqueNamesGenerator } from 'unique-names-generator';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnonSession, AnonSessions } from 'libs/shared/apps/analytics/hooks/UseAnonSessions';\nimport { UserOrAnonSession } from 'libs/shared/apps/analytics/interfaces/UserOrAnonSession';\nimport { StudentResults } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nconst namespace = 'shared.analyticsUtils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getUniqueNamesConfig(id: string): UniqueNamesConfig {\n /**\n * Generate a seed that is unique to each user but changes every 5 minutes.\n * \n * We use a seed so that if the same user's name is anonymised multiple times\n * in quick succession (e.g. multiple renders), the same name will be returned each time.\n * \n * We change the seed every 5 minutes so that students don't always have the same name.\n */\n const seed = +`${id}${Math.floor((new Date()).getMinutes() / 5)}`;\n\n return {\n dictionaries: [ colors, animals ],\n separator: ' ',\n length: 2,\n style: 'capital',\n seed\n };\n}\n\nexport function anonymiseUserName(user: UserOrAnonSession, shouldAnonymise: boolean): string {\n if (!user)\n return '';\n\n if (!shouldAnonymise)\n return 'sessionId' in user ? user.sessionName : UserHelper.getFullName(user);\n\n return uniqueNamesGenerator(getUniqueNamesConfig('sessionId' in user ? user.sessionName : user.id));\n}\n\nexport function getAnonSession(sessionId: string, anonSessions: AnonSessions): AnonSession {\n const fallback = {\n sessionId: sessionId,\n sessionName: getPhrase('anonymousUser')\n };\n\n if (!sessionId || !anonSessions)\n return fallback;\n\n const anonSession = anonSessions[sessionId];\n\n if (anonSession)\n return anonSession;\n\n return fallback;\n}\n\nexport function getUserOrAnonSession(result: StudentResults, anonSessions: AnonSessions): UserOrAnonSession {\n if (result.user)\n return result.user;\n\n return getAnonSession(result.sessionId, anonSessions);\n}\n","import { Engagement } from 'libs/shared/interfaces';\n\n/**\n * The heat map in the API response won't contain trailing zeros so we need to add those\n * in manually.\n */\nexport function getFullHeatMap(engagement: Engagement): number[] {\n return (new Array(Math.ceil(engagement.videoDuration))).fill(null).map((t, idx) => engagement.heatMap[idx] || 0);\n}","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { ResultsSummary } from 'libs/shared/apps/analytics/interfaces/ResultsSummary';\nimport { StudentResultsWithSummary } from 'libs/shared/apps/analytics/interfaces/StudentResultsWithSummary';\nimport { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { Interactive, InteractiveResultSet } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { flattenInteractions, getInteractions, getStudentAttempt, getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\ninterface StudentGroups {\n markingRequired: StudentResultsWithSummary[];\n lowScore: StudentResultsWithSummary[];\n highScore: StudentResultsWithSummary[];\n completed: StudentResultsWithSummary[];\n notCompleted: StudentResultsWithSummary[];\n}\n\nexport function groupStudents(\n interactive: Interactive,\n results: InteractiveResultSet,\n scoreThreshold?: ScoreThresholds\n): StudentGroups {\n const groups: StudentGroups = {\n markingRequired: [],\n lowScore: [],\n highScore: [],\n completed: [],\n notCompleted: []\n };\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n \n results.students.forEach(s => {\n const withSummary = {\n ...s,\n summary: getStudentResultsSummary(interactive, s)\n };\n \n if (withSummary.summary.awaitingMarking) {\n groups.markingRequired.push(withSummary);\n return;\n }\n\n if (ArrayHelper.last(s.results).attempts.length === numInteractions) {\n groups.completed.push(withSummary);\n } else {\n groups.notCompleted.push(withSummary);\n return;\n }\n \n if (withSummary.summary.percentCorrect >= (scoreThreshold?.HIGH || ScoreThresholdDefaults.HIGH))\n groups.highScore.push(withSummary);\n \n if (withSummary.summary.percentCorrect < (scoreThreshold?.MODERATE || ScoreThresholdDefaults.MODERATE))\n groups.lowScore.push(withSummary);\n });\n \n const sortedLowScore = ArrayHelper.sortBy(groups.lowScore, s => s.summary.percentCorrect);\n const sortedHighScore = ArrayHelper.sortBy(groups.highScore, s => -s.summary.percentCorrect);\n \n return {\n ...groups,\n lowScore: sortedLowScore,\n highScore: sortedHighScore\n };\n}\n\nexport function getInteractionById(interactive: Interactive, interactionId: string): Interaction {\n const flattenedInteractions = flattenInteractions(interactive);\n return flattenedInteractions.find(i => i.id.toString() === interactionId.toString());\n}\n\n/**\n * We need to use the question and result ids as a list of one student's responses\n * to multiple questions will all have the same result id and a list of multiple\n * students responses to one question will all have the same questionId.\n */\nexport function getMarkedAnswerId(answer: StudentAnswer): string {\n return `${answer.questionId}:${answer.resultId}`;\n}\n\nexport function getMarkedStatus(\n interactionId: string,\n studentResults: StudentResults,\n markedAnswers: MarkedAnswerHash\n): InteractiveAnswerStatus {\n const result = getStudentResult(studentResults);\n const studentResponse = getStudentAttempt(interactionId, result);\n\n const isMarkedCorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Correct;\n });\n\n if (isMarkedCorrect)\n return InteractiveAnswerStatus.Correct;\n\n const isMarkedIncorrect = studentResponse?.answers.every(a => {\n return markedAnswers[getMarkedAnswerId(a)]?.status === InteractiveAnswerStatus.Incorrect;\n });\n\n if (isMarkedIncorrect)\n return InteractiveAnswerStatus.Incorrect;\n}\n\nexport function getInteractionResultsSummary(\n interaction: Interaction,\n results: InteractiveResultSet\n): ResultsSummary {\n const numStudents = results.students.length;\n let numCorrect = 0;\n let answered = 0;\n let unanswered = 0;\n let awaitingMarking = 0;\n let attempts = 0;\n\n results.students.forEach(s => {\n const result = getStudentResult(s);\n\n if (!result)\n return;\n\n attempts = attempts + s.results.length;\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(interaction, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.UnAnswered)\n unanswered++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n\n if (correctness !== InteractionCorrectness.UnAnswered)\n answered++;\n });\n\n\n const percentCorrect = numStudents > 0\n ? numCorrect / numStudents\n : 0;\n\n return {\n percentCorrect,\n correct: numCorrect,\n answered,\n unanswered,\n awaitingMarking,\n attempts\n };\n}\n\nexport function getStudentResultsSummary(interactive: Interactive, studentResults: StudentResults): ResultsSummary {\n const result = getStudentResult(studentResults);\n\n const interactions = getInteractions(interactive);\n\n const numInteractions = interactions.length;\n\n let numCorrect = 0;\n let awaitingMarking = 0;\n\n interactions.forEach(i => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(i, result);\n\n if (correctness === InteractionCorrectness.Correct)\n numCorrect++;\n\n if (correctness === InteractionCorrectness.AwaitingMarking)\n awaitingMarking++;\n });\n\n const percentCorrect = numInteractions > 0 ? numCorrect / numInteractions : 0;\n\n /**\n * Our interactions list has images and annotations filtered out.\n * We built a map of valid questions, so that we can calculate the unswered accurately.\n * We're doing this because of a bug that caused annotations and images to record answers in the player.\n * - Sha\n */\n const interactionIds = new Set(interactions.map(i => i.id));\n const answeredInteractions = result.attempts.filter(a => !!interactionIds.has(a?.answers[0]?.questionId)).length;\n\n return {\n answered: result.attempts.length,\n attempts: studentResults.results.length,\n unanswered: numInteractions - answeredInteractions,\n percentCorrect,\n correct: numCorrect,\n awaitingMarking\n };\n}","import React from 'react';\n\nimport { ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport {\n getCircleClassName,\n getCircleContainerClassName,\n getCircleRadius,\n getColouredLabelClassName,\n getFormattedPercentage,\n getPercentageToFixed,\n isPending,\n ProgressCircleSize\n} from './PercentageIndicatorUtils';\n\nimport styles from './percentage-indicator.scss';\n\ninterface ProgressCircleProps {\n size: ProgressCircleSize;\n scoreThresholds?: ScoreThresholds;\n percentage?: number;\n}\n\nfunction ProgressCircle(props: ProgressCircleProps): JSX.Element {\n const ref = React.useCallback((circle: SVGCircleElement) => {\n if (!circle)\n return;\n\n const radius = circle.r.baseVal.value;\n const circumference = 2 * Math.PI * radius;\n const offset = circumference - props.percentage * circumference;\n\n circle.style.strokeDasharray = `${circumference} ${circumference}`;\n circle.style.strokeDashoffset = offset.toString();\n }, [props.percentage]);\n\n return (\n <svg>\n <circle r={getCircleRadius(props.size)} className={styles.backgroundCircle} />\n {!isPending(props.percentage) &&\n <circle\n ref={ref}\n r={getCircleRadius(props.size)}\n className={getCircleClassName(props.percentage, props.scoreThresholds)}\n />\n }\n </svg>\n );\n}\n\nexport enum PercentageIndicatorLayout {\n CircleOnly = 'circle_only',\n LabelOnly = 'label_only',\n LabelBefore = 'label_before',\n LabelInside = 'label_inside'\n}\n\ninterface PercentageIndicatorProps {\n layout: PercentageIndicatorLayout;\n percentage?: number; // Between 0 and 1 or undefined for pending\n className?: string;\n customLabel?: string;\n scoreThresholds?: ScoreThresholds;\n size?: ProgressCircleSize;\n}\n\nPercentageIndicator.defaultProps = {\n layout: PercentageIndicatorLayout.CircleOnly\n};\n\nexport function PercentageIndicator(props: PercentageIndicatorProps): JSX.Element {\n const percentageToFixed = getPercentageToFixed(props.percentage);\n\n const size = props.size ||\n (props.layout === PercentageIndicatorLayout.LabelInside\n ? ProgressCircleSize.Large\n : ProgressCircleSize.Small\n );\n\n const label = props.customLabel || getFormattedPercentage(percentageToFixed);\n\n if (props.layout === PercentageIndicatorLayout.LabelOnly)\n return (\n <span className={getColouredLabelClassName(percentageToFixed)}>\n {label}\n </span>\n );\n\n return (\n <div className={`d-flex align-items-center justify-content-between ${props.className ?? ''}`}>\n {props.layout === PercentageIndicatorLayout.LabelBefore &&\n <span className='me-2'>\n {label}\n </span>\n }\n <div className={getCircleContainerClassName(size, percentageToFixed)}>\n <ProgressCircle percentage={percentageToFixed} size={size} scoreThresholds={props.scoreThresholds} />\n {props.layout === PercentageIndicatorLayout.LabelInside &&\n <span className={styles.centredPercentageText}>\n {label}\n </span>\n }\n </div>\n </div>\n );\n}","import { ScoreThresholdDefaults, ScoreThresholds } from 'libs/shared/constants/ScoreThresholds';\n\nimport styles from './percentage-indicator.scss';\n\n/**\n * Values for width and strokeWidth are taken from progress-circle.scss.\n * If either are changed, they must be updated in both places.\n */\nconst CIRCLE_WIDTH = 2; // rem\nconst CIRCLE_WIDTH_LG = 5.8; // rem\nconst CIRCLE_STROKE_WIDTH = 0.2; // rem\nconst CIRCLE_STROKE_WIDTH_LG = 0.36; // rem\n \nexport enum ProgressCircleSize {\n Small = 'small',\n Large = 'large',\n ExtraSmall = 'extraSmall'\n}\n\nconst ProgressCircleSizeMap = {\n [ProgressCircleSize.ExtraSmall]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Small]: {\n size: CIRCLE_WIDTH\n },\n [ProgressCircleSize.Large]: {\n size: CIRCLE_WIDTH_LG\n }\n};\n\n/**\n * radius = width / 2 - strokeWidth * 2\n */\nexport function getCircleRadius(size: ProgressCircleSize): string {\n const width = ProgressCircleSizeMap[size].size;\n const strokeWidth = size === ProgressCircleSize.Large ? CIRCLE_STROKE_WIDTH_LG : CIRCLE_STROKE_WIDTH;\n return `${width / 2 - strokeWidth * 2}rem`;\n}\n \nexport function getCircleClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return styles.circleSuccess;\n \n if (percentage >= scoreThresholds.MODERATE)\n return styles.circleWarning;\n \n return styles.circleDanger;\n}\n \nexport function getColouredLabelClassName(\n percentage: number,\n scoreThresholds: ScoreThresholds = ScoreThresholdDefaults\n): string {\n if (percentage >= scoreThresholds.HIGH)\n return 'text-success';\n \n if (percentage >= scoreThresholds.MODERATE)\n return 'text-warning';\n \n return 'text-danger';\n}\n \nexport function getCircleContainerClassName(size: ProgressCircleSize, percentage?: number): string {\n let className = `d-inline-block ${styles.circleContainer}`;\n \n if (size === ProgressCircleSize.Large)\n className += ` ${styles.lgCircleContainer}`;\n\n if (size === ProgressCircleSize.ExtraSmall)\n className += ` ${styles.xsCircleContainer}`;\n\n if (isPending(percentage))\n className += ` ${styles.pendingCircle}`;\n \n return className;\n}\n\nexport function getPercentageToFixed(percentage?: number): number | undefined {\n if (isPending(percentage))\n return;\n \n return +percentage.toFixed(2);\n}\n \nexport function getFormattedPercentage(percentage?: number): string {\n if (isPending(percentage))\n return `--%`;\n\n return `${Math.round(percentage * 100)}%`;\n}\n\nexport function isPending(percentage?: number): boolean {\n return typeof percentage !== 'number';\n}","export interface ScoreThresholds {\n HIGH: number;\n MODERATE: number;\n}\n\nexport const ScoreThresholdDefaults: ScoreThresholds = {\n HIGH: 0.75,\n MODERATE: 0.5\n};\n\nexport const ScoreThresholdInsights: ScoreThresholds = {\n HIGH: 0.7,\n MODERATE: 0.7\n};","import { Flight } from 'libs/common/react/index';\n\nexport const InsightsDemoRequests = {\n interactive(): Flight.Request {\n return {\n url: `/mocks/insights/interactive.json`,\n key: `demo:interactive`,\n normalize: false\n };\n },\n\n interactiveMetadata(): Flight.Request {\n return {\n url: `/mocks/insights/interactive-metadata.json`,\n key: `demo:interactive:metadata`,\n normalize: false\n };\n },\n\n interactiveResults(): Flight.Request {\n return {\n url: `/mocks/insights/interactive-results.json`,\n key: `demo:interactive:results`,\n normalize: false\n };\n },\n\n videoViews(): Flight.Request {\n return {\n url: `/mocks/insights/video-views.json`,\n key: `demo:video:views`,\n normalize: false\n };\n },\n\n users(): Flight.Request {\n return {\n url: `/mocks/insights/users.json`,\n key: `demo:users`,\n normalize: false\n };\n },\n\n individualHeatmap(): Flight.Request {\n return {\n url: `/mocks/insights/individual-heatmap.json`,\n key: `demo:individual:heatmap`,\n normalize: false\n };\n },\n\n aggregateHeatmap(): Flight.Request {\n return {\n url: `/mocks/insights/aggregate-heatmap.json`,\n key: `demo:aggregate:heatmap`,\n normalize: false\n };\n }\n};","import 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 { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nimport { MySharesTableData } from 'apps/my-shares/components/my-shares-table/MySharesTableUtils';\nimport { ShareType } from 'apps/share-v2/enums/ShareType';\nimport { ShareLink } from 'apps/share-v2/interfaces/ShareLink';\n\nconst namespace = 'myShares.demoInsights';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst DEMO_INSIGHT_DAYS_AGO = 7;\n\nexport const DEMO_INSIGHTS_SHARE: MySharesTableData = {\n share: {\n shareId: 'demo-insights',\n type: ShareType.Link\n } as ShareLink,\n sharedObject: null,\n shareRecipients: null,\n dateShared: DateHelper.subtract(new Date(), DEMO_INSIGHT_DAYS_AGO, 'days').toISOString(),\n viewCount: 23\n};\n\nconst DEMO_INSIGHTS_APPLINK: Core.AppLink = {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_OVERVIEW_DEMO\n};\n\nexport const DEMO_INSIGHTS_ACTION: ActionOptions = {\n svgName: cvSvgLibrary.Analytics,\n label: getPhrase('demoInsights'),\n appLink: DEMO_INSIGHTS_APPLINK,\n group: 'insights',\n className: 'btn btn-outline-dark'\n};\n","import React from 'react';\nimport { format as formatDate } from 'timeago.js';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { ShareLinkHelper } from 'libs/shared/apps/share/utils/ShareLinkHelper';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { ShareLinkStatus } from 'libs/shared/enums/ShareLinkStatus';\nimport { VideoTypes } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport { getShareAppLink } from 'shared/utils/ObjectAppLinkHelper';\n\nimport { SharedToPill } from 'apps/my-shares/components/shared-to-pill/SharedToPill';\nimport { DEMO_INSIGHTS_SHARE } from 'apps/my-shares/constants/MySharesDemoInsights';\n\nconst namespace = 'insights.shareInfoDemo';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ShareInfoDemoProps {\n video: VideoTypes;\n imageCdnUrl: string;\n}\n\nexport function ShareInfoDemo(props: ShareInfoDemoProps) {\n const shareLinkText = props.video &&\n ShareLinkHelper.getIconAndText({\n entity: props.video,\n entityTypeId: props.video.typeId,\n hasStudentExp: false,\n isPasswordProtected: null,\n linkExpireDate: null,\n privacy: {\n privacy: 'public',\n overrideRestrictions: false\n },\n status: ShareLinkStatus.Active,\n yearGroups: null\n });\n\n return (\n <div className='mb-4'>\n <h2 className='h4'><Text namespace={namespace} phrase='shareInfo' /></h2>\n\n <div className='d-flex border p-3 rounded-3 align-items-center justify-content-between'>\n <div className='d-flex align-items-center gap-2'>\n <SharedToPill\n shareRecipients={null}\n imageCdnUrl={props.imageCdnUrl}\n hasShareLink={true}\n maxAvatars={4}\n shareLinkText={shareLinkText?.text}\n />\n ·\n <p className='mb-0'>{formatDate(DEMO_INSIGHTS_SHARE.dateShared)}</p>\n ·\n <p className='mb-0'><Text namespace={namespace} phrase='views' options={{ count: DEMO_INSIGHTS_SHARE.viewCount }} /></p>\n </div>\n <Tooltip id='shareButton' title={getPhrase('demoOnly')} spanHack>\n <IconButton\n appLink={getShareAppLink(props.video)}\n svgName={cvSvgLibrary.Share}\n className='btn btn-outline-dark pointer-events-none'\n >\n <Text namespace={namespace} phrase='share' />\n </IconButton>\n </Tooltip>\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { BaseAnalyticsEventResponse } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { AnalyticsFilterHelper } from 'libs/shared/apps/analytics/utils/AnalyticsFilterUtils';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { InsightsDemoRequests } from 'libs/shared/flight-requests/InsightsDemoRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useLockContentWidth } from 'libs/shared/hooks/useLockContentWidth';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { BasePaginatedCollection, Config, CurrentUser, Engagement, Interactive, InteractiveMetadata, InteractiveResultSet, User } from 'libs/shared/interfaces';\n\nimport { ClassroomRequests } from 'apps/classrooms/flight-requests/ClassroomRequests';\nimport { InsightsHeader } from 'apps/my-shares/components/insights-header/InsightsHeader';\nimport { InteractiveInsightsOverview } from 'apps/my-shares/components/interactive-insights-overview/InteractiveInsightsOverview';\nimport { ShareInfoDemo } from 'apps/my-shares/components/share-info/ShareInfoDemo';\nimport { getInsightsDemoInteractiveTabs } from 'apps/my-shares/utils/InsightsAppLinkUtils';\nimport { getInteractiveInsightsAppLinks } from 'apps/my-shares/views/demo/overview/InteractiveInsightsOverviewDemoUtils';\n\nconst namespace = 'insights.interactiveInsightsOverviewView';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function InteractiveInsightsOverviewDemoView() {\n const [anonymiseUsers] = useViewModel<boolean>(SharedViewModelKeys.ANONYMISE_USERS);\n\n useLockContentWidth();\n\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n const interactiveMetadata = Flight.useBasicFetch<InteractiveMetadata>(\n InsightsDemoRequests.interactiveMetadata()\n );\n\n const interactive = Flight.useBasicFetch<Interactive>(InsightsDemoRequests.interactive());\n\n const audienceAppLinkParams = AnalyticsFilterHelper.getAudienceAppLinkParams();\n const dateRangeAppLinkParams = AnalyticsFilterHelper.getDateRangeAppLinkParams();\n\n const results = Flight.useBasicFetch<InteractiveResultSet>(InsightsDemoRequests.interactiveResults());\n\n const classroomFilterOnly =\n audienceAppLinkParams.classrooms?.length === 1 && !audienceAppLinkParams.classroomGroups?.length;\n const classroomStudents = Flight.useBasicFetch<BasePaginatedCollection<User>>(classroomFilterOnly &&\n ClassroomRequests.getClassroomStudents(ArrayHelper.first(audienceAppLinkParams.classrooms)));\n\n const aggregateEngagement = Flight.useBasicFetch<Engagement>(\n InsightsDemoRequests.aggregateHeatmap()\n );\n\n const videoViews = Flight.useBasicFetch<BaseAnalyticsEventResponse>(\n InsightsDemoRequests.videoViews()\n );\n\n useSetPageMetadata({ title: interactiveMetadata.data ? getPhrase('pageTitle', { video: interactiveMetadata.data?.name }) : null });\n\n const hasDataLoaded =\n currentUser.data &&\n config.data &&\n interactiveMetadata.data &&\n interactive.data &&\n results.data &&\n (!classroomFilterOnly || classroomStudents.data) &&\n aggregateEngagement.data &&\n !!videoViews.data;\n\n const params = {\n ...audienceAppLinkParams,\n ...dateRangeAppLinkParams\n };\n const interactiveInsightsAppLinks = getInteractiveInsightsAppLinks(\n '',\n params\n );\n\n return (\n <div className='px-3'>\n <InsightsHeader\n video={interactiveMetadata.data}\n tabs={getInsightsDemoInteractiveTabs(interactiveMetadata.data?.id, 'insights', params)}\n dateRangeAppLinkParams={dateRangeAppLinkParams}\n isDemo\n />\n\n <ShareInfoDemo video={interactiveMetadata.data} imageCdnUrl={config.data?.imageCdnUrl} />\n\n <InteractiveInsightsOverview\n aggregateEngagement={aggregateEngagement.data}\n interactive={interactive.data}\n interactiveMetadata={interactiveMetadata.data}\n classroomStudents={classroomStudents.data}\n results={results.data}\n videoViews={videoViews.data}\n config={config.data}\n interactiveInsightsAppLinks={interactiveInsightsAppLinks}\n classroomFilterOnly={false}\n anonymiseUsers={anonymiseUsers}\n params={params}\n hasDataLoaded={hasDataLoaded}\n hasShared={true}\n />\n </div>\n );\n}","import { HashObject } from 'libs/common/react/interfaces';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nexport function getInteractiveInsightsAppLinks(id: string, params?: HashObject) {\n return {\n resultsAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_STUDENTS_DEMO,\n args: [id],\n params\n },\n questionsAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_QUESTIONS_DEMO,\n args: [id],\n params\n },\n heatmapAppLink: {\n application: AppChannels.MY_SHARES,\n action: Actions.MyShares.INTERACTIVE_HEATMAP_DEMO,\n args: [id],\n params\n }\n };\n}","// extracted by mini-css-extract-plugin\nexport default {\"circleContainer\":\"p8Vgz\",\"backgroundCircle\":\"asGGE\",\"circleSuccess\":\"PXLNj\",\"circleWarning\":\"ZckRN\",\"circleDanger\":\"slBRg\",\"lgCircleContainer\":\"N8KCI\",\"xsCircleContainer\":\"RPqZ2\",\"pendingCircle\":\"DKrcq\",\"centredPercentageText\":\"tpmLR\"};"],"names":["namespace","ZERO_COLOUR","COLOUR_SCALE","LEGEND_VALUES","getBackgroundColor","value","max","hex","getGradient","data","gradient","i","length","previousValue","currentValue","nextValue","push","join","EngagementHeatMapLegend","Math","legendSquareWidthPercentage","className","Text","phrase","map","val","idx","key","style","width","backgroundColor","EngagementHeatMap","props","heatMap","engagement","background","getPhrase","anonymiseUserName","user","shouldAnonymise","id","sessionName","seed","floor","Date","getMinutes","dictionaries","separator","getAnonSession","sessionId","anonSessions","fallback","getUserOrAnonSession","result","getFullHeatMap","Array","ceil","videoDuration","fill","t","groupStudents","interactive","results","scoreThreshold","groups","markingRequired","lowScore","highScore","completed","notCompleted","numInteractions","students","forEach","s","withSummary","summary","getStudentResultsSummary","awaitingMarking","attempts","percentCorrect","HIGH","MODERATE","sortedLowScore","sortedHighScore","getInteractionById","interactionId","find","toString","getMarkedAnswerId","answer","questionId","resultId","getMarkedStatus","studentResults","markedAnswers","studentResponse","answers","every","a","status","getInteractionResultsSummary","interaction","numStudents","numCorrect","answered","unanswered","correctness","correct","interactions","interactionIds","Set","answeredInteractions","filter","has","PercentageIndicatorLayout","ProgressCircle","ref","circle","radius","r","baseVal","circumference","PI","offset","percentage","strokeDasharray","strokeDashoffset","size","scoreThresholds","PercentageIndicator","percentageToFixed","layout","LabelInside","label","customLabel","LabelOnly","LabelBefore","defaultProps","CircleOnly","ProgressCircleSize","CIRCLE_STROKE_WIDTH","CIRCLE_STROKE_WIDTH_LG","ProgressCircleSizeMap","ExtraSmall","Small","Large","getCircleRadius","strokeWidth","getCircleClassName","getColouredLabelClassName","getCircleContainerClassName","isPending","getPercentageToFixed","toFixed","getFormattedPercentage","round","ScoreThresholdDefaults","ScoreThresholdInsights","InsightsDemoRequests","url","normalize","interactiveMetadata","interactiveResults","videoViews","users","individualHeatmap","aggregateHeatmap","useLockContentWidth","DEMO_INSIGHTS_SHARE","share","shareId","type","sharedObject","shareRecipients","dateShared","toISOString","viewCount","DEMO_INSIGHTS_APPLINK","application","action","DEMO_INSIGHTS_ACTION","svgName","appLink","group","LanguageService","ShareInfoDemo","shareLinkText","video","ShareLinkHelper","entity","entityTypeId","typeId","hasStudentExp","isPasswordProtected","linkExpireDate","privacy","overrideRestrictions","ShareLinkStatus","yearGroups","SharedToPill","imageCdnUrl","hasShareLink","maxAvatars","text","options","count","Tooltip","title","spanHack","IconButton","InteractiveInsightsOverviewDemoView","anonymiseUsers","SharedViewModelKeys","currentUser","UserRequests","config","ConfigRequests","audienceAppLinkParams","dateRangeAppLinkParams","classroomFilterOnly","classrooms","classroomGroups","classroomStudents","ClassroomRequests","ArrayHelper","aggregateEngagement","useSetPageMetadata","name","hasDataLoaded","params","interactiveInsightsAppLinks","resultsAppLink","args","questionsAppLink","heatmapAppLink","getInteractiveInsightsAppLinks","InsightsHeader","tabs","isDemo","InteractiveInsightsOverview","hasShared"],"sourceRoot":""}
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunk_clickview_lite=self.webpackChunk_clickview_lite||[]).push([[4096],{49863:(e,t,n)=>{n.d(t,{m9:()=>b,Ad:()=>E,Kh:()=>k});var r=n(32735),a=n(23481),s=n(75896),i=n(97408),l=n(18995),c=n(12528),o=n(83914),u=n(36532),m=n(4594),d=n(36511),p=n(35223),g=n(64818);const v={avatarContainer:"ByxQa",sm:"EgJ0v",sharedAvatar:"cW0NT"};var f=a.T.encloseNamespace("reportsShare.sharedToAvatarList");function h(e){var t=s.m.countBy(e,"typeId"),n=t[m.E.User],r=t[m.E.Classroom],a=t[m.E.ClassroomGroup];return n&&r&&a?f("classroomsGroupsAndUsers",{userCount:n,classroomCount:r,groupCount:a}):n&&r?f("classroomsAndUsers",{userCount:n,classroomCount:r}):n&&a?f("groupsAndUsers",{userCount:n,groupCount:a}):r&&a?f("classroomsAndGroups",{classroomCount:r,groupCount:a}):n?f("users",{userCount:n}):r?f("classrooms",{classroomCount:r}):a?f("groups",{groupCount:a}):void 0}function y(e){var t,n,a,s,l,f=(null===(t=e.item)||void 0===t?void 0:t.typeId)===m.E.User&&e.item,h=(null===(n=e.item)||void 0===n?void 0:n.typeId)===m.E.Classroom&&e.item,y=(null===(a=e.item)||void 0===a?void 0:a.typeId)===m.E.ClassroomGroup&&e.item,b="d-flex justify-content-center align-items-center text-white rounded-circle h-100 w-100";return r.createElement(r.Fragment,null,!!f&&r.createElement(u.u,{title:"".concat(f.name," ").concat(f.surname),spanHack:!0,spanHackClassName:"h-100 w-100"},r.createElement(i.q,{imageUrl:null===(s=f.avatar)||void 0===s?void 0:s.url,imageCdnUrl:e.imageCdnUrl,initials:g.l.getInitials(f.name,f.surname),extraClasses:v.sharedAvatar})),!!h&&r.createElement(u.u,{title:h.name,spanHack:!0,spanHackClassName:"h-100 w-100"},r.createElement("div",{className:b},r.createElement(c.f,{svgName:p.vn.Classrooms,svgSize:o.S.Large,variant:"teal"}))),!!y&&r.createElement(u.u,{title:y.name,spanHack:!0,spanHackClassName:"h-100 w-100"},r.createElement("div",{className:b},r.createElement(c.f,{svgName:p.vn.Group,variant:(0,d.I)(null===(l=y.metadata)||void 0===l?void 0:l.colour)}))))}function b(e){return r.createElement("div",{className:"".concat(v.avatarContainer," ").concat("sm"===e.avatarSize?v.sm:"")},r.createElement(u.u,{title:f("anonymous"),spanHack:!0,spanHackClassName:"bg-light text-dark d-flex justify-content-center align-items-center rounded-circle h-100 w-100"},r.createElement(o.x,{svgName:p.vn.Anonymous,size:"sm"===e.avatarSize?o.S.Small:null})))}function E(e){return r.createElement("div",{className:"".concat(v.avatarContainer," ").concat("sm"===e.avatarSize?v.sm:"")},r.createElement(u.u,{title:e.text||f("sharedLink"),spanHack:!0,spanHackClassName:"bg-light text-dark d-flex justify-content-center align-items-center rounded-circle h-100 w-100 ".concat(e.className||"")},r.createElement(o.x,{svgName:p.vn.Link,size:"sm"===e.avatarSize?o.S.Small:null})))}function k(e){return r.createElement(l.e,Object.assign({},e,{items:e.recipients,avatarItem:y,avatarContainerClassname:"".concat(v.avatarContainer," ").concat("sm"===e.avatarSize?v.sm:""),getHiddenTooltip:h,hasShareLink:e.hasShareLink,shareLinkText:e.shareLinkText}))}k.defaultProps={maxAvatars:5}},65853:(e,t,n)=>{n.d(t,{R:()=>d});var r=n(23481),a=n(110),s=n(4594),i=n(49080),l=n(26361),c=n(35223),o=n(31908);function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var m=r.T.encloseNamespace("share.shareLinkInfo"),d={getPrivateIconAndText:function(e){var t=e.entityTypeId,n=e.privacy,r=e.hasStudentExp,a=e.entity,i=e.yearGroups;if(t===s.E.Topic||t===s.E.Series)return{icon:c.vn.VisibleOn,text:m(r?"justMySchoolTeachers":"justMySchoolDescription")};if(!Array.isArray(n))switch(n.privacy){case"public":return{icon:c.vn.VisibleOn,text:m("publicDescription")};case"protected":return n.overrideRestrictions?{icon:c.vn.VisibleOn,text:m("clickViewOnly")}:{icon:c.vn.Lock,text:d.getRespectRatingText(a,i,r)};case"just_my_customer":return n.overrideRestrictions?{icon:c.vn.Lock,text:m(r?"justMySchoolTeachers":"justMySchoolDescription")}:{icon:c.vn.Lock,text:d.getRespectRatingText(a,i,r)};case"restricted":case"private":return{icon:c.vn.Lock,text:m("privateDescription")};default:return{}}},getIconAndText:function(e){var t=e.linkExpireDate,n=e.isPasswordProtected,r=e.status;if(!t&&!n)return d.getPrivateIconAndText(e);if(!t)return{icon:c.vn.Lock,text:m("password")};var s=a.O.isToday(t),l=a.O.diffBetween(t,new Date,"day");if(!n){var o=s?m("expiryToday"):m("expiry",{days:l});return r===i.F.Expired&&(o=m("expired")),{icon:c.vn.Timer,text:o}}var u=s?m("passwordExpiryToday"):m("passwordExpiry",{days:l});return r===i.F.Expired&&(u=m("passwordExpired")),{icon:c.vn.Lock,text:u}},getRespectRatingText:function(e,t,n){var r;if(!e||!t)return null;if(n)return m("justMySchoolTeachers");if(!o.M.isVideoType(e))return m("collectionRating");var a=l.l.getWeightedRestriction(null===(r=e._restrictions)||void 0===r?void 0:r.value);if(a&&!a.yearGroup)return m("onlyAdmins");var s,i,c,d=o.M.getRating(e),p=function(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return u(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?u(e,t):void 0}}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0,a=function(){};return{s:a,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s,i=!0,l=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return i=e.done,e},e:function(e){l=!0,s=e},f:function(){try{i||null==n.return||n.return()}finally{if(l)throw s}}}}(t);try{for(p.s();!(c=p.n()).done;){var g=c.value;(!s||g.value>s.value)&&(s=g),a&&g.value<=a.yearGroup||d&&g.rating.value<d.value||(!i||g.value<i.value)&&(i=g)}}catch(e){p.e(e)}finally{p.f()}return i?1===t.length?m("clickViewOnly"):i.value===s.value?m("maxYearGroup",{yearGroup:s.name}):m("yearGroupRange",{yearGroup:i.name}):m("onlyStaff")}}},18995:(e,t,n)=>{n.d(t,{e:()=>c});var r=n(32735),a=n(23481),s=n(49863),i=n(36532),l=a.T.encloseNamespace("shared.avatarList");function c(e){var t=e.items.length>e.maxAvatars?e.items.slice(0,e.maxAvatars-1):e.items,n=e.items.length>t.length?e.items.slice(e.maxAvatars-1):[],a=e.avatarItem,c=n.length,o="sm"===e.avatarSize?4:8;function u(t){return{transform:"translateX(".concat((e.hasShareLink?t+1:t)*-o,"px)"),zIndex:e.maxAvatars-t}}return 0===t.length&&0===n.length?r.createElement(r.Fragment,null):r.createElement("div",{className:"d-flex",style:{marginRight:"-".concat((t.length-1+(n.length?1:0)+(e.hasShareLink?1:0))*o,"px")}},e.hasShareLink&&r.createElement("div",{style:{zIndex:e.maxAvatars+1}},r.createElement(s.Ad,{text:e.shareLinkText,avatarSize:e.avatarSize,className:"bg-dark text-white"})),t.map((function(t,n){return r.createElement("div",{className:"".concat(e.avatarContainerClassname||""),key:t.id,style:u(n)},r.createElement(a,{item:t,imageCdnUrl:e.imageCdnUrl,index:n,maxAvatars:e.maxAvatars}))})),!!n.length&&r.createElement("div",{className:"".concat(e.avatarContainerClassname||""," bg-white rounded-circle"),style:{transform:"translateX(".concat(t.length*-o,"px)"),zIndex:e.maxAvatars-t.length}},r.createElement(i.u,{title:e.getHiddenTooltip?e.getHiddenTooltip(n):e.roleToDisplay?l("staff"===e.roleToDisplay?"staff":"student",{count:c,smartCount:c}):l("users",{count:c,smartCount:c}),spanHack:!0,spanHackClassName:"h-100 w-100"},r.createElement("div",{className:"d-flex justify-content-center align-items-center border border-dark rounded-circle h-100 w-100 ".concat(e.numberClassname||"")},"+".concat(n.length)))))}c.defaultProps={maxAvatars:5}},28972:(e,t,n)=>{var r;n.d(t,{w:()=>r}),function(e){e[e.Correct=0]="Correct",e[e.Incorrect=1]="Incorrect",e[e.AwaitingMarking=2]="AwaitingMarking",e[e.Answered=3]="Answered",e[e.UnAnswered=4]="UnAnswered",e[e.NotApplicable=5]="NotApplicable"}(r||(r={}))},8246:(e,t,n)=>{var r;n.d(t,{N:()=>r}),function(e){e[e.Incorrect=0]="Incorrect",e[e.Correct=1]="Correct",e[e.PendingReview=2]="PendingReview"}(r||(r={}))},36511:(e,t,n)=>{n.d(t,{I:()=>a});var r=n(38129);function a(e){switch(e){case r.R.Pink:return"pink";case r.R.Orange:return"orange";case r.R.Green:return"green";case r.R.Blue:return"blue";case r.R.Purple:return"purple";case r.R.Indigo:return"indigo";default:return"pink"}}},83140:(e,t,n)=>{n.d(t,{A:()=>v});var r=n(28972),a=n(8246),s=n(38129);function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}function l(e,t,n){return(t=function(e){var t=function(e){if("object"!=i(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=i(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==i(t)?t:t+""}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(){return r.w.NotApplicable}function o(e,t){var n=e.actionableItems.filter((function(e){return e.isCorrect}));return n.every((function(e){return!t(e.id)}))?r.w.UnAnswered:n.every((function(e){var n;return e.name.trim().toLowerCase()===(null===(n=t(e.id))||void 0===n?void 0:n.trim().toLowerCase())}))?r.w.Correct:r.w.Incorrect}function u(e,t){return e.actionableItems.every((function(e){return!t(e.id)}))?r.w.UnAnswered:e.actionableItems.filter((function(e){return e.isCorrect})).every((function(e){var n,r=t(e.id);return(null==r?void 0:r.toString())===(null===(n=e.id)||void 0===n?void 0:n.toString())||r===e.name}))?r.w.Correct:r.w.Incorrect}function m(e,t){return function(n){var r=t.attempts.find((function(t){return t.id===e.id}));return null==r?void 0:r.answers.find((function(e){return e.id===n}))}}function d(e,t){var n=m(e,t);return u(e,(function(e){var t=n(e);return null==t?void 0:t.text}))}function p(e,t){return function(e,t){var n;return e.actionableItems.forEach((function(e){var s=t(e.id);n=s?s.status!==a.N.Correct?s.status!==a.N.Incorrect?r.w.AwaitingMarking:r.w.Incorrect:r.w.Correct:r.w.UnAnswered})),n}(e,m(e,t))}var g=l(l(l(l(l(l(l({},s.Z9.Annotation,c),s.Z9.Image,c),s.Z9.MissingWord,(function(e,t){var n=m(e,t);return o(e,(function(e){var t=n(e);return null==t?void 0:t.text}))})),s.Z9.MultipleChoice,d),s.Z9.ShortAnswer,p),s.Z9.TrueOrFalse,d),s.Z9.Illustration,p),v={notApplicable:c,awaitingMarking:function(){return r.w.AwaitingMarking},isMissingWordCorrect:o,isMultipleChoiceCorrect:u,isInteractionCorrect:function(e,t){return(0,g[e.typeId])(e,t)}}},80845:(e,t,n)=>{n.d(t,{Q:()=>o,Wn:()=>i,f6:()=>c,j_:()=>l});var r=n(75896),a=n(38129);function s(e){return e.typeId!==a.Z9.Annotation&&e.typeId!==a.Z9.Image}function i(e){return r.m.flatten(e.timepoints.map((function(e){return e.interactions})))}function l(e){return r.m.last(e.results)}function c(e,t){return r.m.findWhere(null==t?void 0:t.attempts,{id:e})}function o(e){return i(e).filter(s)}},54948:(e,t,n)=>{n.d(t,{m:()=>ce});var r=n(32735),a=n(23481),s=n(84621),i=n(21976),l=n(70072),c=n(83345),o=n(35223);const u={tealChart:"lZZf0",grayChart:"wJQc4"};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){return function(e){if(Array.isArray(e))return g(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||p(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(e,t){if(e){if("string"==typeof e)return g(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?g(e,t):void 0}}function g(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var v="shared.insightAverageAttempts",f=a.T.encloseNamespace(v);function h(e){var t,n,a=function(){var t=e.students.reduce((function(e,t){var n,r,a,s=t.summary.attempts.toString();return s in e||Object.assign(e,(n={},a=0,(r=function(e){var t=function(e){if("object"!=m(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.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+""}(r=s))in n?Object.defineProperty(n,r,{value:a,enumerable:!0,configurable:!0,writable:!0}):n[r]=a,n)),e[s]++,e}),{});return Object.keys(t).length?t:{0:0}}(),g=Math.max.apply(Math,d(Object.keys(a).map((function(e){return a[e]})))),h=Object.keys(a).reduce((function(e,t){return a[t]===g?[].concat(d(e),[t]):e}),[]),y=(t=0===a[0],{categories:Object.keys(a),series:[{type:"column",color:a[0]?"#EAEAEA":"#40C2BB",borderRadius:4,dataLabels:{enabled:!t,style:l.d,inside:!1,overflow:"allow",crop:!1},data:Object.keys(a).map((function(e){var n=0!==g&&a[e]===g;return{className:"".concat(t?u.grayChart:u.tealChart," ").concat(a[e]!==g&&0!==a[e]?"opacity-25":""),borderWidth:n?2:0,borderColor:n?"black":"",y:a[e]}}))}]});return r.createElement(s.L,{title:f("title"),svgName:o.vn.Refresh,svgClassName:"bg-light-purple text-purple"},r.createElement("p",null,h.length?r.createElement(c.x,{namespace:v,phrase:"averageAttempts",options:{smartCount:(n=Object.entries(a).reduce((function(e,t){var n,r,a=(r=2,function(e){if(Array.isArray(e))return e}(n=t)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,s,i,l=[],c=!0,o=!1;try{if(s=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=s.call(n)).done)&&(l.push(r.value),l.length!==t);c=!0);}catch(e){o=!0,a=e}finally{try{if(!c&&null!=n.return&&(i=n.return(),Object(i)!==i))return}finally{if(o)throw a}}return l}}(n,r)||p(n,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],i=a[1];return e.totalAttempts+=+s*i,e.totalUsers+=i,e}),{totalAttempts:0,totalUsers:0}),0===n.totalUsers?0:Math.round(n.totalAttempts/n.totalUsers*100)/100)}}):r.createElement(c.x,{namespace:v,phrase:"noAttempts"})),r.createElement("div",{className:"mt-auto"},r.createElement(i.x,{label:f("attempts"),chartData:y})))}var y=n(75896);const b={redChart:"G7zOw",yellowChart:"k34mm",greenChart:"vBneA",blueChart:"RPTWm",grayChart:"k4JFZ",borderDark:"LWor3"};var E="shared.insightAverageScore",k=a.T.encloseNamespace(E);function A(e){return r.createElement(s.L,{title:k("title"),svgName:o.vn.Analytics,svgClassName:"bg-light-orange text-orange"},r.createElement("p",null,e.students.length?r.createElement(c.x,{namespace:E,phrase:"averageScore",options:(l=e.students.map((function(e){return e.summary.percentCorrect})),u=l.reduce((function(e,t){return e+t}),0)/l.length,m=y.m.last(y.m.last(e.students).results).attempts.length,{averageScore:Math.round(m*u),totalQuestions:m,averagePercentage:(100*u).toFixed(1)})}):r.createElement(c.x,{namespace:E,phrase:"noAnswers"})),r.createElement(i.x,{label:"".concat(k("studentScores")," (%)"),chartData:(t=Array(11).fill(0),n=e.students.reduce((function(e,t){return e[Math.floor(10*t.summary.percentCorrect)]++,e}),t),a=["0","10","20","30","40","50","60","70","80","90","100"],{categories:a,series:[{type:"column",color:"#4E9ACE",borderRadius:4,data:n.map((function(e,t){var n=Number(a[t]);return{className:"".concat(function(e,t){return 0===t?b.grayChart:e<50?b.redChart:e<70?b.yellowChart:e<90?b.greenChart:b.blueChart}(n,e)),y:e}}))}]})}));var t,n,a,l,u,m}var C=n(98551),S=n(26136),N=a.T.encloseNamespace("shared.insightCompletedStudents");function w(e){return r.createElement(s.L,{title:N("title"),svgName:o.vn.Flag,svgClassName:"bg-light-indigo text-indigo",count:e.students.length},r.createElement(C.y,{students:e.students.map((function(t){return Object.assign(Object.assign({},(0,S.DV)(t,e.anonSessions)),{percentage:t.summary.percentCorrect})})),imageCdnUrl:e.imageCdnUrl,imageUrl:e.imageUrl,description:N("completedStudents"),appLink:e.resultsAppLink,appLinkText:N("viewAll"),anonymiseUsers:e.anonymiseUsers}))}var x=n(51870),L=n(39157),I=n(15611),U=n(86572),j=n(40782),O=n(80845),T="shared.insightEasiestQuestion",M=a.T.encloseNamespace(T);function R(e){var t,n=r.useMemo((function(){return t=e.interactive,n=e.results,r=(0,O.Q)(t).map((function(e){return Object.assign(Object.assign({},e),{resultsSummary:(0,L.nq)(e,n)})})).filter((function(e){return!!e.resultsSummary.answered&&!e.resultsSummary.awaitingMarking})),a=y.m.sortBy(r,(function(e){return e.resultsSummary.percentCorrect})),y.m.last(a);var t,n,r,a}),[e.results.students.length]);return r.createElement(s.L,{title:M("title"),svgName:o.vn.StarOutline,svgClassName:"bg-light-blue text-blue"},r.createElement("div",{className:"d-flex align-items-center"},r.createElement(j.O,{percentage:null===(t=null==n?void 0:n.resultsSummary)||void 0===t?void 0:t.percentCorrect,layout:j.I.LabelInside}),n?r.createElement("div",{className:"d-flex ms-2"},r.createElement(U.y,{interaction:n,iconClassName:"flex-shrink-0"})):r.createElement("span",{className:"ms-2"},M("noAnswers"))),n&&r.createElement(I.F,{appLink:Object.assign(Object.assign({},e.questionsAppLink),{params:Object.assign(Object.assign({},e.questionsAppLink.params),{sortBy:"score_desc"})}),className:"text-info"},r.createElement(c.x,{namespace:T,phrase:"viewQuestions"})))}var q="shared.insightHardestQuestion",H=a.T.encloseNamespace(q);function P(e){var t,n=r.useMemo((function(){return t=e.interactive,n=e.results,r=(0,O.Q)(t).map((function(e){return Object.assign(Object.assign({},e),{resultsSummary:(0,L.nq)(e,n)})})).filter((function(e){return!!e.resultsSummary.answered&&!e.resultsSummary.awaitingMarking})),a=y.m.sortBy(r,(function(e){return e.resultsSummary.percentCorrect})),y.m.first(a);var t,n,r,a}),[e.results.students.length]);return r.createElement(s.L,{title:H("title"),svgName:o.vn.QuestionMark,svgClassName:"bg-light-orange text-orange"},r.createElement("div",{className:"d-flex align-items-center"},r.createElement(j.O,{percentage:null===(t=null==n?void 0:n.resultsSummary)||void 0===t?void 0:t.percentCorrect,layout:j.I.LabelInside}),n?r.createElement("div",{className:"d-flex ms-2"},r.createElement(U.y,{interaction:n,iconClassName:"flex-shrink-0"})):r.createElement("span",{className:"ms-2"},H("noAnswers"))),n&&r.createElement(I.F,{appLink:Object.assign(Object.assign({},e.questionsAppLink),{params:Object.assign(Object.assign({},e.questionsAppLink.params),{sortBy:"score_asc"})}),className:"text-info"},r.createElement(c.x,{namespace:q,phrase:"viewQuestions"})))}var D=n(50916),_=a.T.encloseNamespace("shared.insightHighScoringStudents");function B(e){return r.createElement(s.L,{title:_("title"),svgName:o.vn.Trophy,svgClassName:"bg-light-teal text-teal",count:e.students.length},r.createElement(C.y,{students:e.students.map((function(t){return Object.assign(Object.assign({},(0,S.DV)(t,e.anonSessions)),{percentage:t.summary.percentCorrect})})),imageCdnUrl:e.imageCdnUrl,imageUrl:e.greenChartImageUrl,description:_(e.completed.length?"noStudents":"highScore"),appLink:Object.assign(Object.assign({},e.resultsAppLink),{params:Object.assign(Object.assign({},e.resultsAppLink.params),{sortBy:"score_desc"})}),appLinkText:_("viewByHighest"),anonymiseUsers:e.anonymiseUsers}))}var z=a.T.encloseNamespace("shared.insightLowScoringStudents");function W(e){return r.createElement(s.L,{title:z("title"),svgName:o.vn.Hand,svgClassName:"bg-light-red text-red",count:e.students.length},r.createElement(C.y,{students:e.students.map((function(t){return Object.assign(Object.assign({},(0,S.DV)(t,e.anonSessions)),{percentage:t.summary.percentCorrect})})),imageCdnUrl:e.imageCdnUrl,imageUrl:e.completed.length?e.heartImageUrl:e.redChartImageUrl,description:z(e.completed.length?"doingWell":"lowScore"),appLink:Object.assign(Object.assign({},e.resultsAppLink),{params:Object.assign(Object.assign({},e.resultsAppLink.params),{sortBy:"score_asc"})}),appLinkText:z("viewByLowest"),anonymiseUsers:e.anonymiseUsers}))}var G=a.T.encloseNamespace("shared.insightMarkingRequired");function V(e){return r.createElement(s.L,{title:G("title"),svgName:o.vn.Hand,svgClassName:"bg-light-blue text-blue",count:e.students.length},r.createElement(C.y,{students:e.students,imageCdnUrl:e.imageCdnUrl,imageUrl:e.imageUrl,description:G("studentsRequireMarking"),appLink:Object.assign(Object.assign({},e.resultsAppLink),{params:{filterBy:"marking_required"}}),appLinkText:G("viewAll"),anonymiseUsers:e.anonymiseUsers}))}function Z(e){return function(e){if(Array.isArray(e))return F(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return F(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?F(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function F(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var Q=a.T.encloseNamespace("shared.insightNotCompletedStudents");function $(e){var t,n,a,i=(t=e.markingRequiredStudents.map((function(e){return null==e?void 0:e.user.id})),n=e.completedStudents.map((function(e){return null==e?void 0:e.user.id})),a=e.classroomStudents.filter((function(e){return!t.includes(e.id)&&!n.includes(e.id)})),y.m.uniq([].concat(Z(e.notCompletedStudents.map((function(e){return e.user}))),Z(a)),"id"));return r.createElement(s.L,{title:Q("title"),svgName:o.vn.Puzzle,svgClassName:"bg-light-teal text-teal",count:i.length},r.createElement(C.y,{students:i,imageCdnUrl:e.imageCdnUrl,imageUrl:e.imageUrl,description:Q("completed"),appLink:Object.assign(Object.assign({},e.resultsAppLink),{params:"not_completed"}),appLinkText:Q("viewAll"),anonymiseUsers:e.anonymiseUsers}))}var J=n(94892),K=n(37802),X=n(99742),Y=n(91693),ee=n(38279),te="lite.insightsMask";function ne(e){return r.createElement("div",{className:"".concat(e.requiresMarking&&ee.Z.mask," position-relative")},r.createElement("div",{className:e.requiresMarking?"position-absolute top-0":""},e.children),r.createElement("div",{className:e.requiresMarking?"".concat(ee.Z.backdrop," d-flex flex-column align-items-center justify-content-start py-5"):""},!!e.requiresMarking&&r.createElement("div",{className:"text-center w-50"},r.createElement("img",{src:X.W.Insights.MARKING_RESPONSES,className:"mb-3",width:288}),r.createElement("h2",{className:"h3 mb-3"},r.createElement(c.x,{namespace:te,phrase:"markHeading"})),r.createElement("p",{className:"mb-3"},r.createElement(c.x,{namespace:te,phrase:"markDescription"})),r.createElement(Y.h,{svgName:o.vn.Check,className:"btn btn-dark mb-3",appLink:Object.assign(Object.assign({},e.appLink),{params:Object.assign(Object.assign({},e.appLink.params),{filterBy:"marking_required"})})},r.createElement(c.x,{namespace:te,phrase:"markResponses",options:{smartCount:e.requiresMarking}})),r.createElement("button",{className:"btn btn-link d-block p-0 mx-auto",onClick:e.hideMarkingRequiredMask},r.createElement(c.x,{namespace:te,phrase:"seeIncomplete"})))))}var re=n(53214);const ae={partialInsights:"pG0Jh"};function se(){return r.createElement("div",null,r.createElement("h2",{className:"h4 w-25 partial-loading-background"}," "),r.createElement("div",{className:"row g-3 mb-5"},r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")})),r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")}))),r.createElement("h2",{className:"h4 w-25 partial-loading-background"}," "),r.createElement("div",{className:"row g-3 mb-5"},r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")})),r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")})),r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")})),r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")}))),r.createElement("h2",{className:"h4 w-25 partial-loading-background"}," "),r.createElement("div",{className:"row g-3 mb-5"},r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")})),r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")})),r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")})),r.createElement("div",{className:"col-6"},r.createElement("div",{className:"".concat(ae.partialInsights," rounded partial-loading-background")}))))}function ie(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}var le="insights.interactiveInsightsOverview";function ce(e){var t,n,a,s,i=(a=r.useState(!1),s=2,function(e){if(Array.isArray(e))return e}(a)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,a,s,i,l=[],c=!0,o=!1;try{if(s=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=s.call(n)).done)&&(l.push(r.value),l.length!==t);c=!0);}catch(e){o=!0,a=e}finally{try{if(!c&&null!=n.return&&(i=n.return(),Object(i)!==i))return}finally{if(o)throw a}}return l}}(a,s)||function(e,t){if(e){if("string"==typeof e)return ie(e,t);var n={}.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?ie(e,t):void 0}}(a,s)||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.")}()),l=i[0],o=i[1],u=(0,K.r)(null).hasShareFlowV2,m=e.hasDataLoaded&&(0,L.R6)(e.interactive,e.results,J.T);return r.createElement(r.Fragment,null,!e.hasDataLoaded&&r.createElement(se,null),e.hasDataLoaded&&r.createElement(re.u,{video:e.interactiveMetadata,hasShared:e.hasShared,hasShareFlowV2:u,shareId:e.shareId},r.createElement("section",{className:"mb-5"},r.createElement("h2",{className:"h4"},r.createElement(c.x,{namespace:le,phrase:"studentResponses"}),r.createElement("span",null,": ",e.results.students.length,e.classroomStudents?"/".concat(e.classroomStudents.data.length):"")),r.createElement("div",{className:"row g-3"},r.createElement("div",{className:"col"},r.createElement(V,{imageUrl:X.W.Insights.SPEECH_BUBBLE_ASTERISK,resultsAppLink:e.interactiveInsightsAppLinks.resultsAppLink,imageCdnUrl:e.config.imageCdnUrl,students:(n=m.markingRequired,n.map((function(t){return(0,S.DV)(t,e.anonSessions)}))),anonymiseUsers:e.anonymiseUsers})),e.classroomFilterOnly&&r.createElement("div",{className:"col"},r.createElement($,{markingRequiredStudents:m.markingRequired,completedStudents:m.completed,notCompletedStudents:m.notCompleted,classroomStudents:e.classroomStudents.data,imageCdnUrl:e.config.imageCdnUrl,imageUrl:X.W.Insights.JIGSAW,resultsAppLink:e.interactiveInsightsAppLinks.resultsAppLink,anonymiseUsers:e.anonymiseUsers})),r.createElement("div",{className:"col"},r.createElement(w,{students:m.completed,imageCdnUrl:e.config.imageCdnUrl,imageUrl:X.W.Insights.AVATAR,resultsAppLink:e.interactiveInsightsAppLinks.resultsAppLink,anonymiseUsers:e.anonymiseUsers,anonSessions:e.anonSessions})))),r.createElement(ne,{requiresMarking:!l&&m.markingRequired.length,appLink:e.interactiveInsightsAppLinks.resultsAppLink,hideMarkingRequiredMask:function(){return o(!0)}},r.createElement("section",{className:"mb-5"},r.createElement("h2",{className:"h4"},r.createElement(c.x,{namespace:le,phrase:"studentsPerformance"})),r.createElement("div",{className:"row g-3"},r.createElement("div",{className:"col-6"},r.createElement(W,{redChartImageUrl:X.W.Insights.RED_CHART,heartImageUrl:X.W.Insights.SPEECH_BUBBLE_HEART,resultsAppLink:e.interactiveInsightsAppLinks.resultsAppLink,imageCdnUrl:e.config.imageCdnUrl,students:m.lowScore,completed:m.completed,anonymiseUsers:e.anonymiseUsers,anonSessions:e.anonSessions})),r.createElement("div",{className:"col-6"},r.createElement(B,{greenChartImageUrl:X.W.Insights.GREEN_CHART,resultsAppLink:e.interactiveInsightsAppLinks.resultsAppLink,imageCdnUrl:e.config.imageCdnUrl,students:m.highScore,completed:m.completed,anonymiseUsers:e.anonymiseUsers,anonSessions:e.anonSessions})),r.createElement("div",{className:"col-6"},r.createElement(P,{interactive:e.interactive,interactiveMetadata:e.interactiveMetadata,results:e.results,questionsAppLink:e.interactiveInsightsAppLinks.questionsAppLink})),r.createElement("div",{className:"col-6"},r.createElement(R,{interactive:e.interactive,interactiveMetadata:e.interactiveMetadata,results:e.results,questionsAppLink:e.interactiveInsightsAppLinks.questionsAppLink})))),r.createElement("section",{className:"mb-5"},r.createElement("h2",{className:"h4"},r.createElement(c.x,{namespace:le,phrase:"classPerformance"})),r.createElement("div",{className:"row g-3"},r.createElement("div",{className:"col-6"},r.createElement(A,{students:m.completed})),r.createElement("div",{className:"col-6"},r.createElement(h,{students:m.completed})),r.createElement("div",{className:"col-6"},r.createElement(x.i,{osCount:null===(t=e.videoViews)||void 0===t?void 0:t.osCount})),r.createElement("div",{className:"col-6"},r.createElement(D.b,{engagement:e.aggregateEngagement,heatmapAppLink:e.interactiveInsightsAppLinks.heatmapAppLink})))))))}},24758:(e,t,n)=>{n.d(t,{A:()=>l});var r=n(32735),a=n(49863),s=n(83345),i="myShares.sharedToPill";function l(e){var t=e.shareRecipients;return r.createElement("div",{className:"d-flex align-items-center bg-gray-100 rounded-pill w-fit gap-2 p-2"},r.createElement("span",{className:"text-nowrap"},r.createElement(s.x,{namespace:i,phrase:t?"sharedTo":"sharedVia"})),!t&&r.createElement(a.Ad,{text:e.shareLinkText,avatarSize:"sm",className:"bg-dark text-white"}),t&&!(null==t?void 0:t.length)&&r.createElement(a.m9,{avatarSize:"sm"}),t&&r.createElement(a.Kh,{recipients:t,imageCdnUrl:e.imageCdnUrl,maxAvatars:e.maxAvatars,avatarSize:"sm",hasShareLink:e.hasShareLink,shareLinkText:e.shareLinkText}))}l.defaultProps={maxAvatars:3}},82602:(e,t,n)=>{n.d(t,{WU:()=>o});var r=["second","minute","hour","day","week","month","year"],a=["秒","分钟","小时","天","周","个月","年"],s={},i=function(e,t){s[e]=t},l=[60,60,24,7,365/7/12,12];function c(e){return e instanceof Date?e:!isNaN(e)||/^\d+$/.test(e)?new Date(parseInt(e)):(e=(e||"").trim().replace(/\.\d+/,"").replace(/-/,"/").replace(/-/,"/").replace(/(\d)T(\d)/,"$1 $2").replace(/Z/," UTC").replace(/([+-]\d\d):?(\d\d)/," $1$2"),new Date(e))}var o=function(e,t,n){var r=function(e,t){return(+(t?c(t):new Date)-+c(e))/1e3}(e,n&&n.relativeDate);return function(e,t){for(var n=e<0?1:0,r=e=Math.abs(e),a=0;e>=l[a]&&a<l.length;a++)e/=l[a];return(e=Math.floor(e))>(0==(a*=2)?9:1)&&(a+=1),t(e,a,r)[n].replace("%s",e.toString())}(r,function(e){return s[e]||s.en_US}(t))};i("en_US",(function(e,t){if(0===t)return["just now","right now"];var n=r[Math.floor(t/2)];return e>1&&(n+="s"),[e+" "+n+" ago","in "+e+" "+n]})),i("zh_CN",(function(e,t){if(0===t)return["刚刚","片刻后"];var n=a[~~(t/2)];return[e+" "+n+"前",e+" "+n+"后"]}))}}]);
2
+ //# sourceMappingURL=4096-c834372efb-lite.chunk.js.map