@instructure/quiz-core 20.28.0 → 20.28.1-snapshot.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +4671 -0
  2. package/es/common/actions/analyses.js +25 -1
  3. package/es/common/reducers/analyses.js +14 -2
  4. package/es/common/selectors/analyses.js +13 -0
  5. package/es/index.js +1 -0
  6. package/es/reporting/api/fetchStudentAnalyses.js +30 -0
  7. package/es/reporting/api/getAnalysesExport.js +7 -4
  8. package/es/reporting/api/getAnalysesStatus.js +7 -4
  9. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnalysisMetric/presenter.js +1 -1
  10. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnalysisPopoverMetric/presenter.js +1 -1
  11. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/AggregationType/presenter.js +1 -1
  12. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/ChoiceType/presenter.js +1 -1
  13. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/LegacyChoiceType/presenter.js +1 -1
  14. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/MatchingType/CategorizationType.js +1 -1
  15. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/MatchingType/MatchingType.js +1 -1
  16. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/MatchingType/MatchingTypeTable/presenter.js +1 -1
  17. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/MatchingType/OrderingType.js +1 -1
  18. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/NumericType/ChoiceTypeWithInfo/presenter.js +1 -1
  19. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/NumericType/presenter.js +1 -1
  20. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/RichFillBlankType/ChoiceGroupTypeTable/presenter.js +1 -1
  21. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/RichFillBlankType/presenter.js +1 -1
  22. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/ScoreDistributionType/Table/index.js +1 -1
  23. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/ScoreDistributionType/index.js +1 -1
  24. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/presenter.js +1 -1
  25. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/shared/AggregationTable/presenter.js +1 -1
  26. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/shared/ChoiceTypeTable/presenter.js +1 -1
  27. package/es/reporting/components/resources/NewQuizAndItemAnalysis/ExportButton/index.js +6 -1
  28. package/es/reporting/components/resources/NewQuizAndItemAnalysis/NewItemAnalysis/presenter.js +1 -1
  29. package/es/reporting/components/resources/NewQuizAndItemAnalysis/NewQuizAnalysis/presenter.js +1 -1
  30. package/es/reporting/components/resources/NewQuizAndItemAnalysis/ReportCard/presenter.js +2 -2
  31. package/es/reporting/components/resources/NewQuizAndItemAnalysis/fetchReports.js +1 -1
  32. package/es/reporting/components/resources/NewQuizAndItemAnalysis/fetchReportsStatus.js +1 -1
  33. package/es/reporting/components/resources/NewQuizAndItemAnalysis/presenter.js +3 -3
  34. package/es/reporting/components/resources/NewQuizAndItemAnalysis/withAnalysisState.js +2 -2
  35. package/es/reporting/components/resources/NewQuizAndItemAnalysis/withAnalysisStatePresenter.js +5 -5
  36. package/es/reporting/components/resources/StudentAnalysis/ReportCard/index.js +3 -0
  37. package/es/reporting/components/resources/StudentAnalysis/ReportCard/presenter.js +164 -0
  38. package/es/reporting/components/resources/StudentAnalysis/ReportCard/styles.js +41 -0
  39. package/es/reporting/components/resources/StudentAnalysis/ReportCard/theme.js +12 -0
  40. package/es/reporting/components/resources/StudentAnalysis/fetchReport.js +48 -0
  41. package/es/reporting/components/resources/StudentAnalysis/fetchReportStatus.js +42 -0
  42. package/es/reporting/components/resources/StudentAnalysis/withStudentAnalysisReportState.js +39 -0
  43. package/es/reporting/components/resources/StudentAnalysis/withStudentAnalysisReportStatePresenter.js +222 -0
  44. package/es/reporting/components/resources/common/ExportButton/index.js +24 -0
  45. package/es/reporting/components/resources/{NewQuizAndItemAnalysis → common}/errorCodes.js +2 -2
  46. package/es/reporting/components/resources/{NewQuizAndItemAnalysis → common}/errorMessages.js +1 -1
  47. package/es/reporting/components/resources/{NewQuizAndItemAnalysis → common}/exportReports.js +4 -3
  48. package/es/reporting/components/resources/{NewQuizAndItemAnalysis → common}/propTypes.js +3 -0
  49. package/lib/common/actions/analyses.js +28 -0
  50. package/lib/common/reducers/analyses.js +18 -2
  51. package/lib/common/selectors/analyses.js +18 -1
  52. package/lib/index.js +106 -98
  53. package/lib/reporting/api/fetchStudentAnalyses.js +38 -0
  54. package/lib/reporting/api/getAnalysesExport.js +7 -4
  55. package/lib/reporting/api/getAnalysesStatus.js +7 -4
  56. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnalysisMetric/presenter.js +1 -1
  57. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnalysisPopoverMetric/presenter.js +1 -1
  58. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/AggregationType/presenter.js +1 -1
  59. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/ChoiceType/presenter.js +1 -1
  60. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/LegacyChoiceType/presenter.js +1 -1
  61. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/MatchingType/CategorizationType.js +1 -1
  62. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/MatchingType/MatchingType.js +1 -1
  63. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/MatchingType/MatchingTypeTable/presenter.js +1 -1
  64. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/MatchingType/OrderingType.js +1 -1
  65. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/NumericType/ChoiceTypeWithInfo/presenter.js +1 -1
  66. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/NumericType/presenter.js +1 -1
  67. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/RichFillBlankType/ChoiceGroupTypeTable/presenter.js +1 -1
  68. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/RichFillBlankType/presenter.js +1 -1
  69. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/ScoreDistributionType/Table/index.js +1 -1
  70. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/ScoreDistributionType/index.js +1 -1
  71. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/presenter.js +1 -1
  72. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/shared/AggregationTable/presenter.js +1 -1
  73. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/shared/ChoiceTypeTable/presenter.js +1 -1
  74. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/ExportButton/index.js +5 -1
  75. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/NewItemAnalysis/presenter.js +1 -1
  76. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/NewQuizAnalysis/presenter.js +1 -1
  77. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/ReportCard/presenter.js +2 -2
  78. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/fetchReports.js +1 -1
  79. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/fetchReportsStatus.js +1 -1
  80. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/presenter.js +3 -3
  81. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/withAnalysisState.js +2 -3
  82. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/withAnalysisStatePresenter.js +5 -5
  83. package/lib/reporting/components/resources/StudentAnalysis/ReportCard/index.js +11 -0
  84. package/lib/reporting/components/resources/StudentAnalysis/ReportCard/presenter.js +172 -0
  85. package/lib/reporting/components/resources/StudentAnalysis/ReportCard/styles.js +49 -0
  86. package/lib/reporting/components/resources/StudentAnalysis/ReportCard/theme.js +19 -0
  87. package/lib/reporting/components/resources/StudentAnalysis/fetchReport.js +56 -0
  88. package/lib/reporting/components/resources/StudentAnalysis/fetchReportStatus.js +50 -0
  89. package/lib/reporting/components/resources/StudentAnalysis/withStudentAnalysisReportState.js +46 -0
  90. package/lib/reporting/components/resources/StudentAnalysis/withStudentAnalysisReportStatePresenter.js +231 -0
  91. package/lib/reporting/components/resources/common/ExportButton/index.js +32 -0
  92. package/lib/reporting/components/resources/{NewQuizAndItemAnalysis → common}/errorCodes.js +1 -1
  93. package/lib/reporting/components/resources/{NewQuizAndItemAnalysis → common}/errorMessages.js +3 -3
  94. package/lib/reporting/components/resources/{NewQuizAndItemAnalysis → common}/exportReports.js +4 -3
  95. package/lib/reporting/components/resources/{NewQuizAndItemAnalysis → common}/propTypes.js +5 -1
  96. package/package.json +11 -10
  97. /package/es/reporting/components/resources/{NewQuizAndItemAnalysis → common}/AnalysisUpdateDate/index.js +0 -0
  98. /package/es/reporting/components/resources/{NewQuizAndItemAnalysis → common}/generateReports.js +0 -0
  99. /package/es/reporting/components/resources/{NewQuizAndItemAnalysis → common}/utils.js +0 -0
  100. /package/lib/reporting/components/resources/{NewQuizAndItemAnalysis → common}/AnalysisUpdateDate/index.js +0 -0
  101. /package/lib/reporting/components/resources/{NewQuizAndItemAnalysis → common}/generateReports.js +0 -0
  102. /package/lib/reporting/components/resources/{NewQuizAndItemAnalysis → common}/utils.js +0 -0
@@ -0,0 +1,164 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/esm/createClass";
3
+ import _inherits from "@babel/runtime/helpers/esm/inherits";
4
+ import _createSuper from "@babel/runtime/helpers/esm/createSuper";
5
+ var _dec, _class, _StudentAnalysisReportCardPresenter;
6
+ /** @jsx jsx */
7
+ import { Component } from 'react';
8
+ import { Text } from '@instructure/ui-text';
9
+ import { Link } from '@instructure/ui-link';
10
+ import { Flex } from '@instructure/ui-flex';
11
+ import { ScreenReaderContent } from '@instructure/ui-a11y-content';
12
+ import { withStyle, jsx } from '@instructure/emotion';
13
+ import PropTypes from 'prop-types';
14
+ import t from '@instructure/quiz-i18n/es/format-message';
15
+ import Card from "../../../../../common/components/shared/Card/index.js";
16
+ import { generateStyle } from "./styles.js";
17
+ import { generateComponentTheme } from "./theme.js";
18
+ import { ExportButton } from "../../common/ExportButton/index.js";
19
+ import Spinner from "../../../../../common/components/shared/spinner/Spinner.js";
20
+ import { STUDENT_ANALYSES } from '@instructure/quiz-common';
21
+ import { studentAnalysesPropType } from "../../common/propTypes.js";
22
+ import { AnalysisUpdateDate } from "../../common/AnalysisUpdateDate/index.js";
23
+ export var StudentAnalysisReportCardPresenter = (_dec = withStyle(generateStyle, generateComponentTheme), _dec(_class = (_StudentAnalysisReportCardPresenter = /*#__PURE__*/function (_Component) {
24
+ _inherits(StudentAnalysisReportCardPresenter, _Component);
25
+ var _super = _createSuper(StudentAnalysisReportCardPresenter);
26
+ function StudentAnalysisReportCardPresenter() {
27
+ var _this;
28
+ _classCallCheck(this, StudentAnalysisReportCardPresenter);
29
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
30
+ args[_key] = arguments[_key];
31
+ }
32
+ _this = _super.call.apply(_super, [this].concat(args));
33
+ _this.renderSpinner = function (mainText) {
34
+ return jsx("div", {
35
+ css: _this.props.styles.emptyCardBodyContainer
36
+ }, jsx(Flex, {
37
+ direction: "row"
38
+ }, jsx(Flex.Item, null, jsx(Spinner, {
39
+ size: "x-small",
40
+ color: "brand",
41
+ minHeight: "0",
42
+ mainText: mainText,
43
+ fontSize: "x-small",
44
+ "data-automation": "sdk-new-sa-report-card-spinner"
45
+ }))));
46
+ };
47
+ _this.handleExport = function (_event) {
48
+ _this.props.exportReport('csv', 'last_attempt', STUDENT_ANALYSES);
49
+ };
50
+ _this.handleGeneration = function (_event) {
51
+ _this.props.generateReport('last_attempt', STUDENT_ANALYSES);
52
+ };
53
+ _this.renderExportButton = function () {
54
+ var _this$props = _this.props,
55
+ studentAnalyses = _this$props.studentAnalyses,
56
+ generationInProgress = _this$props.generationInProgress;
57
+ return jsx(ExportButton, {
58
+ enabled: !generationInProgress && studentAnalyses,
59
+ handleExport: _this.handleExport
60
+ });
61
+ };
62
+ _this.renderGenerateReportButton = function () {
63
+ return jsx(Link, {
64
+ onClick: _this.handleGeneration,
65
+ role: "button",
66
+ "data-automation": "sdk-new-sa-report-card-generate-report-button"
67
+ }, jsx(ScreenReaderContent, null, t('Generate Student Analysis Report')), jsx(Text, {
68
+ size: "small",
69
+ "aria-hidden": "true"
70
+ }, t('Generate Report')));
71
+ };
72
+ _this.renderReportCardHeader = function () {
73
+ var _this$props2 = _this.props,
74
+ name = _this$props2.name,
75
+ exportEnabled = _this$props2.exportEnabled,
76
+ fetchInProgress = _this$props2.fetchInProgress;
77
+ return jsx("div", {
78
+ css: _this.props.styles.titleContainer
79
+ }, jsx(Flex, {
80
+ direction: "row",
81
+ wrap: "wrap",
82
+ justifyItems: "space-between"
83
+ }, jsx(Flex.Item, null, jsx(Text, {
84
+ size: "medium",
85
+ weight: "bold"
86
+ }, name)), exportEnabled && !fetchInProgress && jsx(Flex.Item, null, _this.renderExportButton())));
87
+ };
88
+ _this.renderReportCardFooter = function () {
89
+ var _this$props3 = _this.props,
90
+ generationInProgress = _this$props3.generationInProgress,
91
+ analysisError = _this$props3.analysisError;
92
+ return jsx("div", {
93
+ css: _this.props.styles.emptyCardBodyContainer
94
+ }, jsx(Flex, {
95
+ direction: "row",
96
+ justifyItems: "space-between"
97
+ }, jsx(Flex.Item, {
98
+ shouldShrink: true,
99
+ size: analysisError && !generationInProgress ? '40%' : null
100
+ }, analysisError && !generationInProgress && jsx(Text, {
101
+ size: "x-small",
102
+ weight: "bold",
103
+ color: "danger"
104
+ }, analysisError)), jsx(Flex.Item, {
105
+ shouldShrink: analysisError && !generationInProgress
106
+ }, generationInProgress ? _this.renderSpinner(t('Generation In Progress')) : _this.renderGenerateReportButton())));
107
+ };
108
+ _this.renderDateBlock = function () {
109
+ var studentAnalyses = _this.props.studentAnalyses;
110
+ return jsx("div", {
111
+ css: _this.props.styles.studentAnalysesSummary
112
+ }, jsx(Flex, {
113
+ direction: "row",
114
+ justifyItems: "space-between"
115
+ }, jsx("div", {
116
+ css: _this.props.styles.dateContainer
117
+ }, jsx(AnalysisUpdateDate, {
118
+ date: studentAnalyses.created_timestamp,
119
+ multiline: true
120
+ }))));
121
+ };
122
+ return _this;
123
+ }
124
+ _createClass(StudentAnalysisReportCardPresenter, [{
125
+ key: "componentDidMount",
126
+ value: function componentDidMount() {
127
+ this.props.makeStyles();
128
+ }
129
+ }, {
130
+ key: "componentDidUpdate",
131
+ value: function componentDidUpdate() {
132
+ this.props.makeStyles();
133
+ }
134
+ }, {
135
+ key: "render",
136
+ value: function render() {
137
+ var _this$props4 = this.props,
138
+ studentAnalyses = _this$props4.studentAnalyses,
139
+ fetchInProgress = _this$props4.fetchInProgress,
140
+ styles = _this$props4.styles;
141
+ return jsx(Card, {
142
+ css: styles.reportCard,
143
+ customStyles: styles.reportCard
144
+ }, this.renderReportCardHeader(), !fetchInProgress && studentAnalyses && this.renderDateBlock(), fetchInProgress && this.renderSpinner(), !fetchInProgress && this.renderReportCardFooter());
145
+ }
146
+ }]);
147
+ StudentAnalysisReportCardPresenter.displayName = "StudentAnalysisReportCardPresenter";
148
+ return StudentAnalysisReportCardPresenter;
149
+ }(Component), _StudentAnalysisReportCardPresenter.propTypes = {
150
+ name: PropTypes.node,
151
+ studentAnalyses: studentAnalysesPropType,
152
+ fetchInProgress: PropTypes.bool.isRequired,
153
+ generationInProgress: PropTypes.bool.isRequired,
154
+ exportEnabled: PropTypes.bool.isRequired,
155
+ analysisError: PropTypes.string,
156
+ generateReport: PropTypes.func.isRequired,
157
+ exportReport: PropTypes.func.isRequired,
158
+ styles: PropTypes.object,
159
+ makeStyles: PropTypes.func
160
+ }, _StudentAnalysisReportCardPresenter.defaultProps = {
161
+ studentAnalyses: void 0,
162
+ analysisError: void 0,
163
+ generationInProgress: void 0
164
+ }, _StudentAnalysisReportCardPresenter)) || _class);
@@ -0,0 +1,41 @@
1
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
3
+ export var generateStyle = function generateStyle(componentTheme, props) {
4
+ var msMaxWidth = 'max-width: 25rem';
5
+ var mq = "@media only screen and (".concat(msMaxWidth, ")");
6
+ return {
7
+ reportCard: _objectSpread(_defineProperty({
8
+ width: componentTheme.cardWidth,
9
+ padding: componentTheme.cardPadding,
10
+ margin: componentTheme.cardMargin,
11
+ display: 'inline-flex',
12
+ flexDirection: 'column'
13
+ }, mq, {
14
+ width: 'initial',
15
+ maxWidth: componentTheme.cardWidth
16
+ }), !props.studentAnalyses && !props.analysisError && _defineProperty({
17
+ height: componentTheme.cardHeight
18
+ }, mq, {
19
+ height: 'initial'
20
+ })),
21
+ studentAnalysesSummary: {
22
+ borderBottom: "1px solid ".concat(componentTheme.quizSummaryBorderBottomColor),
23
+ paddingBottom: '15px',
24
+ marginBottom: '15px'
25
+ },
26
+ emptyCardBodyContainer: {
27
+ display: 'flex',
28
+ justifyContent: 'flex-end',
29
+ alignItems: 'flex-end',
30
+ alignSelf: 'flex-end',
31
+ height: '100%'
32
+ },
33
+ dateContainer: {
34
+ maxWidth: '160px',
35
+ paddingRight: '10px'
36
+ },
37
+ titleContainer: {
38
+ paddingBottom: '15px'
39
+ }
40
+ };
41
+ };
@@ -0,0 +1,12 @@
1
+ export var generateComponentTheme = function generateComponentTheme(_ref) {
2
+ var spacing = _ref.spacing,
3
+ colors = _ref.colors;
4
+ return {
5
+ metricsPadding: spacing.medium,
6
+ cardHeight: '6rem',
7
+ cardWidth: '19.5rem',
8
+ cardPadding: spacing.medium,
9
+ cardMargin: spacing.xSmall,
10
+ quizSummaryBorderBottomColor: colors.tiara
11
+ };
12
+ };
@@ -0,0 +1,48 @@
1
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
+ import { getFailedToFetchReports, getLastReportGenerationFailed } from "../common/errorMessages.js";
4
+ export var fetchReport = /*#__PURE__*/function () {
5
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
6
+ var activeQuizId, setFetchInProgress, setStudentAnalyses, setStatusPollingInProgress, setAnalysisError, setGenerationInProgress, addError, fetchStudentAnalyses, setAnalysisFetchError, getErrorMessageForCode, studentAnalyses, isAnalysisInProgress, isAnalysisFailed, analysisErrorCode;
7
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
8
+ while (1) {
9
+ switch (_context.prev = _context.next) {
10
+ case 0:
11
+ activeQuizId = _ref.activeQuizId, setFetchInProgress = _ref.setFetchInProgress, setStudentAnalyses = _ref.setStudentAnalyses, setStatusPollingInProgress = _ref.setStatusPollingInProgress, setAnalysisError = _ref.setAnalysisError, setGenerationInProgress = _ref.setGenerationInProgress, addError = _ref.addError, fetchStudentAnalyses = _ref.fetchStudentAnalyses, setAnalysisFetchError = _ref.setAnalysisFetchError, getErrorMessageForCode = _ref.getErrorMessageForCode;
12
+ _context.prev = 1;
13
+ setAnalysisFetchError(false);
14
+ setFetchInProgress(true);
15
+ _context.next = 6;
16
+ return fetchStudentAnalyses(activeQuizId);
17
+ case 6:
18
+ studentAnalyses = _context.sent;
19
+ isAnalysisInProgress = studentAnalyses.new_analysis_in_progress;
20
+ isAnalysisFailed = studentAnalyses.last_analysis_failed;
21
+ analysisErrorCode = studentAnalyses.last_analysis_failed_error_code;
22
+ setGenerationInProgress(isAnalysisInProgress);
23
+ setStatusPollingInProgress(isAnalysisInProgress);
24
+ setStudentAnalyses(studentAnalyses.last_successful_analysis);
25
+ setAnalysisError(isAnalysisFailed ? getErrorMessageForCode(analysisErrorCode, getLastReportGenerationFailed()) : null);
26
+ _context.next = 21;
27
+ break;
28
+ case 16:
29
+ _context.prev = 16;
30
+ _context.t0 = _context["catch"](1);
31
+ setStudentAnalyses(null);
32
+ setAnalysisFetchError(true);
33
+ addError(getFailedToFetchReports());
34
+ case 21:
35
+ _context.prev = 21;
36
+ setFetchInProgress(false);
37
+ return _context.finish(21);
38
+ case 24:
39
+ case "end":
40
+ return _context.stop();
41
+ }
42
+ }
43
+ }, _callee, null, [[1, 16, 21, 24]]);
44
+ }));
45
+ return function fetchReport(_x) {
46
+ return _ref2.apply(this, arguments);
47
+ };
48
+ }();
@@ -0,0 +1,42 @@
1
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
+ import { getFailedToFetchReports } from "../common/errorMessages.js";
4
+ import { STUDENT_ANALYSES } from '@instructure/quiz-common';
5
+ export var fetchReportStatus = /*#__PURE__*/function () {
6
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
7
+ var activeQuizId, addError, fetchAnalysesStatus, instrumentedFetchReports, setStatusPollingInProgress, setGenerationInProgress, status, isReportGenerationReady;
8
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
9
+ while (1) {
10
+ switch (_context.prev = _context.next) {
11
+ case 0:
12
+ activeQuizId = _ref.activeQuizId, addError = _ref.addError, fetchAnalysesStatus = _ref.fetchAnalysesStatus, instrumentedFetchReports = _ref.instrumentedFetchReports, setStatusPollingInProgress = _ref.setStatusPollingInProgress, setGenerationInProgress = _ref.setGenerationInProgress;
13
+ _context.prev = 1;
14
+ _context.next = 4;
15
+ return fetchAnalysesStatus(activeQuizId, 'last_attempt', STUDENT_ANALYSES);
16
+ case 4:
17
+ status = _context.sent;
18
+ isReportGenerationReady = !status.student_analyses_in_progress;
19
+ if (isReportGenerationReady) {
20
+ instrumentedFetchReports();
21
+ setStatusPollingInProgress(false);
22
+ setGenerationInProgress(false);
23
+ }
24
+ return _context.abrupt("return", isReportGenerationReady);
25
+ case 10:
26
+ _context.prev = 10;
27
+ _context.t0 = _context["catch"](1);
28
+ addError(getFailedToFetchReports());
29
+ setStatusPollingInProgress(false);
30
+ setGenerationInProgress(false);
31
+ return _context.abrupt("return", true);
32
+ case 16:
33
+ case "end":
34
+ return _context.stop();
35
+ }
36
+ }
37
+ }, _callee, null, [[1, 10]]);
38
+ }));
39
+ return function fetchReportStatus(_x) {
40
+ return _ref2.apply(this, arguments);
41
+ };
42
+ }();
@@ -0,0 +1,39 @@
1
+ import { connect } from "../../../../common/react-redux.js";
2
+ import { featureOn } from "../../../../common/util/featureCheck.js";
3
+ import { withStudentAnalysisReportStatePresenter } from "./withStudentAnalysisReportStatePresenter.js";
4
+ import { bindActionCreators, compose } from 'redux';
5
+ import { getStudentAnalyses, getStudentAnalysisFetchInProgress, getStudentAnalysisGenerationInProgress, getAnalysisError, getStudentAnalysisStatusPollingInProgress } from "../../../../common/selectors/analyses.js";
6
+ import { setStudentAnalyses, setStudentAnalysisFetchInProgress, setStudentAnalysesGenerationInProgress, setAnalysisError, setStudentAnalysisStatusPollingInProgress } from "../../../../common/actions/analyses.js";
7
+ import { getAnalysesStatus as fetchAnalysesStatus } from "../../../api/getAnalysesStatus.js";
8
+ import { fetchStudentAnalyses } from "../../../api/fetchStudentAnalyses.js";
9
+ import { addError } from "../../../../common/actions/alerts.js";
10
+ import { getActiveQuizId } from "../../../../common/selectors/quizzes.js";
11
+ import { getAnalysesExport } from "../../../api/getAnalysesExport.js";
12
+ var DEFAULT_POLLING_INTERVAL = 3000;
13
+ var mapStateToProps = function mapStateToProps(state, ownProps) {
14
+ return {
15
+ studentAnalyses: getStudentAnalyses(state),
16
+ fetchInProgress: getStudentAnalysisFetchInProgress(state),
17
+ generationInProgress: getStudentAnalysisGenerationInProgress(state),
18
+ statusPollingInProgress: getStudentAnalysisStatusPollingInProgress(state),
19
+ analysisError: getAnalysisError(state),
20
+ activeQuizId: ownProps.activeQuizId || getActiveQuizId(state),
21
+ getAnalysesExport: getAnalysesExport,
22
+ fetchStudentAnalyses: fetchStudentAnalyses,
23
+ fetchAnalysesStatus: fetchAnalysesStatus,
24
+ pollingInterval: ownProps.pollingInterval || DEFAULT_POLLING_INTERVAL,
25
+ exportEnabled: featureOn('student_analysis_csv')
26
+ };
27
+ };
28
+ var mapDispatchToProps = function mapDispatchToProps(dispatch, ownProps) {
29
+ return {
30
+ setStudentAnalyses: bindActionCreators(setStudentAnalyses, dispatch),
31
+ setFetchInProgress: bindActionCreators(setStudentAnalysisFetchInProgress, dispatch),
32
+ setGenerationInProgress: bindActionCreators(setStudentAnalysesGenerationInProgress, dispatch),
33
+ setAnalysisError: bindActionCreators(setAnalysisError, dispatch),
34
+ addError: ownProps.addError || bindActionCreators(addError, dispatch),
35
+ setStatusPollingInProgress: bindActionCreators(setStudentAnalysisStatusPollingInProgress, dispatch)
36
+ };
37
+ };
38
+ var withStudentAnalysisReportState = compose(connect(mapStateToProps, mapDispatchToProps), withStudentAnalysisReportStatePresenter);
39
+ export default withStudentAnalysisReportState;
@@ -0,0 +1,222 @@
1
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
4
+ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
5
+ import React, { useEffect, useState } from 'react';
6
+ import PropTypes from 'prop-types';
7
+ import { generateReports as triggerReportGeneration } from "../common/generateReports.js";
8
+ import { exportReports as triggerReportExport } from "../common/exportReports.js";
9
+ import { getErrorMessageForCode } from "../common/errorCodes.js";
10
+ import { saveFile } from "../common/utils.js";
11
+ import { fetchReport } from "./fetchReport.js";
12
+ import { fetchReportStatus } from "./fetchReportStatus.js";
13
+ import { STUDENT_ANALYSES } from '@instructure/quiz-common';
14
+ import { studentAnalysesPropType } from "../common/propTypes.js";
15
+ export var withStudentAnalysisReportStatePresenter = function withStudentAnalysisReportStatePresenter(OriginalComponent) {
16
+ var StudentAnalysisReportStatePresenter = function StudentAnalysisReportStatePresenter(_ref) {
17
+ var studentAnalyses = _ref.studentAnalyses,
18
+ fetchInProgress = _ref.fetchInProgress,
19
+ generationInProgress = _ref.generationInProgress,
20
+ analysisError = _ref.analysisError,
21
+ setStudentAnalyses = _ref.setStudentAnalyses,
22
+ addError = _ref.addError,
23
+ setFetchInProgress = _ref.setFetchInProgress,
24
+ setGenerationInProgress = _ref.setGenerationInProgress,
25
+ setAnalysisError = _ref.setAnalysisError,
26
+ activeQuizId = _ref.activeQuizId,
27
+ generateAnalysis = _ref.generateAnalysis,
28
+ fetchStudentAnalyses = _ref.fetchStudentAnalyses,
29
+ getAnalysesExport = _ref.getAnalysesExport,
30
+ fetchAnalysesStatus = _ref.fetchAnalysesStatus,
31
+ statusPollingInProgress = _ref.statusPollingInProgress,
32
+ setStatusPollingInProgress = _ref.setStatusPollingInProgress,
33
+ pollingInterval = _ref.pollingInterval,
34
+ disableReportsCache = _ref.disableReportsCache,
35
+ passThroughProps = _objectWithoutProperties(_ref, ["studentAnalyses", "fetchInProgress", "generationInProgress", "analysisError", "setStudentAnalyses", "addError", "setFetchInProgress", "setGenerationInProgress", "setAnalysisError", "activeQuizId", "generateAnalysis", "fetchStudentAnalyses", "getAnalysesExport", "fetchAnalysesStatus", "statusPollingInProgress", "setStatusPollingInProgress", "pollingInterval", "disableReportsCache"]);
36
+ StudentAnalysisReportStatePresenter.displayName = "StudentAnalysisReportStatePresenter(".concat(OriginalComponent.displayName || OriginalComponent.name, ")");
37
+ var _useState = useState(false),
38
+ _useState2 = _slicedToArray(_useState, 2),
39
+ analysisFetchError = _useState2[0],
40
+ setAnalysisFetchError = _useState2[1];
41
+ var instrumentedFetchReports = function instrumentedFetchReports() {
42
+ return fetchReport({
43
+ activeQuizId: activeQuizId,
44
+ addError: addError,
45
+ fetchStudentAnalyses: fetchStudentAnalyses,
46
+ setAnalysisError: setAnalysisError,
47
+ setStatusPollingInProgress: setStatusPollingInProgress,
48
+ setGenerationInProgress: setGenerationInProgress,
49
+ setFetchInProgress: setFetchInProgress,
50
+ setStudentAnalyses: setStudentAnalyses,
51
+ getErrorMessageForCode: getErrorMessageForCode,
52
+ setAnalysisFetchError: setAnalysisFetchError
53
+ });
54
+ };
55
+ var instrumentedStatusFetching = function instrumentedStatusFetching() {
56
+ return fetchReportStatus({
57
+ activeQuizId: activeQuizId,
58
+ addError: addError,
59
+ setGenerationInProgress: setGenerationInProgress,
60
+ setStatusPollingInProgress: setStatusPollingInProgress,
61
+ fetchAnalysesStatus: fetchAnalysesStatus,
62
+ instrumentedFetchReports: instrumentedFetchReports
63
+ });
64
+ };
65
+ function generateReport() {
66
+ return _generateReport.apply(this, arguments);
67
+ }
68
+ function _generateReport() {
69
+ _generateReport = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
70
+ var filter,
71
+ analysisType,
72
+ generationConfig,
73
+ _args3 = arguments;
74
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
75
+ while (1) {
76
+ switch (_context3.prev = _context3.next) {
77
+ case 0:
78
+ filter = _args3.length > 0 && _args3[0] !== void 0 ? _args3[0] : 'last_attempt';
79
+ analysisType = _args3.length > 1 ? _args3[1] : void 0;
80
+ generationConfig = {
81
+ filter: filter,
82
+ analysisType: analysisType,
83
+ setGenerationInProgress: setGenerationInProgress,
84
+ setStatusPollingInProgress: setStatusPollingInProgress,
85
+ generateAnalysis: generateAnalysis,
86
+ addError: addError
87
+ };
88
+ _context3.next = 5;
89
+ return triggerReportGeneration(generationConfig);
90
+ case 5:
91
+ case "end":
92
+ return _context3.stop();
93
+ }
94
+ }
95
+ }, _callee3);
96
+ }));
97
+ return _generateReport.apply(this, arguments);
98
+ }
99
+ function exportReport(_x) {
100
+ return _exportReport.apply(this, arguments);
101
+ }
102
+ function _exportReport() {
103
+ _exportReport = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(format) {
104
+ var filter,
105
+ analysisType,
106
+ exportConfig,
107
+ _args4 = arguments;
108
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
109
+ while (1) {
110
+ switch (_context4.prev = _context4.next) {
111
+ case 0:
112
+ filter = _args4.length > 1 && _args4[1] !== void 0 ? _args4[1] : 'last_attempt';
113
+ analysisType = _args4.length > 2 && _args4[2] !== void 0 ? _args4[2] : STUDENT_ANALYSES;
114
+ exportConfig = {
115
+ getAnalysesExport: getAnalysesExport,
116
+ format: format,
117
+ filter: filter,
118
+ activeQuizId: activeQuizId,
119
+ addError: addError,
120
+ saveFile: saveFile,
121
+ analysisType: analysisType
122
+ };
123
+ _context4.next = 5;
124
+ return triggerReportExport(exportConfig);
125
+ case 5:
126
+ case "end":
127
+ return _context4.stop();
128
+ }
129
+ }
130
+ }, _callee4);
131
+ }));
132
+ return _exportReport.apply(this, arguments);
133
+ }
134
+ useEffect(function () {
135
+ var fetchIfNeeded = /*#__PURE__*/function () {
136
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
137
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
138
+ while (1) {
139
+ switch (_context.prev = _context.next) {
140
+ case 0:
141
+ if (!(!studentAnalyses || disableReportsCache)) {
142
+ _context.next = 3;
143
+ break;
144
+ }
145
+ _context.next = 3;
146
+ return instrumentedFetchReports();
147
+ case 3:
148
+ case "end":
149
+ return _context.stop();
150
+ }
151
+ }
152
+ }, _callee);
153
+ }));
154
+ return function fetchIfNeeded() {
155
+ return _ref2.apply(this, arguments);
156
+ };
157
+ }();
158
+ fetchIfNeeded();
159
+ }, []);
160
+ var recursiveInstrumentedStatusFetching = /*#__PURE__*/function () {
161
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
162
+ var isReportGenerationReady;
163
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
164
+ while (1) {
165
+ switch (_context2.prev = _context2.next) {
166
+ case 0:
167
+ _context2.next = 2;
168
+ return instrumentedStatusFetching();
169
+ case 2:
170
+ isReportGenerationReady = _context2.sent;
171
+ !isReportGenerationReady && setTimeout(recursiveInstrumentedStatusFetching, pollingInterval);
172
+ case 4:
173
+ case "end":
174
+ return _context2.stop();
175
+ }
176
+ }
177
+ }, _callee2);
178
+ }));
179
+ return function recursiveInstrumentedStatusFetching() {
180
+ return _ref3.apply(this, arguments);
181
+ };
182
+ }();
183
+ useEffect(function () {
184
+ statusPollingInProgress && recursiveInstrumentedStatusFetching();
185
+ }, [statusPollingInProgress]);
186
+ return /*#__PURE__*/React.createElement(OriginalComponent, Object.assign({
187
+ studentAnalyses: studentAnalyses,
188
+ fetchInProgress: fetchInProgress,
189
+ generationInProgress: generationInProgress,
190
+ analysisError: analysisError,
191
+ exportReport: exportReport,
192
+ generateReport: generateReport,
193
+ analysisFetchError: analysisFetchError
194
+ }, passThroughProps));
195
+ };
196
+ StudentAnalysisReportStatePresenter.propTypes = {
197
+ studentAnalyses: studentAnalysesPropType,
198
+ fetchInProgress: PropTypes.bool.isRequired,
199
+ generationInProgress: PropTypes.bool.isRequired,
200
+ statusPollingInProgress: PropTypes.bool.isRequired,
201
+ analysisError: PropTypes.string,
202
+ setStudentAnalyses: PropTypes.func.isRequired,
203
+ setFetchInProgress: PropTypes.func.isRequired,
204
+ setGenerationInProgress: PropTypes.func.isRequired,
205
+ setAnalysisError: PropTypes.func.isRequired,
206
+ setStatusPollingInProgress: PropTypes.func.isRequired,
207
+ activeQuizId: PropTypes.string.isRequired,
208
+ fetchStudentAnalyses: PropTypes.func.isRequired,
209
+ fetchAnalysesStatus: PropTypes.func.isRequired,
210
+ getAnalysesExport: PropTypes.func.isRequired,
211
+ addError: PropTypes.func.isRequired,
212
+ pollingInterval: PropTypes.number.isRequired,
213
+ generateAnalysis: PropTypes.func.isRequired,
214
+ disableReportsCache: PropTypes.bool
215
+ };
216
+ StudentAnalysisReportStatePresenter.defaultProps = {
217
+ studentAnalyses: void 0,
218
+ analysisError: '',
219
+ disableReportsCache: false
220
+ };
221
+ return StudentAnalysisReportStatePresenter;
222
+ };
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import t from '@instructure/quiz-i18n/es/format-message';
4
+ import { Text } from '@instructure/ui-text';
5
+ import { Button } from '@instructure/ui-buttons';
6
+ export var ExportButton = function ExportButton(_ref) {
7
+ var enabled = _ref.enabled,
8
+ handleExport = _ref.handleExport;
9
+ return /*#__PURE__*/React.createElement(Button, {
10
+ color: enabled ? 'secondary' : 'primary-inverse',
11
+ interaction: enabled ? 'enabled' : 'disabled',
12
+ onClick: handleExport,
13
+ themeOverride: {
14
+ lineHeight: '24px'
15
+ },
16
+ "data-automation": "sdk-new-report-export-button"
17
+ }, /*#__PURE__*/React.createElement(Text, {
18
+ size: "medium"
19
+ }, t('Export CSV')));
20
+ };
21
+ ExportButton.propTypes = {
22
+ enabled: PropTypes.bool.isRequired,
23
+ handleExport: PropTypes.func.isRequired
24
+ };
@@ -1,4 +1,4 @@
1
- import { getReportGenerationFailure, getInsufficentSubmissionNumberError, getOngoingReportGenerationError, getMinimumThreeGradedSubmissionError, getNotEnoughDataAvailableError } from "./errorMessages.js";
1
+ import { getReportGenerationFailure, getInsufficientSubmissionNumberError, getOngoingReportGenerationError, getMinimumThreeGradedSubmissionError, getNotEnoughDataAvailableError } from "./errorMessages.js";
2
2
  import { DEFAULT_ALERT_TIME } from '@instructure/quiz-common';
3
3
  export var INSUFFICIENT_NUMBER_OF_SESSIONS = 'INSUFFICIENT_NUMBER_OF_SESSIONS';
4
4
  export var ANALYSIS_GENERATION_IN_PROGRESS = 'ANALYSIS_GENERATION_IN_PROGRESS';
@@ -9,7 +9,7 @@ export var getErrorMessageForCode = function getErrorMessageForCode(code) {
9
9
  var defaultMsg = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : null;
10
10
  switch (code) {
11
11
  case INSUFFICIENT_NUMBER_OF_SESSIONS:
12
- return getInsufficentSubmissionNumberError();
12
+ return getInsufficientSubmissionNumberError();
13
13
  case ANALYSIS_GENERATION_IN_PROGRESS:
14
14
  return getOngoingReportGenerationError();
15
15
  case GENERAL_ANALYSIS_ERROR:
@@ -11,7 +11,7 @@ export var getLastReportGenerationFailed = function getLastReportGenerationFaile
11
11
  export var getReportGenerationFailure = function getReportGenerationFailure() {
12
12
  return t('An error has occurred while generating this report. Please try again.');
13
13
  };
14
- export var getInsufficentSubmissionNumberError = function getInsufficentSubmissionNumberError() {
14
+ export var getInsufficientSubmissionNumberError = function getInsufficientSubmissionNumberError() {
15
15
  return t('There is not enough data available to generate this report. A minimum of 3 submissions is required to generate. Please try again when more submissions are available.');
16
16
  };
17
17
  export var getOngoingReportGenerationError = function getOngoingReportGenerationError() {
@@ -2,17 +2,18 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
2
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
3
  import { getFailedToExportReports } from "./errorMessages.js";
4
4
  import contentDisposition from 'content-disposition';
5
+ import { ITEM_ANALYSES } from '@instructure/quiz-common';
5
6
  export var exportReports = /*#__PURE__*/function () {
6
7
  var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
7
- var getAnalysesExport, activeQuizId, filter, format, saveFile, addError, response, dispositionHeader, disposition, filename, blob;
8
+ var getAnalysesExport, activeQuizId, filter, format, saveFile, addError, _ref$analysisType, analysisType, response, dispositionHeader, disposition, filename, blob;
8
9
  return _regeneratorRuntime.wrap(function _callee$(_context) {
9
10
  while (1) {
10
11
  switch (_context.prev = _context.next) {
11
12
  case 0:
12
- getAnalysesExport = _ref.getAnalysesExport, activeQuizId = _ref.activeQuizId, filter = _ref.filter, format = _ref.format, saveFile = _ref.saveFile, addError = _ref.addError;
13
+ getAnalysesExport = _ref.getAnalysesExport, activeQuizId = _ref.activeQuizId, filter = _ref.filter, format = _ref.format, saveFile = _ref.saveFile, addError = _ref.addError, _ref$analysisType = _ref.analysisType, analysisType = _ref$analysisType === void 0 ? ITEM_ANALYSES : _ref$analysisType;
13
14
  _context.prev = 1;
14
15
  _context.next = 4;
15
- return getAnalysesExport(activeQuizId, format, filter);
16
+ return getAnalysesExport(activeQuizId, format, filter, analysisType);
16
17
  case 4:
17
18
  response = _context.sent;
18
19
  dispositionHeader = response.headers.get('Content-Disposition');
@@ -26,6 +26,9 @@ export var quizAnalysisPropType = PropTypes.shape({
26
26
  average_attempts: PropTypes.number
27
27
  }).isRequired
28
28
  });
29
+ export var studentAnalysesPropType = PropTypes.shape({
30
+ created_timestamp: PropTypes.string.isRequired
31
+ });
29
32
  export var aggregateDetailPropType = PropTypes.shape({
30
33
  count: PropTypes.number.isRequired,
31
34
  percentage: PropTypes.number.isRequired