@clickview/lite 0.73.1 → 0.74.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles.json +2 -2
- package/dist/css/{7122-lite-a094f8fe17.chunk.css → 7122-lite-e0652641e4.chunk.css} +1 -1
- package/dist/css/{4499-lite-c43d17524f.chunk.css → 7150-lite-60d455ba66.chunk.css} +1 -1
- package/dist/css/{lite-app-10d57977f3.css → lite-app-98b3200025.css} +1 -1
- package/dist/languages/en.json +1 -1
- package/dist/scripts/{1362-061cd588c0-lite.chunk.js → 1362-56810ef4c8-lite.chunk.js} +3 -3
- package/dist/scripts/1362-56810ef4c8-lite.chunk.js.map +1 -0
- package/dist/scripts/{1367-12750422b0-lite.chunk.js → 1367-e0481edee3-lite.chunk.js} +2 -2
- package/dist/scripts/1367-e0481edee3-lite.chunk.js.map +1 -0
- package/dist/scripts/{1735-c0f3f1238a-lite.chunk.js → 1735-e4cdbc46ed-lite.chunk.js} +3 -3
- package/dist/scripts/1735-e4cdbc46ed-lite.chunk.js.map +1 -0
- package/dist/scripts/{324-6d6ee95d5d-lite.chunk.js → 324-e7a99b7d52-lite.chunk.js} +2 -2
- package/dist/scripts/{324-6d6ee95d5d-lite.chunk.js.map → 324-e7a99b7d52-lite.chunk.js.map} +1 -1
- package/dist/scripts/{3252-22fac3da15-lite.chunk.js → 3252-50b5c19f19-lite.chunk.js} +1 -1
- package/dist/scripts/{3252-22fac3da15-lite.chunk.js.map → 3252-50b5c19f19-lite.chunk.js.map} +1 -1
- package/dist/scripts/3677-4904f30c6a-lite.chunk.js +2 -0
- package/dist/scripts/3677-4904f30c6a-lite.chunk.js.map +1 -0
- package/dist/scripts/{3781-7a9ddc7736-lite.chunk.js → 3781-e092f92668-lite.chunk.js} +2 -2
- package/dist/scripts/{3781-7a9ddc7736-lite.chunk.js.map → 3781-e092f92668-lite.chunk.js.map} +1 -1
- package/dist/scripts/{3823-e38a508a3c-lite.chunk.js → 3823-0dc1972eb2-lite.chunk.js} +2 -2
- package/dist/scripts/3823-0dc1972eb2-lite.chunk.js.map +1 -0
- package/dist/scripts/3915-abd9a65a08-lite.chunk.js +2 -0
- package/dist/scripts/3915-abd9a65a08-lite.chunk.js.map +1 -0
- package/dist/scripts/{3978-09fb1f250e-lite.chunk.js → 3978-a551dd2648-lite.chunk.js} +2 -2
- package/dist/scripts/3978-a551dd2648-lite.chunk.js.map +1 -0
- package/dist/scripts/{4013-d31272b42a-lite.chunk.js → 4013-6f68d7031e-lite.chunk.js} +1 -1
- package/dist/scripts/{4013-d31272b42a-lite.chunk.js.map → 4013-6f68d7031e-lite.chunk.js.map} +1 -1
- package/dist/scripts/{4014-4225ce1eb6-lite.chunk.js → 4014-3eccce2f89-lite.chunk.js} +3 -3
- package/dist/scripts/4014-3eccce2f89-lite.chunk.js.map +1 -0
- package/dist/scripts/{4050-cf35c4ec45-lite.chunk.js → 4050-ffe5b6ae6d-lite.chunk.js} +2 -2
- package/dist/scripts/{4050-cf35c4ec45-lite.chunk.js.map → 4050-ffe5b6ae6d-lite.chunk.js.map} +1 -1
- package/dist/scripts/{4061-525ef00f69-lite.chunk.js → 4061-100002abf6-lite.chunk.js} +2 -2
- package/dist/scripts/4061-100002abf6-lite.chunk.js.map +1 -0
- package/dist/scripts/4191-9a08c4b205-lite.chunk.js +2 -0
- package/dist/scripts/4191-9a08c4b205-lite.chunk.js.map +1 -0
- package/dist/scripts/{4358-b21c24f96a-lite.chunk.js → 4358-a1bbca8249-lite.chunk.js} +1 -1
- package/dist/scripts/{4358-b21c24f96a-lite.chunk.js.map → 4358-a1bbca8249-lite.chunk.js.map} +1 -1
- package/dist/scripts/{4400-8c36fb4ab5-lite.chunk.js → 4400-755a158a52-lite.chunk.js} +2 -2
- package/dist/scripts/4400-755a158a52-lite.chunk.js.map +1 -0
- package/dist/scripts/4806-13c9302b2c-lite.chunk.js +2 -0
- package/dist/scripts/4806-13c9302b2c-lite.chunk.js.map +1 -0
- package/dist/scripts/{5135-864055ab0b-lite.chunk.js → 5135-166ec46620-lite.chunk.js} +2 -2
- package/dist/scripts/5135-166ec46620-lite.chunk.js.map +1 -0
- package/dist/scripts/{5143-286c66de2b-lite.chunk.js → 5143-d6c4a357ea-lite.chunk.js} +2 -2
- package/dist/scripts/5143-d6c4a357ea-lite.chunk.js.map +1 -0
- package/dist/scripts/{5743-a764171a6d-lite.chunk.js → 5743-14700e4f76-lite.chunk.js} +2 -2
- package/dist/scripts/5743-14700e4f76-lite.chunk.js.map +1 -0
- package/dist/scripts/{6030-5db8cc1bc4-lite.chunk.js → 6030-c2e07df714-lite.chunk.js} +2 -2
- package/dist/scripts/6030-c2e07df714-lite.chunk.js.map +1 -0
- package/dist/scripts/{618-4334f9451b-lite.chunk.js → 618-996d8b560b-lite.chunk.js} +2 -2
- package/dist/scripts/618-996d8b560b-lite.chunk.js.map +1 -0
- package/dist/scripts/{6207-f444184025-lite.chunk.js → 6207-be843186e0-lite.chunk.js} +1 -1
- package/dist/scripts/{6207-f444184025-lite.chunk.js.map → 6207-be843186e0-lite.chunk.js.map} +1 -1
- package/dist/scripts/{6413-c4333e80d4-lite.chunk.js → 6413-caaae6a383-lite.chunk.js} +3 -3
- package/dist/scripts/{6413-c4333e80d4-lite.chunk.js.map → 6413-caaae6a383-lite.chunk.js.map} +1 -1
- package/dist/scripts/{6646-24a34f7d99-lite.chunk.js → 6646-c5775f6553-lite.chunk.js} +3 -3
- package/dist/scripts/6646-c5775f6553-lite.chunk.js.map +1 -0
- package/dist/scripts/{6909-8a45942b63-lite.chunk.js → 6909-6805b6a0d9-lite.chunk.js} +2 -2
- package/dist/scripts/6909-6805b6a0d9-lite.chunk.js.map +1 -0
- package/dist/scripts/7064-b3bafc599f-lite.chunk.js +2 -0
- package/dist/scripts/7064-b3bafc599f-lite.chunk.js.map +1 -0
- package/dist/scripts/7122-dbf374af58-lite.chunk.js +2 -0
- package/dist/scripts/7122-dbf374af58-lite.chunk.js.map +1 -0
- package/dist/scripts/7150-93a205975c-lite.chunk.js +2 -0
- package/dist/scripts/7150-93a205975c-lite.chunk.js.map +1 -0
- package/dist/scripts/{7234-85d4acaa33-lite.chunk.js → 7234-bcddfe2112-lite.chunk.js} +2 -2
- package/dist/scripts/7234-bcddfe2112-lite.chunk.js.map +1 -0
- package/dist/scripts/{7383-690bc234f1-lite.chunk.js → 7383-02d4956304-lite.chunk.js} +2 -2
- package/dist/scripts/7383-02d4956304-lite.chunk.js.map +1 -0
- package/dist/scripts/{7873-2e64f4eb37-lite.chunk.js → 7873-0ce0523a28-lite.chunk.js} +2 -2
- package/dist/scripts/{7873-2e64f4eb37-lite.chunk.js.map → 7873-0ce0523a28-lite.chunk.js.map} +1 -1
- package/dist/scripts/{8248-050265ed2d-lite.chunk.js → 8248-41dad9bf71-lite.chunk.js} +3 -3
- package/dist/scripts/8248-41dad9bf71-lite.chunk.js.map +1 -0
- package/dist/scripts/8385-6ef08fa319-lite.chunk.js +2 -0
- package/dist/scripts/8385-6ef08fa319-lite.chunk.js.map +1 -0
- package/dist/scripts/{8451-1cb649a3f3-lite.chunk.js → 8451-0103210a8f-lite.chunk.js} +2 -2
- package/dist/scripts/8451-0103210a8f-lite.chunk.js.map +1 -0
- package/dist/scripts/8630-80f676dcda-lite.chunk.js +2 -0
- package/dist/scripts/8630-80f676dcda-lite.chunk.js.map +1 -0
- package/dist/scripts/8891-5118c47b59-lite.chunk.js +2 -0
- package/dist/scripts/8891-5118c47b59-lite.chunk.js.map +1 -0
- package/dist/scripts/8982-b9e53e43ec-lite.chunk.js +2 -0
- package/dist/scripts/8982-b9e53e43ec-lite.chunk.js.map +1 -0
- package/dist/scripts/{9186-daf77d7174-lite.chunk.js → 9186-c1d2615458-lite.chunk.js} +2 -2
- package/dist/scripts/9186-c1d2615458-lite.chunk.js.map +1 -0
- package/dist/scripts/{9241-dbac9cb9f9-lite.chunk.js → 9241-2386134dd3-lite.chunk.js} +2 -2
- package/dist/scripts/9241-2386134dd3-lite.chunk.js.map +1 -0
- package/dist/scripts/{9345-30ccf524c5-lite.chunk.js → 9345-0a7f58bb53-lite.chunk.js} +3 -3
- package/dist/scripts/9345-0a7f58bb53-lite.chunk.js.map +1 -0
- package/dist/scripts/9352-d4b2dc16a8-lite.chunk.js +2 -0
- package/dist/scripts/9352-d4b2dc16a8-lite.chunk.js.map +1 -0
- package/dist/scripts/{9503-275c13891d-lite.chunk.js → 9503-715c46ecc1-lite.chunk.js} +2 -2
- package/dist/scripts/9503-715c46ecc1-lite.chunk.js.map +1 -0
- package/dist/scripts/9630-ca2a850260-lite.chunk.js +2 -0
- package/dist/scripts/9630-ca2a850260-lite.chunk.js.map +1 -0
- package/dist/scripts/{9767-d69fdc31b0-lite.chunk.js → 9767-1b583ceb6c-lite.chunk.js} +2 -2
- package/dist/scripts/9767-1b583ceb6c-lite.chunk.js.map +1 -0
- package/dist/scripts/9894-7c119a8fe3-lite.chunk.js +2 -0
- package/dist/scripts/9894-7c119a8fe3-lite.chunk.js.map +1 -0
- package/dist/scripts/bundle-5b65703152.min.js +3 -0
- package/dist/scripts/{bundle-0075afb6af.min.js.map → bundle-5b65703152.min.js.map} +1 -1
- package/package.json +1 -1
- package/dist/scripts/1362-061cd588c0-lite.chunk.js.map +0 -1
- package/dist/scripts/1367-12750422b0-lite.chunk.js.map +0 -1
- package/dist/scripts/1735-c0f3f1238a-lite.chunk.js.map +0 -1
- package/dist/scripts/3677-20958f59d3-lite.chunk.js +0 -2
- package/dist/scripts/3677-20958f59d3-lite.chunk.js.map +0 -1
- package/dist/scripts/3823-e38a508a3c-lite.chunk.js.map +0 -1
- package/dist/scripts/3915-a1f15d687a-lite.chunk.js +0 -2
- package/dist/scripts/3915-a1f15d687a-lite.chunk.js.map +0 -1
- package/dist/scripts/3978-09fb1f250e-lite.chunk.js.map +0 -1
- package/dist/scripts/4014-4225ce1eb6-lite.chunk.js.map +0 -1
- package/dist/scripts/4061-525ef00f69-lite.chunk.js.map +0 -1
- package/dist/scripts/4191-7612e1713c-lite.chunk.js +0 -2
- package/dist/scripts/4191-7612e1713c-lite.chunk.js.map +0 -1
- package/dist/scripts/4400-8c36fb4ab5-lite.chunk.js.map +0 -1
- package/dist/scripts/4499-1365934bf2-lite.chunk.js +0 -2
- package/dist/scripts/4499-1365934bf2-lite.chunk.js.map +0 -1
- package/dist/scripts/4806-384760d9c9-lite.chunk.js +0 -2
- package/dist/scripts/4806-384760d9c9-lite.chunk.js.map +0 -1
- package/dist/scripts/5135-864055ab0b-lite.chunk.js.map +0 -1
- package/dist/scripts/5143-286c66de2b-lite.chunk.js.map +0 -1
- package/dist/scripts/5743-a764171a6d-lite.chunk.js.map +0 -1
- package/dist/scripts/6030-5db8cc1bc4-lite.chunk.js.map +0 -1
- package/dist/scripts/618-4334f9451b-lite.chunk.js.map +0 -1
- package/dist/scripts/6646-24a34f7d99-lite.chunk.js.map +0 -1
- package/dist/scripts/6909-8a45942b63-lite.chunk.js.map +0 -1
- package/dist/scripts/7064-3ccf1b82d1-lite.chunk.js +0 -2
- package/dist/scripts/7064-3ccf1b82d1-lite.chunk.js.map +0 -1
- package/dist/scripts/7122-352fdd3516-lite.chunk.js +0 -2
- package/dist/scripts/7122-352fdd3516-lite.chunk.js.map +0 -1
- package/dist/scripts/7234-85d4acaa33-lite.chunk.js.map +0 -1
- package/dist/scripts/7383-690bc234f1-lite.chunk.js.map +0 -1
- package/dist/scripts/8248-050265ed2d-lite.chunk.js.map +0 -1
- package/dist/scripts/8385-083e882d77-lite.chunk.js +0 -2
- package/dist/scripts/8385-083e882d77-lite.chunk.js.map +0 -1
- package/dist/scripts/8451-1cb649a3f3-lite.chunk.js.map +0 -1
- package/dist/scripts/8630-0945271ea2-lite.chunk.js +0 -2
- package/dist/scripts/8630-0945271ea2-lite.chunk.js.map +0 -1
- package/dist/scripts/8891-393bb5bdaf-lite.chunk.js +0 -2
- package/dist/scripts/8891-393bb5bdaf-lite.chunk.js.map +0 -1
- package/dist/scripts/8982-8c21fab48a-lite.chunk.js +0 -2
- package/dist/scripts/8982-8c21fab48a-lite.chunk.js.map +0 -1
- package/dist/scripts/9186-daf77d7174-lite.chunk.js.map +0 -1
- package/dist/scripts/9241-dbac9cb9f9-lite.chunk.js.map +0 -1
- package/dist/scripts/9345-30ccf524c5-lite.chunk.js.map +0 -1
- package/dist/scripts/9352-04db4c533d-lite.chunk.js +0 -2
- package/dist/scripts/9352-04db4c533d-lite.chunk.js.map +0 -1
- package/dist/scripts/9503-275c13891d-lite.chunk.js.map +0 -1
- package/dist/scripts/9630-285237c980-lite.chunk.js +0 -2
- package/dist/scripts/9630-285237c980-lite.chunk.js.map +0 -1
- package/dist/scripts/9767-d69fdc31b0-lite.chunk.js.map +0 -1
- package/dist/scripts/9894-10943e41f7-lite.chunk.js +0 -2
- package/dist/scripts/9894-10943e41f7-lite.chunk.js.map +0 -1
- package/dist/scripts/bundle-0075afb6af.min.js +0 -3
- /package/dist/scripts/{1362-061cd588c0-lite.chunk.js.LICENSE.txt → 1362-56810ef4c8-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{1735-c0f3f1238a-lite.chunk.js.LICENSE.txt → 1735-e4cdbc46ed-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{4014-4225ce1eb6-lite.chunk.js.LICENSE.txt → 4014-3eccce2f89-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{4050-cf35c4ec45-lite.chunk.js.LICENSE.txt → 4050-ffe5b6ae6d-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{6413-c4333e80d4-lite.chunk.js.LICENSE.txt → 6413-caaae6a383-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{6646-24a34f7d99-lite.chunk.js.LICENSE.txt → 6646-c5775f6553-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{8248-050265ed2d-lite.chunk.js.LICENSE.txt → 8248-41dad9bf71-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{9345-30ccf524c5-lite.chunk.js.LICENSE.txt → 9345-0a7f58bb53-lite.chunk.js.LICENSE.txt} +0 -0
- /package/dist/scripts/{bundle-0075afb6af.min.js.LICENSE.txt → bundle-5b65703152.min.js.LICENSE.txt} +0 -0
package/dist/scripts/{4358-b21c24f96a-lite.chunk.js.map → 4358-a1bbca8249-lite.chunk.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scripts/4358-b21c24f96a-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/utils/StudentTableUtils.ts","file:///app/packages/libs/shared/src/components/confirmation-popup/ConfirmationPopup.tsx","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/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListFilters.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListHeader.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/submit-marked-answers/SubmitMarkedAnswers.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/interaction-response-list.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseList.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMissingWord.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/question-table-answers.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMultipleChoice.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableShortAnswer.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableTrueOrFalse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/QuestionTableUtils.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummaryUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummary.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/selected-interaction-empty-state/SelectedInteractionEmptyState.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/QuestionTable.tsx","file:///app/packages/projects/lite/src/apps/insights/components/interactive-insights-questions/partial-loading/partial-interactive-insights-questions.scss","file:///app/packages/projects/lite/src/apps/insights/components/interactive-insights-questions/partial-loading/PartialInteractiveInsightsQuestions.tsx","file:///app/packages/projects/lite/src/apps/insights/components/interactive-insights-questions/InteractiveInsightsQuestions.tsx"],"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 { 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}","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 { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'shared.interactionResponseList';\n\nexport type InteractionResponseFilterType = 'marking_required' | 'correct' | 'incorrect' | 'skipped';\n\ninterface InteractionResponseListFiltersEmptyStatesProps {\n filter: InteractionResponseFilterType;\n markingRequiredImageUrl: string;\n correctImageUrl: string;\n incorrectImageUrl: string;\n skippedImageUrl: string;\n}\n\nexport function InteractionResponseListFiltersEmptyStates(props: InteractionResponseListFiltersEmptyStatesProps) {\n function getFilterEmptyStateImageUrl() {\n switch (props.filter) {\n case 'correct': return props.correctImageUrl;\n case 'incorrect': return props.incorrectImageUrl;\n case 'marking_required': return props.markingRequiredImageUrl;\n case 'skipped': return props.skippedImageUrl;\n }\n }\n\n function getFilterEmptyStatePhrase() {\n switch (props.filter) {\n case 'correct': return 'correctEmptyState';\n case 'incorrect': return 'incorrectEmptyState';\n case 'marking_required': return 'markingRequiredEmptyState';\n case 'skipped': return 'skippedEmptyState';\n }\n }\n\n return (\n <>\n <EmptyState className='m-4'>\n <EmptyState.Image src={getFilterEmptyStateImageUrl()} className='w-25 h-auto' />\n <EmptyState.Info>\n <Text namespace={namespace} phrase={getFilterEmptyStatePhrase()} />\n </EmptyState.Info>\n </EmptyState>\n </>\n );\n}\n\ninterface InteractionResponseListFiltersProps {\n filter: InteractionResponseFilterType;\n toggleFilter: (filter: InteractionResponseFilterType) => void\n}\n\nexport function InteractionResponseListFilters(props: InteractionResponseListFiltersProps) {\n function isFilterSelected(filterButton: InteractionResponseFilterType) {\n return filterButton === props.filter;\n }\n\n function getFilterClassName(filterButton: InteractionResponseFilterType) {\n return `rounded-pill bg-light ${isFilterSelected(filterButton) ? 'bg-dark text-white' : ''}`;\n }\n\n return (\n\n <div className='d-flex gap-2 m-3'>\n <button className={getFilterClassName('marking_required')} onClick={() => props.toggleFilter('marking_required')}>\n <Text namespace={namespace} phrase='markingRequired' />\n </button>\n <button className={getFilterClassName('correct')} onClick={() => props.toggleFilter('correct')}>\n <Text namespace={namespace} phrase='correct' />\n </button>\n <button className={getFilterClassName('incorrect')} onClick={() => props.toggleFilter('incorrect')}>\n <Text namespace={namespace} phrase='incorrect' />\n </button>\n <button className={getFilterClassName('skipped')} onClick={() => props.toggleFilter('skipped')}>\n <Text namespace={namespace} phrase='skipped' />\n </button>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { Interaction } from 'libs/shared/interfaces';\n\nconst namespace = 'interactives.interactionResponseListHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InteractionResponseListHeaderProps {\n interaction: Interaction;\n}\n\nexport function InteractionResponseListHeader(props: InteractionResponseListHeaderProps): JSX.Element {\n const suggestedResponse = props.interaction.data?.suggestedResponse;\n\n return (\n <div className='rounded bg-white'>\n <div className='p-2 position-relative'>\n <div className='d-flex'>\n <InteractionLabel\n interaction={props.interaction}\n iconClassName='flex-shrink-0'\n />\n </div>\n {!!suggestedResponse &&\n <div className='mt-2'>\n <strong>{getPhrase('suggestedResponse')}</strong>\n <p className='m-0'>{suggestedResponse}</p>\n </div>\n }\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nconst namespace = 'shared.submitMarkedAnswers';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SubmitMarkedAnswersProps {\n submit: () => void;\n disabled: boolean\n}\n\nexport function SubmitMarkedAnswers(props: SubmitMarkedAnswersProps): JSX.Element {\n return (\n <div className='d-flex justify-content-end'>\n <button\n className='btn btn-outline-dark'\n onClick={props.submit}\n disabled={props.disabled}\n >\n {getPhrase('submitAnswers')}\n </button>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"awaitingMarking\":\"PPNkp\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { InteractionResponseItem } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/InteractionResponseItem';\nimport { InteractionResponseFilterType, InteractionResponseListFilters, InteractionResponseListFiltersEmptyStates } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListFilters';\nimport { InteractionResponseListHeader } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListHeader';\nimport { SubmitMarkedAnswers } from 'libs/shared/apps/analytics/components/questions-list/submit-marked-answers/SubmitMarkedAnswers';\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { anonymiseUserName } from 'libs/shared/apps/analytics/utils/AnonymiseUserUtils';\nimport { getMarkedStatus } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { InteractionResponse } from 'libs/shared/components/interaction-response/InteractionResponse';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, InteractiveResultSet, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\nimport styles from './interaction-response-list.scss';\n\nconst namespace = 'shared.interactionResponseList';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getResponsesToMark(\n interaction: Interaction,\n studentResults: StudentResults[]\n): HashObject {\n const responsesToMark = studentResults.filter(s => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(\n interaction,\n getStudentResult(s)\n );\n return correctness === InteractionCorrectness.AwaitingMarking;\n });\n\n return responsesToMark.reduce((acc, s) => ({\n ...acc,\n [s.user?.id || s.publicUser?.profileId]: true\n }), {});\n}\n\ninterface InteractionResponseListProps {\n interaction: Interaction\n results: InteractiveResultSet;\n markedAnswers: MarkedAnswerHash;\n addMarkedAnswers: (answer: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n submitMarkedAnswers: () => void;\n imageCdnUrl: string;\n anonymiseUsers: boolean;\n reportsStyling?: boolean;\n emptyStateImageUrl: string;\n markingRequiredImageUrl: string;\n correctImageUrl: string;\n incorrectImageUrl: string;\n skippedImageUrl: string;\n isDemo?: boolean;\n}\n\nexport function InteractionResponseList(props: InteractionResponseListProps): JSX.Element {\n const [ filter, setFilter ] = React.useState<InteractionResponseFilterType>();\n\n const responsesToMark = getResponsesToMark(props.interaction, props.results.students);\n const numMarkedAnswers = Object.keys(props.markedAnswers).length;\n\n if (!props.results.students?.length)\n return (\n <div className='d-flex flex-column h-100'>\n <EmptyState className='bg-white rounded mt-2 py-5 flex-grow-1 justify-content-center'>\n <EmptyState.Image src={props.emptyStateImageUrl} size='small' />\n <EmptyState.Heading>\n {getPhrase('emptyStateHeading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('emptyStateDescription')}\n </EmptyState.Info>\n </EmptyState>\n </div>\n );\n\n\n function toggleFilter(selectedFilter: InteractionResponseFilterType) {\n setFilter(filter === selectedFilter ? null : selectedFilter);\n }\n\n function filterStudentResults() {\n return props.results.students.filter(s => {\n const result = getStudentResult(s);\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(props.interaction, result);\n\n const filterMap = {\n correct: InteractionCorrectness.Correct,\n incorrect: InteractionCorrectness.Incorrect,\n marking_required: InteractionCorrectness.AwaitingMarking,\n skipped: InteractionCorrectness.UnAnswered\n };\n\n return !filter || (filter in filterMap && correctness === filterMap[filter]);\n });\n }\n\n const filteredStudentResults = filterStudentResults();\n\n return (\n <>\n {props.reportsStyling && <InteractionResponseListHeader interaction={props.interaction} />}\n <div className={props.reportsStyling\n ? 'd-flex justify-content-end'\n : 'd-flex align-items-center justify-content-between border-bottom px-3 py-2'\n }>\n {!props.reportsStyling && <p className='fw-semibold mb-0'><Text namespace={namespace} phrase='studentAnswers' /></p>}\n {!!Object.keys(responsesToMark).length &&\n <Tooltip id='submitAnswers' title={getPhrase('demoOnly')} spanHack={props.isDemo}>\n <div className={`${props.isDemo ? 'pointer-events-none' : ''} ${props.reportsStyling ? 'mt-2' : ''}`}>\n <SubmitMarkedAnswers submit={props.submitMarkedAnswers} disabled={!numMarkedAnswers} />\n </div>\n </Tooltip>\n }\n </div>\n <>\n {!props.reportsStyling && <InteractionResponseListFilters filter={filter} toggleFilter={toggleFilter} />}\n\n {!props.reportsStyling && !filteredStudentResults.length && filter && (\n <InteractionResponseListFiltersEmptyStates\n filter={filter}\n markingRequiredImageUrl={props.markingRequiredImageUrl}\n correctImageUrl={props.correctImageUrl}\n incorrectImageUrl={props.incorrectImageUrl}\n skippedImageUrl={props.skippedImageUrl}\n />\n )}\n \n {filteredStudentResults && (\n <ul className='list-unstyled mb-0'>\n {filteredStudentResults.map((s, idx) => {\n const anonymisedUserName = anonymiseUserName(s.user || s.publicUser, props.anonymiseUsers);\n const markingRequired = responsesToMark[s.user?.id || s.publicUser?.profileId];\n\n let className = props.reportsStyling ? 'bg-white p-2' : 'bg-white px-3 pt-3 pb-2';\n\n if (markingRequired)\n className += ` ${styles.awaitingMarking} my-1`;\n\n return (\n <li key={idx} className={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 { InteractionWithResultsSummary } from 'libs/shared/apps/analytics/interfaces/InteractionWithResultsSummary';\nimport { getInteractionById } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { getSortStudents, SortStudentsBy } from 'libs/shared/apps/analytics/utils/StudentTableUtils';\nimport { Table, TableTheme } from 'libs/shared/components/table/Table';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interactive, InteractiveResultSet, StudentAnswer } from 'libs/shared/interfaces';\nimport { AppRouteHelper } from 'libs/shared/utils/AppRouteHelper';\n\nimport { getColumns, useGetTableData } from './QuestionTableUtils';\n\ninterface QuestionTableProps {\n interactive: Interactive;\n results: InteractiveResultSet;\n markedAnswers: { [id: string]: StudentAnswer };\n addMarkedAnswers: (answer: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n submitMarkedAnswers: () => void;\n editSuggestedResponse?: () => void;\n imageCdnUrl: string;\n selectQuestionImageUrl: string;\n anonymiseUsers: boolean;\n sortBy?: SortStudentsBy;\n emptyStateImageUrl: string;\n markingRequiredImageUrl?: string;\n correctImageUrl?: string;\n incorrectImageUrl?: string;\n skippedImageUrl?: string;\n\n /**\n * As the table data is memoized, it must be prompted to recalculate.\n * Toggle `refreshTable` to do so.\n */\n refreshTable: boolean;\n selectedInteractionId?: string;\n showAnswersInTable?: boolean;\n theme: TableTheme;\n reportsStyling?: boolean;\n isDemo?: boolean;\n}\n\nexport function QuestionTable(props: QuestionTableProps): JSX.Element {\n const [ sortBy, setSortBy ] = React.useState<SortingRule<InteractionWithResultsSummary>[]>(\n getSortStudents(props.sortBy, 'correctlyAnswered')\n );\n const data = useGetTableData(props.interactive, props.results, props.refreshTable, ArrayHelper.first(sortBy));\n\n const selectedInteraction = props.selectedInteractionId &&\n getInteractionById(props.interactive, props.selectedInteractionId);\n\n function onSelectRow({ original: interaction }: Row<InteractionWithResultsSummary>): void {\n ScrollHelper.preventScrollTop();\n\n AppRouteHelper.updateParams(\n { interactionId: interaction.id },\n { merge: true }\n );\n }\n\n return (\n <div className='row'>\n <div className='col-6 flex-grow-1'>\n <Table\n key={props.selectedInteractionId}\n columns={getColumns(props.showAnswersInTable)}\n data={data}\n theme={props.theme}\n onSelectRow={onSelectRow}\n initialSelectedRowIds={selectedInteraction ? [selectedInteraction.id] : null}\n getRowId={(row: InteractionWithResultsSummary) => row.id}\n enableSort\n manualSort\n onSort={setSortBy}\n initialSortBy={sortBy}\n />\n </div>\n <div className='col-6 d-flex flex-column'>\n {!props.reportsStyling && props.selectedInteractionId && !!props.results.students?.length && (\n <QuestionResultsSummary\n interaction={selectedInteraction}\n results={props.results}\n />\n )}\n\n <div className={`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 />\n }\n {!selectedInteraction && <SelectedInteractionEmptyState emptyStateUrl={props.selectQuestionImageUrl} />}\n </div>\n </div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialInsights\":\"zZ5oK\"};","import React from 'react';\n\nimport styles from './partial-interactive-insights-questions.scss';\n\nexport function PartialInteractiveInsightsQuestions() {\n return (\n <div>\n <div className='row g-3 mb-5'>\n <div className='col-6'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n <div className='col-6'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { QuestionTable } from 'libs/shared/apps/analytics/components/questions-list/question-table/QuestionTable';\nimport { useMarkAnswers } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { SortStudentsBy } from 'libs/shared/apps/analytics/utils/StudentTableUtils';\nimport { ConfirmationPopup } from 'libs/shared/components/confirmation-popup/ConfirmationPopup';\nimport { TableTheme } from 'libs/shared/components/table/Table';\nimport { Config, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport { PartialInteractiveInsightsQuestions } from 'apps/insights/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}\n\nexport function InteractiveInsightsQuestions(props: InteractiveInsightsQuestionsProps) {\n const [ showMarkConfirmationPopup, setShowMarkConfirmationPopup ] = React.useState(false);\n\n const { markedAnswers, addMarkedAnswers, submitMarkedAnswers } = useMarkAnswers(\n props.interactive?.id,\n props.interactiveMetadata?.id,\n () => setShowMarkConfirmationPopup(false)\n );\n\n return (\n <>\n {!props.hasDataLoaded && <PartialInteractiveInsightsQuestions />}\n\n {props.hasDataLoaded &&\n <QuestionTable\n interactive={props.interactive}\n results={props.results}\n markedAnswers={markedAnswers}\n addMarkedAnswers={addMarkedAnswers}\n submitMarkedAnswers={() => setShowMarkConfirmationPopup(true)}\n imageCdnUrl={props.config.imageCdnUrl}\n selectedInteractionId={props.interactionId}\n refreshTable={props.isFetching}\n emptyStateImageUrl={ImageUrls.Insights.NO_RESPONSES}\n selectQuestionImageUrl={ImageUrls.Insights.NO_DATA}\n anonymiseUsers={props.anonymiseUsers}\n sortBy={props.sortBy}\n showAnswersInTable\n theme={theme}\n correctImageUrl={ImageUrls.Insights.JIGSAW}\n incorrectImageUrl={ImageUrls.Insights.RED_JIGSAW}\n skippedImageUrl={ImageUrls.Insights.SKIPPED}\n markingRequiredImageUrl={ImageUrls.Insights.CLIPBOARD}\n isDemo={props.isDemo}\n />\n }\n\n {showMarkConfirmationPopup &&\n <ConfirmationPopup\n title={getPhrase('markPopupTitle', { smartCount: Object.keys(markedAnswers).length ?? 0 })}\n closePopup={() => setShowMarkConfirmationPopup(false)}\n confirmButtonText={getPhrase('submit')}\n confirmButtonVariant='dark'\n onClickConfirm={submitMarkedAnswers}\n >\n <p>{getPhrase('markPopupBody')}</p>\n </ConfirmationPopup>\n }\n </>\n );\n}"],"names":["getPhrase","getClassName","props","className","showLabel","PendingIndicator","Indicator","title","spanHack","spanHackClassName","tooltipClassName","getSortStudents","sortBy","id","desc","shouldFilterStudent","filter","summary","awaitingMarking","percentCorrect","unanswered","ConfirmationPopup","showButtonSpinner","setShowButtonSpinner","closePopup","children","onClick","variant","cancelButtonVariant","text","cancelButtonText","onClickConfirm","confirmButtonText","confirmButtonVariant","showSpinner","disabled","disabledConfirmButton","defaultProps","DragOverlayStyles","opacity","cursor","calculateScrollState","ref","canScrollLeft","current","scrollLeft","canScrollRight","scrollWidth","clientWidth","SortIndicator","column","canSort","isSorted","theme","sortIndicator","SvgContainer","svgName","isSortedDesc","size","S","BaseTable","ids","idHash","tableOptions","columns","data","disableSortBy","enableSort","manualSortBy","manualSort","autoResetHiddenColumns","autoResetSortBy","initialState","initialSortBy","initialSelectedRowIds","selectedRowIds","forEach","getRowId","useTable","plugins","useSortBy","useRowSelect","layout","useFlexLayout","useBlockLayout","allowFiltering","useFilters","allowGlobalFiltering","useGlobalFilter","getPlugins","getTableProps","getTableBodyProps","headerGroups","rows","prepareRow","toggleAllRowsSelected","setGlobalFilter","setHiddenColumns","state","renderTableRows","map","row","FunctionHelper","isSelected","selectedRow","onSelectRow","enableSortableRows","getTableRowsClass","rowAppLink","getRowAppLink","onClickRow","allowSelectMultipleRows","toggleRowSelected","renderRow","sortableProps","dragAttributes","dragListeners","getSortableProps","role","key","AppLink","appLink","renderCells","rowProps","getRowProps","SortableItemWrapper","original","childProps","childComponent","cells","cell","cellClassName","onSelectCell","getCellClassName","getCellProps","render","onSort","globalFilter","hiddenColumns","length","table","header","headerGroup","getHeaderGroupProps","headerRow","headers","getHeaderProps","getSortByToggleProps","headerCell","renderSortIndicator","hideSortIndicator","body","SortableContainerWrapper","getDragOverlay","rowIndex","findIndex","item","style","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","namespace","InteractionResponseListFiltersEmptyStates","EmptyState","src","correctImageUrl","incorrectImageUrl","markingRequiredImageUrl","skippedImageUrl","getFilterEmptyStateImageUrl","Text","phrase","getFilterEmptyStatePhrase","InteractionResponseListFilters","getFilterClassName","filterButton","isFilterSelected","toggleFilter","LanguageService","InteractionResponseListHeader","suggestedResponse","interaction","InteractionLabel","iconClassName","SubmitMarkedAnswers","submit","InteractionResponseList","setFilter","responsesToMark","results","students","s","InteractiveCorrectnessHelper","InteractionCorrectness","reduce","acc","user","publicUser","profileId","numMarkedAnswers","Object","keys","markedAnswers","emptyStateImageUrl","filteredStudentResults","result","correctness","filterMap","correct","incorrect","marking_required","skipped","reportsStyling","Tooltip","isDemo","submitMarkedAnswers","selectedFilter","idx","anonymisedUserName","anonymiseUsers","markingRequired","InteractionResponse","studentResults","markedStatus","markInteraction","addMarkedAnswers","imageCdnUrl","showStudentDetails","showFeedback","responseComponentClass","InteractionResponseItem","QuestionTableMissingWord","str","sentence","split","part","index","match","replacement","actionableItems","find","answer","order","name","QuestionTableMultipleChoice","ArrayHelper","imageUrl","MultipleChoiceInteractionAnswers","showCorrectnessIcons","isDisplayOnly","option","isCorrect","indexToLetter","QuestionTableShortAnswer","QuestionTableTrueOrFalse","QuestionTableAnswers","QuestionTableAnswerComponent","typeId","getQuestionTableAnswerComponent","sortScore","rowA","rowB","columnId","cellA","value","cellB","CellWrapper","HeaderCell","phraseKey","String","fromCharCode","charCodeAt","multipleChoiceSummary","questionsSummary","i","label","count","student","latestAttempts","attempts","response","answers","questionSummary","missingWordSummary","push","status","InteractiveAnswerStatus","markedSummary","pendingSummary","QuestionResultsSummary","summaryMethod","getQuestionSummary","maxResponseCount","getBarClassName","width","height","SelectedInteractionEmptyState","emptyStateUrl","QuestionTable","showAnswersInTable","setSortBy","interactive","refreshData","flattenedInteractions","questionNumbers","interactions","questionNumber","resultsSummary","sorted","reverse","useGetTableData","refreshTable","selectedInteraction","selectedInteractionId","Header","accessor","Cell","containerClassName","PercentageIndicator","percentage","sortDescFirst","sortType","ScrollHelper","AppRouteHelper","interactionId","merge","selectQuestionImageUrl","PartialInteractiveInsightsQuestions","InteractiveInsightsQuestions","showMarkConfirmationPopup","setShowMarkConfirmationPopup","interactiveMetadata","hasDataLoaded","config","isFetching","ImageUrls","smartCount"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"scripts/4358-a1bbca8249-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/utils/StudentTableUtils.ts","file:///app/packages/libs/shared/src/components/confirmation-popup/ConfirmationPopup.tsx","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/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListFilters.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListHeader.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/submit-marked-answers/SubmitMarkedAnswers.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/interaction-response-list.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseList.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMissingWord.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/question-table-answers.scss","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableMultipleChoice.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableShortAnswer.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableTrueOrFalse.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-table-answers/QuestionTableAnswers.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/QuestionTableUtils.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummaryUtils.ts","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/question-results-summary/QuestionResultsSummary.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/selected-interaction-empty-state/SelectedInteractionEmptyState.tsx","file:///app/packages/libs/shared/src/apps/analytics/components/questions-list/question-table/QuestionTable.tsx","file:///app/packages/projects/lite/src/apps/insights/components/interactive-insights-questions/partial-loading/partial-interactive-insights-questions.scss","file:///app/packages/projects/lite/src/apps/insights/components/interactive-insights-questions/partial-loading/PartialInteractiveInsightsQuestions.tsx","file:///app/packages/projects/lite/src/apps/insights/components/interactive-insights-questions/InteractiveInsightsQuestions.tsx"],"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 { 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}","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 { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'shared.interactionResponseList';\n\nexport type InteractionResponseFilterType = 'marking_required' | 'correct' | 'incorrect' | 'skipped';\n\ninterface InteractionResponseListFiltersEmptyStatesProps {\n filter: InteractionResponseFilterType;\n markingRequiredImageUrl: string;\n correctImageUrl: string;\n incorrectImageUrl: string;\n skippedImageUrl: string;\n}\n\nexport function InteractionResponseListFiltersEmptyStates(props: InteractionResponseListFiltersEmptyStatesProps) {\n function getFilterEmptyStateImageUrl() {\n switch (props.filter) {\n case 'correct': return props.correctImageUrl;\n case 'incorrect': return props.incorrectImageUrl;\n case 'marking_required': return props.markingRequiredImageUrl;\n case 'skipped': return props.skippedImageUrl;\n }\n }\n\n function getFilterEmptyStatePhrase() {\n switch (props.filter) {\n case 'correct': return 'correctEmptyState';\n case 'incorrect': return 'incorrectEmptyState';\n case 'marking_required': return 'markingRequiredEmptyState';\n case 'skipped': return 'skippedEmptyState';\n }\n }\n\n return (\n <>\n <EmptyState className='m-4'>\n <EmptyState.Image src={getFilterEmptyStateImageUrl()} className='w-25 h-auto' />\n <EmptyState.Info>\n <Text namespace={namespace} phrase={getFilterEmptyStatePhrase()} />\n </EmptyState.Info>\n </EmptyState>\n </>\n );\n}\n\ninterface InteractionResponseListFiltersProps {\n filter: InteractionResponseFilterType;\n toggleFilter: (filter: InteractionResponseFilterType) => void\n}\n\nexport function InteractionResponseListFilters(props: InteractionResponseListFiltersProps) {\n function isFilterSelected(filterButton: InteractionResponseFilterType) {\n return filterButton === props.filter;\n }\n\n function getFilterClassName(filterButton: InteractionResponseFilterType) {\n return `rounded-pill bg-light ${isFilterSelected(filterButton) ? 'bg-dark text-white' : ''}`;\n }\n\n return (\n\n <div className='d-flex gap-2 m-3'>\n <button className={getFilterClassName('marking_required')} onClick={() => props.toggleFilter('marking_required')}>\n <Text namespace={namespace} phrase='markingRequired' />\n </button>\n <button className={getFilterClassName('correct')} onClick={() => props.toggleFilter('correct')}>\n <Text namespace={namespace} phrase='correct' />\n </button>\n <button className={getFilterClassName('incorrect')} onClick={() => props.toggleFilter('incorrect')}>\n <Text namespace={namespace} phrase='incorrect' />\n </button>\n <button className={getFilterClassName('skipped')} onClick={() => props.toggleFilter('skipped')}>\n <Text namespace={namespace} phrase='skipped' />\n </button>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { InteractionLabel } from 'libs/shared/components/interactive-questions/InteractionLabel';\nimport { Interaction } from 'libs/shared/interfaces';\n\nconst namespace = 'interactives.interactionResponseListHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface InteractionResponseListHeaderProps {\n interaction: Interaction;\n}\n\nexport function InteractionResponseListHeader(props: InteractionResponseListHeaderProps): JSX.Element {\n const suggestedResponse = props.interaction.data?.suggestedResponse;\n\n return (\n <div className='rounded bg-white'>\n <div className='p-2 position-relative'>\n <div className='d-flex'>\n <InteractionLabel\n interaction={props.interaction}\n iconClassName='flex-shrink-0'\n />\n </div>\n {!!suggestedResponse &&\n <div className='mt-2'>\n <strong>{getPhrase('suggestedResponse')}</strong>\n <p className='m-0'>{suggestedResponse}</p>\n </div>\n }\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nconst namespace = 'shared.submitMarkedAnswers';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface SubmitMarkedAnswersProps {\n submit: () => void;\n disabled: boolean\n}\n\nexport function SubmitMarkedAnswers(props: SubmitMarkedAnswersProps): JSX.Element {\n return (\n <div className='d-flex justify-content-end'>\n <button\n className='btn btn-outline-dark'\n onClick={props.submit}\n disabled={props.disabled}\n >\n {getPhrase('submitAnswers')}\n </button>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"awaitingMarking\":\"PPNkp\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { InteractionResponseItem } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-item/InteractionResponseItem';\nimport { InteractionResponseFilterType, InteractionResponseListFilters, InteractionResponseListFiltersEmptyStates } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListFilters';\nimport { InteractionResponseListHeader } from 'libs/shared/apps/analytics/components/questions-list/interaction-response-list/InteractionResponseListHeader';\nimport { SubmitMarkedAnswers } from 'libs/shared/apps/analytics/components/questions-list/submit-marked-answers/SubmitMarkedAnswers';\nimport { MarkedAnswerHash } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { anonymiseUserName } from 'libs/shared/apps/analytics/utils/AnonymiseUserUtils';\nimport { getMarkedStatus } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { InteractionResponse } from 'libs/shared/components/interaction-response/InteractionResponse';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { InteractionCorrectness } from 'libs/shared/enums/InteractionCorrectness';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interaction, InteractiveResultSet, StudentAnswer, StudentResults } from 'libs/shared/interfaces';\nimport { InteractiveCorrectnessHelper } from 'libs/shared/utils/InteractiveCorrectnessHelper';\nimport { getStudentResult } from 'libs/shared/utils/InteractiveHelper';\n\nimport styles from './interaction-response-list.scss';\n\nconst namespace = 'shared.interactionResponseList';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getResponsesToMark(\n interaction: Interaction,\n studentResults: StudentResults[]\n): HashObject {\n const responsesToMark = studentResults.filter(s => {\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(\n interaction,\n getStudentResult(s)\n );\n return correctness === InteractionCorrectness.AwaitingMarking;\n });\n\n return responsesToMark.reduce((acc, s) => ({\n ...acc,\n [s.user?.id || s.publicUser?.profileId]: true\n }), {});\n}\n\ninterface InteractionResponseListProps {\n interaction: Interaction\n results: InteractiveResultSet;\n markedAnswers: MarkedAnswerHash;\n addMarkedAnswers: (answer: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n submitMarkedAnswers: () => void;\n imageCdnUrl: string;\n anonymiseUsers: boolean;\n reportsStyling?: boolean;\n emptyStateImageUrl: string;\n markingRequiredImageUrl: string;\n correctImageUrl: string;\n incorrectImageUrl: string;\n skippedImageUrl: string;\n isDemo?: boolean;\n}\n\nexport function InteractionResponseList(props: InteractionResponseListProps): JSX.Element {\n const [ filter, setFilter ] = React.useState<InteractionResponseFilterType>();\n\n const responsesToMark = getResponsesToMark(props.interaction, props.results.students);\n const numMarkedAnswers = Object.keys(props.markedAnswers).length;\n\n if (!props.results.students?.length)\n return (\n <div className='d-flex flex-column h-100'>\n <EmptyState className='bg-white rounded mt-2 py-5 flex-grow-1 justify-content-center'>\n <EmptyState.Image src={props.emptyStateImageUrl} size='small' />\n <EmptyState.Heading>\n {getPhrase('emptyStateHeading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('emptyStateDescription')}\n </EmptyState.Info>\n </EmptyState>\n </div>\n );\n\n\n function toggleFilter(selectedFilter: InteractionResponseFilterType) {\n setFilter(filter === selectedFilter ? null : selectedFilter);\n }\n\n function filterStudentResults() {\n return props.results.students.filter(s => {\n const result = getStudentResult(s);\n\n const correctness = InteractiveCorrectnessHelper.isInteractionCorrect(props.interaction, result);\n\n const filterMap = {\n correct: InteractionCorrectness.Correct,\n incorrect: InteractionCorrectness.Incorrect,\n marking_required: InteractionCorrectness.AwaitingMarking,\n skipped: InteractionCorrectness.UnAnswered\n };\n\n return !filter || (filter in filterMap && correctness === filterMap[filter]);\n });\n }\n\n const filteredStudentResults = filterStudentResults();\n\n return (\n <>\n {props.reportsStyling && <InteractionResponseListHeader interaction={props.interaction} />}\n <div className={props.reportsStyling\n ? 'd-flex justify-content-end'\n : 'd-flex align-items-center justify-content-between border-bottom px-3 py-2'\n }>\n {!props.reportsStyling && <p className='fw-semibold mb-0'><Text namespace={namespace} phrase='studentAnswers' /></p>}\n {!!Object.keys(responsesToMark).length &&\n <Tooltip id='submitAnswers' title={getPhrase('demoOnly')} spanHack={props.isDemo}>\n <div className={`${props.isDemo ? 'pointer-events-none' : ''} ${props.reportsStyling ? 'mt-2' : ''}`}>\n <SubmitMarkedAnswers submit={props.submitMarkedAnswers} disabled={!numMarkedAnswers} />\n </div>\n </Tooltip>\n }\n </div>\n <>\n {!props.reportsStyling && <InteractionResponseListFilters filter={filter} toggleFilter={toggleFilter} />}\n\n {!props.reportsStyling && !filteredStudentResults.length && filter && (\n <InteractionResponseListFiltersEmptyStates\n filter={filter}\n markingRequiredImageUrl={props.markingRequiredImageUrl}\n correctImageUrl={props.correctImageUrl}\n incorrectImageUrl={props.incorrectImageUrl}\n skippedImageUrl={props.skippedImageUrl}\n />\n )}\n \n {filteredStudentResults && (\n <ul className='list-unstyled mb-0'>\n {filteredStudentResults.map((s, idx) => {\n const anonymisedUserName = anonymiseUserName(s.user || s.publicUser, props.anonymiseUsers);\n const markingRequired = responsesToMark[s.user?.id || s.publicUser?.profileId];\n\n let className = props.reportsStyling ? 'bg-white p-2' : 'bg-white px-3 pt-3 pb-2';\n\n if (markingRequired)\n className += ` ${styles.awaitingMarking} my-1`;\n\n return (\n <li key={idx} className={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 { InteractionWithResultsSummary } from 'libs/shared/apps/analytics/interfaces/InteractionWithResultsSummary';\nimport { getInteractionById } from 'libs/shared/apps/analytics/utils/InteractiveUtils';\nimport { getSortStudents, SortStudentsBy } from 'libs/shared/apps/analytics/utils/StudentTableUtils';\nimport { Table, TableTheme } from 'libs/shared/components/table/Table';\nimport { InteractiveAnswerStatus } from 'libs/shared/enums/InteractiveAnswerStatus';\nimport { Interactive, InteractiveResultSet, StudentAnswer } from 'libs/shared/interfaces';\nimport { AppRouteHelper } from 'libs/shared/utils/AppRouteHelper';\n\nimport { getColumns, useGetTableData } from './QuestionTableUtils';\n\ninterface QuestionTableProps {\n interactive: Interactive;\n results: InteractiveResultSet;\n markedAnswers: { [id: string]: StudentAnswer };\n addMarkedAnswers: (answer: StudentAnswer[], status: InteractiveAnswerStatus) => void;\n submitMarkedAnswers: () => void;\n editSuggestedResponse?: () => void;\n imageCdnUrl: string;\n selectQuestionImageUrl: string;\n anonymiseUsers: boolean;\n sortBy?: SortStudentsBy;\n emptyStateImageUrl: string;\n markingRequiredImageUrl?: string;\n correctImageUrl?: string;\n incorrectImageUrl?: string;\n skippedImageUrl?: string;\n\n /**\n * As the table data is memoized, it must be prompted to recalculate.\n * Toggle `refreshTable` to do so.\n */\n refreshTable: boolean;\n selectedInteractionId?: string;\n showAnswersInTable?: boolean;\n theme: TableTheme;\n reportsStyling?: boolean;\n isDemo?: boolean;\n}\n\nexport function QuestionTable(props: QuestionTableProps): JSX.Element {\n const [ sortBy, setSortBy ] = React.useState<SortingRule<InteractionWithResultsSummary>[]>(\n getSortStudents(props.sortBy, 'correctlyAnswered')\n );\n const data = useGetTableData(props.interactive, props.results, props.refreshTable, ArrayHelper.first(sortBy));\n\n const selectedInteraction = props.selectedInteractionId &&\n getInteractionById(props.interactive, props.selectedInteractionId);\n\n function onSelectRow({ original: interaction }: Row<InteractionWithResultsSummary>): void {\n ScrollHelper.preventScrollTop();\n\n AppRouteHelper.updateParams(\n { interactionId: interaction.id },\n { merge: true }\n );\n }\n\n return (\n <div className='row'>\n <div className='col-6 flex-grow-1'>\n <Table\n key={props.selectedInteractionId}\n columns={getColumns(props.showAnswersInTable)}\n data={data}\n theme={props.theme}\n onSelectRow={onSelectRow}\n initialSelectedRowIds={selectedInteraction ? [selectedInteraction.id] : null}\n getRowId={(row: InteractionWithResultsSummary) => row.id}\n enableSort\n manualSort\n onSort={setSortBy}\n initialSortBy={sortBy}\n />\n </div>\n <div className='col-6 d-flex flex-column'>\n {!props.reportsStyling && props.selectedInteractionId && !!props.results.students?.length && (\n <QuestionResultsSummary\n interaction={selectedInteraction}\n results={props.results}\n />\n )}\n\n <div className={`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 />\n }\n {!selectedInteraction && <SelectedInteractionEmptyState emptyStateUrl={props.selectQuestionImageUrl} />}\n </div>\n </div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"partialInsights\":\"zZ5oK\"};","import React from 'react';\n\nimport styles from './partial-interactive-insights-questions.scss';\n\nexport function PartialInteractiveInsightsQuestions() {\n return (\n <div>\n <div className='row g-3 mb-5'>\n <div className='col-6'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n <div className='col-6'>\n <div className={`${styles.partialInsights} rounded partial-loading-background`}></div>\n </div>\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { QuestionTable } from 'libs/shared/apps/analytics/components/questions-list/question-table/QuestionTable';\nimport { useMarkAnswers } from 'libs/shared/apps/analytics/hooks/UseMarkAnswers';\nimport { SortStudentsBy } from 'libs/shared/apps/analytics/utils/StudentTableUtils';\nimport { ConfirmationPopup } from 'libs/shared/components/confirmation-popup/ConfirmationPopup';\nimport { TableTheme } from 'libs/shared/components/table/Table';\nimport { Config, Interactive, InteractiveMetadata, InteractiveResultSet } from 'libs/shared/interfaces';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\n\nimport { PartialInteractiveInsightsQuestions } from 'apps/insights/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}\n\nexport function InteractiveInsightsQuestions(props: InteractiveInsightsQuestionsProps) {\n const [ showMarkConfirmationPopup, setShowMarkConfirmationPopup ] = React.useState(false);\n\n const { markedAnswers, addMarkedAnswers, submitMarkedAnswers } = useMarkAnswers(\n props.interactive?.id,\n props.interactiveMetadata?.id,\n () => setShowMarkConfirmationPopup(false)\n );\n\n return (\n <>\n {!props.hasDataLoaded && <PartialInteractiveInsightsQuestions />}\n\n {props.hasDataLoaded &&\n <QuestionTable\n interactive={props.interactive}\n results={props.results}\n markedAnswers={markedAnswers}\n addMarkedAnswers={addMarkedAnswers}\n submitMarkedAnswers={() => setShowMarkConfirmationPopup(true)}\n imageCdnUrl={props.config.imageCdnUrl}\n selectedInteractionId={props.interactionId}\n refreshTable={props.isFetching}\n emptyStateImageUrl={ImageUrls.Insights.NO_RESPONSES}\n selectQuestionImageUrl={ImageUrls.Insights.NO_DATA}\n anonymiseUsers={props.anonymiseUsers}\n sortBy={props.sortBy}\n showAnswersInTable\n theme={theme}\n correctImageUrl={ImageUrls.Insights.JIGSAW}\n incorrectImageUrl={ImageUrls.Insights.RED_JIGSAW}\n skippedImageUrl={ImageUrls.Insights.SKIPPED}\n markingRequiredImageUrl={ImageUrls.Insights.CLIPBOARD}\n isDemo={props.isDemo}\n />\n }\n\n {showMarkConfirmationPopup &&\n <ConfirmationPopup\n title={getPhrase('markPopupTitle', { smartCount: Object.keys(markedAnswers).length ?? 0 })}\n closePopup={() => setShowMarkConfirmationPopup(false)}\n confirmButtonText={getPhrase('submit')}\n confirmButtonVariant='dark'\n onClickConfirm={submitMarkedAnswers}\n >\n <p>{getPhrase('markPopupBody')}</p>\n </ConfirmationPopup>\n }\n </>\n );\n}"],"names":["getPhrase","getClassName","props","className","showLabel","PendingIndicator","Indicator","title","spanHack","spanHackClassName","tooltipClassName","getSortStudents","sortBy","id","desc","shouldFilterStudent","filter","summary","awaitingMarking","percentCorrect","unanswered","ConfirmationPopup","showButtonSpinner","setShowButtonSpinner","closePopup","children","onClick","variant","cancelButtonVariant","text","cancelButtonText","onClickConfirm","confirmButtonText","confirmButtonVariant","showSpinner","disabled","disabledConfirmButton","defaultProps","DragOverlayStyles","opacity","cursor","calculateScrollState","ref","canScrollLeft","current","scrollLeft","canScrollRight","scrollWidth","clientWidth","SortIndicator","column","canSort","isSorted","theme","sortIndicator","SvgContainer","svgName","isSortedDesc","size","S","BaseTable","ids","idHash","tableOptions","columns","data","disableSortBy","enableSort","manualSortBy","manualSort","autoResetHiddenColumns","autoResetSortBy","initialState","initialSortBy","initialSelectedRowIds","selectedRowIds","forEach","getRowId","useTable","plugins","useSortBy","useRowSelect","layout","useFlexLayout","useBlockLayout","allowFiltering","useFilters","allowGlobalFiltering","useGlobalFilter","getPlugins","getTableProps","getTableBodyProps","headerGroups","rows","prepareRow","toggleAllRowsSelected","setGlobalFilter","setHiddenColumns","state","renderTableRows","map","row","FunctionHelper","isSelected","selectedRow","onSelectRow","enableSortableRows","getTableRowsClass","rowAppLink","getRowAppLink","onClickRow","allowSelectMultipleRows","toggleRowSelected","renderRow","sortableProps","dragAttributes","dragListeners","getSortableProps","role","key","AppLink","appLink","renderCells","rowProps","getRowProps","SortableItemWrapper","original","childProps","childComponent","cells","cell","cellClassName","onSelectCell","getCellClassName","getCellProps","render","onSort","globalFilter","hiddenColumns","length","table","header","headerGroup","getHeaderGroupProps","headerRow","headers","getHeaderProps","getSortByToggleProps","headerCell","renderSortIndicator","hideSortIndicator","body","SortableContainerWrapper","getDragOverlay","rowIndex","findIndex","item","style","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","namespace","InteractionResponseListFiltersEmptyStates","EmptyState","src","correctImageUrl","incorrectImageUrl","markingRequiredImageUrl","skippedImageUrl","getFilterEmptyStateImageUrl","Text","phrase","getFilterEmptyStatePhrase","InteractionResponseListFilters","getFilterClassName","filterButton","isFilterSelected","toggleFilter","LanguageService","InteractionResponseListHeader","suggestedResponse","interaction","InteractionLabel","iconClassName","SubmitMarkedAnswers","submit","InteractionResponseList","setFilter","responsesToMark","results","students","s","InteractiveCorrectnessHelper","InteractionCorrectness","reduce","acc","user","publicUser","profileId","numMarkedAnswers","Object","keys","markedAnswers","emptyStateImageUrl","filteredStudentResults","result","correctness","filterMap","correct","incorrect","marking_required","skipped","reportsStyling","Tooltip","isDemo","submitMarkedAnswers","selectedFilter","idx","anonymisedUserName","anonymiseUsers","markingRequired","InteractionResponse","studentResults","markedStatus","markInteraction","addMarkedAnswers","imageCdnUrl","showStudentDetails","showFeedback","responseComponentClass","InteractionResponseItem","QuestionTableMissingWord","str","sentence","split","part","index","match","replacement","actionableItems","find","answer","order","name","QuestionTableMultipleChoice","ArrayHelper","imageUrl","MultipleChoiceInteractionAnswers","showCorrectnessIcons","isDisplayOnly","option","isCorrect","indexToLetter","QuestionTableShortAnswer","QuestionTableTrueOrFalse","QuestionTableAnswers","QuestionTableAnswerComponent","typeId","getQuestionTableAnswerComponent","sortScore","rowA","rowB","columnId","cellA","value","cellB","CellWrapper","HeaderCell","phraseKey","String","fromCharCode","charCodeAt","multipleChoiceSummary","questionsSummary","i","label","count","student","latestAttempts","attempts","response","answers","questionSummary","missingWordSummary","push","status","InteractiveAnswerStatus","markedSummary","pendingSummary","QuestionResultsSummary","summaryMethod","getQuestionSummary","maxResponseCount","getBarClassName","width","height","SelectedInteractionEmptyState","emptyStateUrl","QuestionTable","showAnswersInTable","setSortBy","interactive","refreshData","flattenedInteractions","questionNumbers","interactions","questionNumber","resultsSummary","sorted","reverse","useGetTableData","refreshTable","selectedInteraction","selectedInteractionId","Header","accessor","Cell","containerClassName","PercentageIndicator","percentage","sortDescFirst","sortType","ScrollHelper","AppRouteHelper","interactionId","merge","selectQuestionImageUrl","PartialInteractiveInsightsQuestions","InteractiveInsightsQuestions","showMarkConfirmationPopup","setShowMarkConfirmationPopup","interactiveMetadata","hasDataLoaded","config","isFetching","ImageUrls","smartCount"],"sourceRoot":""}
|