@instructure/quiz-core 18.7.1-alpha.0 → 18.7.1-rc.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 (33) hide show
  1. package/es/banks/components/BanksList/presenter.js +1 -1
  2. package/es/common/components/resources/stimulus/StimulusShowInfo/index.js +1 -1
  3. package/es/common/components/shared/TagDisplay/index.js +1 -1
  4. package/es/reporting/api/getAnalysesExport.js +2 -2
  5. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnalysisMetric/presenter.js +1 -1
  6. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnalysisPopoverMetric/presenter.js +1 -1
  7. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/ChoiceType/ChoiceTypeTableRow/presenter.js +4 -4
  8. package/es/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/shared/AggregationTable/presenter.js +3 -3
  9. package/es/reporting/components/resources/NewQuizAndItemAnalysis/ExportButton/index.js +40 -0
  10. package/es/reporting/components/resources/NewQuizAndItemAnalysis/MetricPopover/presenter.js +2 -2
  11. package/es/reporting/components/resources/NewQuizAndItemAnalysis/ReportCard/presenter.js +45 -12
  12. package/es/reporting/components/resources/NewQuizAndItemAnalysis/charts/ScoreDistribution/presenter.js +1 -1
  13. package/es/reporting/components/resources/NewQuizAndItemAnalysis/exportFormats.js +1 -0
  14. package/es/reporting/components/resources/NewQuizAndItemAnalysis/presenter.js +45 -15
  15. package/es/reporting/components/resources/NewQuizAndItemAnalysis/propTypes.js +22 -22
  16. package/es/reporting/components/resources/NewQuizAndItemAnalysis/withAnalysisState.js +3 -1
  17. package/lib/banks/components/BanksList/presenter.js +1 -1
  18. package/lib/common/components/resources/stimulus/StimulusShowInfo/index.js +1 -1
  19. package/lib/common/components/shared/TagDisplay/index.js +1 -1
  20. package/lib/reporting/api/getAnalysesExport.js +5 -5
  21. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnalysisMetric/presenter.js +1 -1
  22. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnalysisPopoverMetric/presenter.js +1 -1
  23. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/ChoiceType/ChoiceTypeTableRow/presenter.js +4 -4
  24. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/AnswerFrequencySummary/shared/AggregationTable/presenter.js +3 -3
  25. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/ExportButton/index.js +58 -0
  26. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/MetricPopover/presenter.js +2 -2
  27. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/ReportCard/presenter.js +47 -12
  28. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/charts/ScoreDistribution/presenter.js +1 -1
  29. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/exportFormats.js +8 -0
  30. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/presenter.js +47 -15
  31. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/propTypes.js +26 -26
  32. package/lib/reporting/components/resources/NewQuizAndItemAnalysis/withAnalysisState.js +4 -1
  33. package/package.json +56 -57
@@ -266,7 +266,7 @@ export var BanksList = (_dec = themeable(theme, styles), _dec(_class = (_temp =
266
266
  className: styles.bankTitle
267
267
  }, /*#__PURE__*/React.createElement(Link, {
268
268
  onClick: navigateToBank(bank.id),
269
- themeOverride: {
269
+ theme: {
270
270
  color: _this.theme.bankTitleLinkColor,
271
271
  hoverColor: _this.theme.bankTitleLinkHoverColor
272
272
  },
@@ -51,7 +51,7 @@ var StimulusShowInfo = /*#__PURE__*/function (_Component) {
51
51
  as: "h2",
52
52
  color: "primary",
53
53
  margin: "0 0 small",
54
- themeOverride: {
54
+ theme: {
55
55
  h2FontWeight: '700'
56
56
  }
57
57
  }, this.props.stimulus.title), instructions, /*#__PURE__*/React.createElement("div", {
@@ -54,7 +54,7 @@ export var TagDisplay = (_dec = themeable(theme, styles), _dec(_class = (_temp =
54
54
  className: styles.tags,
55
55
  "aria-label": t('question tags')
56
56
  }, visible, extra > 0 && /*#__PURE__*/React.createElement(Tag, {
57
- themeOverride: {
57
+ theme: {
58
58
  defaultBackground: '#FFFFFF'
59
59
  },
60
60
  text: /*#__PURE__*/React.createElement(AccessibleContent, {
@@ -1,6 +1,7 @@
1
1
  import _regeneratorRuntime from "@babel/runtime/regenerator";
2
2
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
3
  import Fetcher from "../../common/util/Fetcher.js";
4
+ import { csvFormat } from "../components/resources/NewQuizAndItemAnalysis/exportFormats.js";
4
5
 
5
6
  var getFetcher = function getFetcher(format) {
6
7
  var mimeType = formatsToMimeTypes.get(format);
@@ -13,14 +14,13 @@ var getFetcher = function getFetcher(format) {
13
14
  headers: {
14
15
  'Accept': mimeType
15
16
  },
16
- injectUserToken: true,
17
+ injectMissingUserToken: true,
17
18
  asyncResponseHandler: function asyncResponseHandler(response) {
18
19
  return response;
19
20
  }
20
21
  });
21
22
  };
22
23
 
23
- export var csvFormat = 'csv';
24
24
  var formatsToMimeTypes = new Map().set(csvFormat, 'text/csv');
25
25
  export var getAnalysesExport = /*#__PURE__*/function () {
26
26
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(quizId, format) {
@@ -43,7 +43,7 @@ export var AnalysisMetric = (_dec = themeable(theme, styles), _dec(_class = (_te
43
43
  "data-automation": dataAutomation,
44
44
  className: styles.metricWrapper
45
45
  }, /*#__PURE__*/React.createElement(Metric, {
46
- themeOverride: {
46
+ theme: {
47
47
  valueFontWeight: 500,
48
48
  padding: '0'
49
49
  },
@@ -51,7 +51,7 @@ export var AnalysisPopoverMetric = (_dec = themeable(theme, styles), _dec(_class
51
51
  popoverDescription = _this$props.popoverDescription,
52
52
  value = _this$props.value;
53
53
  return /*#__PURE__*/React.createElement(Metric, {
54
- themeOverride: {
54
+ theme: {
55
55
  valueFontWeight: 500,
56
56
  padding: '0'
57
57
  },
@@ -86,19 +86,19 @@ export var ChoiceTypeTableRow = (_dec = themeable(theme, styles), _dec(_class =
86
86
  return /*#__PURE__*/React.createElement(Table.Row, {
87
87
  key: _this.props.choiceIndex
88
88
  }, /*#__PURE__*/React.createElement(Table.Cell, {
89
- themeOverride: {
89
+ theme: {
90
90
  padding: '0px'
91
91
  }
92
92
  }, /*#__PURE__*/React.createElement(ScreenReaderContent, null, _this.answerLabel(correct)), _this.renderIcon(correct)), /*#__PURE__*/React.createElement(Table.RowHeader, {
93
- themeOverride: {
93
+ theme: {
94
94
  padding: cellPadding
95
95
  }
96
96
  }, _this.renderMiddleCell(correct, _this.extractChoiceText(choiceBody, correct))), /*#__PURE__*/React.createElement(Table.Cell, {
97
- themeOverride: {
97
+ theme: {
98
98
  padding: cellPadding
99
99
  }
100
100
  }, _this.renderMiddleCell(correct, _this.props.choice.count)), /*#__PURE__*/React.createElement(Table.Cell, {
101
- themeOverride: {
101
+ theme: {
102
102
  padding: cellPadding
103
103
  },
104
104
  textAlign: "center"
@@ -88,7 +88,7 @@ export var AggregationTable = (_dec = themeable(theme, styles), _dec(_class = (_
88
88
  return /*#__PURE__*/React.createElement(Table.Row, {
89
89
  key: key
90
90
  }, /*#__PURE__*/React.createElement(Table.RowHeader, {
91
- themeOverride: {
91
+ theme: {
92
92
  padding: '0px'
93
93
  }
94
94
  }, /*#__PURE__*/React.createElement(ScreenReaderContent, null, label), /*#__PURE__*/React.createElement(Flex, {
@@ -105,12 +105,12 @@ export var AggregationTable = (_dec = themeable(theme, styles), _dec(_class = (_
105
105
  }, /*#__PURE__*/React.createElement("div", {
106
106
  className: classNames(styles.labelWrapper)
107
107
  }, /*#__PURE__*/React.createElement(Text, null, label))))), /*#__PURE__*/React.createElement(Table.Cell, {
108
- themeOverride: {
108
+ theme: {
109
109
  padding: '0px'
110
110
  },
111
111
  textAlign: "center"
112
112
  }, /*#__PURE__*/React.createElement(Text, null, count)), /*#__PURE__*/React.createElement(Table.Cell, {
113
- themeOverride: {
113
+ theme: {
114
114
  padding: '0px'
115
115
  },
116
116
  textAlign: "center"
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import t from '@instructure/quiz-i18n/es/format-message';
4
+ import { quizAnalysisPropType } from "../propTypes.js";
5
+ import { Text } from '@instructure/ui-text';
6
+ import { Button } from '@instructure/ui-buttons';
7
+ export var ExportButton = function ExportButton(_ref) {
8
+ var quizAnalysis = _ref.quizAnalysis,
9
+ generationInProgress = _ref.generationInProgress,
10
+ handleExport = _ref.handleExport;
11
+
12
+ var renderExportButton = function renderExportButton(enabled) {
13
+ var interaction = enabled ? 'enabled' : 'disabled';
14
+ var color = enabled ? 'secondary' : 'primary-inverse';
15
+ return /*#__PURE__*/React.createElement(Button, {
16
+ color: color,
17
+ interaction: interaction,
18
+ onClick: handleExport,
19
+ theme: {
20
+ lineHeight: '24px'
21
+ }
22
+ }, /*#__PURE__*/React.createElement(Text, {
23
+ size: "medium"
24
+ }, t('Export CSV')));
25
+ };
26
+
27
+ if (generationInProgress || !quizAnalysis) {
28
+ return renderExportButton(false);
29
+ }
30
+
31
+ if (quizAnalysis) {
32
+ return renderExportButton(true);
33
+ }
34
+ };
35
+ ExportButton.propTypes = {
36
+ quizAnalysis: quizAnalysisPropType.isRequired,
37
+ generationInProgress: PropTypes.bool.isRequired,
38
+ handleExport: PropTypes.func.isRequired
39
+ };
40
+ export default ExportButton;
@@ -86,7 +86,7 @@ export var MetricPopover = (_dec = themeable(theme, styles), _dec(_class = (_tem
86
86
  className: styles.popoverTitle,
87
87
  level: "h3"
88
88
  }, _this.props.title)), /*#__PURE__*/React.createElement("div", null, _this.props.subtitle && /*#__PURE__*/React.createElement(Heading, {
89
- themeOverride: {
89
+ theme: {
90
90
  h5FontWeight: 700
91
91
  },
92
92
  level: "h5"
@@ -103,7 +103,7 @@ export var MetricPopover = (_dec = themeable(theme, styles), _dec(_class = (_tem
103
103
  value: function renderPopoverTrigger() {
104
104
  return /*#__PURE__*/React.createElement(IconButton, {
105
105
  size: "small",
106
- themeOverride: {
106
+ theme: {
107
107
  smallHeight: '18px',
108
108
  transform: 'translateY(-1px)'
109
109
  },
@@ -34,6 +34,8 @@ import AnalysisMetric from "../AnalysisMetric/index.js";
34
34
  import Spinner from "../../../../../common/components/shared/spinner/Spinner.js";
35
35
  import { AnalysisUpdateDate } from "../AnalysisUpdateDate/index.js";
36
36
  import { itemAnalysisPropType, quizAnalysisPropType } from "../propTypes.js";
37
+ import { csvFormat } from "../exportFormats.js";
38
+ import { ExportButton } from "../ExportButton/index.js";
37
39
  export var NewQuizAndItemAnalysisReportCardPresenter = (_dec = themeable(theme, styles), _dec(_class = (_temp = _class2 = /*#__PURE__*/function (_Component) {
38
40
  _inherits(NewQuizAndItemAnalysisReportCardPresenter, _Component);
39
41
 
@@ -56,6 +58,13 @@ export var NewQuizAndItemAnalysisReportCardPresenter = (_dec = themeable(theme,
56
58
  _this.props.generateReports(filter);
57
59
  };
58
60
 
61
+ _this.handleExport = function (_event) {
62
+ var format = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : csvFormat;
63
+ var filter = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 'last_attempt';
64
+
65
+ _this.props.exportReports(format, filter);
66
+ };
67
+
59
68
  _this.renderMetrics = function () {
60
69
  var _quizAnalysis$scores, _quizAnalysis$scores2, _quizAnalysis$scores3;
61
70
 
@@ -151,26 +160,48 @@ export var NewQuizAndItemAnalysisReportCardPresenter = (_dec = themeable(theme,
151
160
  }, generationInProgress ? _this.renderSpinner(t('Generation In Progress')) : _this.renderGenerateReportButton())));
152
161
  };
153
162
 
163
+ _this.renderExport = function () {
164
+ var _this$props3 = _this.props,
165
+ quizAnalysis = _this$props3.quizAnalysis,
166
+ generationInProgress = _this$props3.generationInProgress;
167
+ return /*#__PURE__*/React.createElement(ExportButton, {
168
+ quizAnalysis: quizAnalysis,
169
+ generationInProgress: generationInProgress,
170
+ handleExport: _this.handleExport
171
+ });
172
+ };
173
+
174
+ _this.renderReportCardHeader = function () {
175
+ var _this$props4 = _this.props,
176
+ name = _this$props4.name,
177
+ exportEnabled = _this$props4.exportEnabled,
178
+ fetchInProgress = _this$props4.fetchInProgress;
179
+ return /*#__PURE__*/React.createElement("div", {
180
+ className: styles.titleContainer
181
+ }, /*#__PURE__*/React.createElement(Flex, {
182
+ direction: "row",
183
+ wrap: "wrap",
184
+ justifyItems: "space-between"
185
+ }, /*#__PURE__*/React.createElement(Flex.Item, null, /*#__PURE__*/React.createElement(Text, {
186
+ size: "medium",
187
+ weight: "bold"
188
+ }, name)), exportEnabled && !fetchInProgress && /*#__PURE__*/React.createElement(Flex.Item, null, _this.renderExport())));
189
+ };
190
+
154
191
  return _this;
155
192
  }
156
193
 
157
194
  _createClass(NewQuizAndItemAnalysisReportCardPresenter, [{
158
195
  key: "render",
159
196
  value: function render() {
160
- var _this$props3 = this.props,
161
- fetchInProgress = _this$props3.fetchInProgress,
162
- name = _this$props3.name,
163
- quizAnalysis = _this$props3.quizAnalysis,
164
- analysisError = _this$props3.analysisError;
197
+ var _this$props5 = this.props,
198
+ fetchInProgress = _this$props5.fetchInProgress,
199
+ quizAnalysis = _this$props5.quizAnalysis,
200
+ analysisError = _this$props5.analysisError;
165
201
  var reportCardStyles = classnames(styles.reportCard, _defineProperty({}, styles.emptyReportCard, !quizAnalysis && !analysisError));
166
202
  return /*#__PURE__*/React.createElement(Card, {
167
203
  className: reportCardStyles
168
- }, /*#__PURE__*/React.createElement("div", {
169
- className: styles.titleContainer
170
- }, /*#__PURE__*/React.createElement(Text, {
171
- size: "medium",
172
- weight: "bold"
173
- }, name)), !fetchInProgress && quizAnalysis && this.renderQuizAnalysisSummary(), fetchInProgress && this.renderSpinner(), !fetchInProgress && this.renderReportCardFooter());
204
+ }, this.renderReportCardHeader(), !fetchInProgress && quizAnalysis && this.renderQuizAnalysisSummary(), fetchInProgress && this.renderSpinner(), !fetchInProgress && this.renderReportCardFooter());
174
205
  }
175
206
  }]);
176
207
 
@@ -184,7 +215,9 @@ export var NewQuizAndItemAnalysisReportCardPresenter = (_dec = themeable(theme,
184
215
  fetchInProgress: PropTypes.bool.isRequired,
185
216
  generationInProgress: PropTypes.bool.isRequired,
186
217
  analysisError: PropTypes.string,
187
- generateReports: PropTypes.func.isRequired
218
+ generateReports: PropTypes.func.isRequired,
219
+ exportReports: PropTypes.func.isRequired,
220
+ exportEnabled: PropTypes.bool.isRequired
188
221
  }, _class2.defaultProps = {
189
222
  name: void 0,
190
223
  href: void 0,
@@ -69,7 +69,7 @@ export var ScoreDistribution = (_dec = themeable(theme, styles), _dec(_class = (
69
69
  className: styles.headingContainer
70
70
  }, /*#__PURE__*/React.createElement(Heading, {
71
71
  level: "h3",
72
- themeOverride: {
72
+ theme: {
73
73
  h3FontWeight: 700
74
74
  }
75
75
  }, t('Score Distribution'))), /*#__PURE__*/React.createElement(QuintileDistribution, {
@@ -0,0 +1 @@
1
+ export var csvFormat = 'csv';
@@ -19,6 +19,8 @@ import { getFailedToFetchReports } from "./errorMessages.js";
19
19
  import { Img } from '@instructure/ui-img';
20
20
  import errorImage from './downForRepair.svg';
21
21
  import { PresentationContent, ScreenReaderContent } from '@instructure/ui-a11y-content';
22
+ import { csvFormat } from "./exportFormats.js";
23
+ import { ExportButton } from "./ExportButton/index.js";
22
24
 
23
25
  var _ref = /*#__PURE__*/React.createElement(Flex.Item, {
24
26
  align: "center"
@@ -47,7 +49,7 @@ export var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component)
47
49
  var itemAnalyses = _this.props.itemAnalyses || [];
48
50
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Heading, {
49
51
  level: "h2",
50
- themeOverride: {
52
+ theme: {
51
53
  h2FontWeight: 700
52
54
  },
53
55
  color: "primary"
@@ -101,7 +103,7 @@ export var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component)
101
103
  overflowY: "hidden"
102
104
  }, /*#__PURE__*/React.createElement(Heading, {
103
105
  level: "h2",
104
- themeOverride: {
106
+ theme: {
105
107
  h2FontWeight: 700
106
108
  },
107
109
  margin: "0 x-large 0 0",
@@ -130,6 +132,7 @@ export var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component)
130
132
  };
131
133
 
132
134
  _this.renderRightSide = function () {
135
+ var exportEnabled = _this.props.exportEnabled;
133
136
  return /*#__PURE__*/React.createElement(Flex, {
134
137
  alignItems: "center",
135
138
  justifyItems: "space-between",
@@ -139,11 +142,24 @@ export var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component)
139
142
  }, /*#__PURE__*/React.createElement(Flex.Item, {
140
143
  padding: "0 small 0 0",
141
144
  margin: "0 0 0 auto"
142
- }, _this.renderUpdateDateWithError()), /*#__PURE__*/React.createElement(Flex.Item, {
145
+ }, _this.renderUpdateDateWithError()), exportEnabled && /*#__PURE__*/React.createElement(Flex.Item, {
146
+ margin: "0 small 0 auto"
147
+ }, _this.renderExport()), /*#__PURE__*/React.createElement(Flex.Item, {
143
148
  margin: "0 0 0 auto"
144
149
  }, _this.renderGenerationButton()));
145
150
  };
146
151
 
152
+ _this.renderExport = function () {
153
+ var _this$props2 = _this.props,
154
+ quizAnalysis = _this$props2.quizAnalysis,
155
+ generationInProgress = _this$props2.generationInProgress;
156
+ return /*#__PURE__*/React.createElement(ExportButton, {
157
+ quizAnalysis: quizAnalysis,
158
+ generationInProgress: generationInProgress,
159
+ handleExport: _this.handleExport
160
+ });
161
+ };
162
+
147
163
  _this.renderTop = function () {
148
164
  return /*#__PURE__*/React.createElement(Flex, {
149
165
  justifyItems: "space-between",
@@ -156,12 +172,17 @@ export var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component)
156
172
  };
157
173
 
158
174
  _this.renderTopOnFailedFetch = function () {
175
+ var exportEnabled = _this.props.exportEnabled;
159
176
  return /*#__PURE__*/React.createElement(Flex, {
160
- alignItems: "end",
161
- width: "82.5rem",
177
+ justifyItems: "end",
178
+ wrap: "wrap",
179
+ width: "auto",
162
180
  margin: "auto",
163
- direction: "column"
164
- }, /*#__PURE__*/React.createElement(Flex.Item, {
181
+ direction: "row"
182
+ }, exportEnabled && /*#__PURE__*/React.createElement(Flex.Item, {
183
+ margin: "small",
184
+ overflowY: "visible"
185
+ }, _this.renderExport()), /*#__PURE__*/React.createElement(Flex.Item, {
165
186
  overflowY: "visible"
166
187
  }, _this.renderGenerationButton()));
167
188
  };
@@ -185,7 +206,7 @@ export var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component)
185
206
  color: "secondary",
186
207
  margin: "auto",
187
208
  onClick: _this.handleGeneration,
188
- themeOverride: {
209
+ theme: {
189
210
  lineHeight: '24px'
190
211
  }
191
212
  }, /*#__PURE__*/React.createElement(Text, {
@@ -200,9 +221,9 @@ export var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component)
200
221
  };
201
222
 
202
223
  _this.renderBody = function () {
203
- var _this$props2 = _this.props,
204
- fetchInProgress = _this$props2.fetchInProgress,
205
- quizAnalysis = _this$props2.quizAnalysis; // TODO need to refactor the NewQuizAnalysis to move out spinner logic
224
+ var _this$props3 = _this.props,
225
+ fetchInProgress = _this$props3.fetchInProgress,
226
+ quizAnalysis = _this$props3.quizAnalysis; // TODO need to refactor the NewQuizAnalysis to move out spinner logic
206
227
 
207
228
  return /*#__PURE__*/React.createElement(React.Fragment, null, (fetchInProgress || quizAnalysis) && /*#__PURE__*/React.createElement(NewQuizAnalysis, {
208
229
  quizAnalysis: quizAnalysis,
@@ -216,15 +237,22 @@ export var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component)
216
237
  _this.props.generateReports(filter);
217
238
  };
218
239
 
240
+ _this.handleExport = function (_event) {
241
+ var format = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : csvFormat;
242
+ var filter = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 'last_attempt';
243
+
244
+ _this.props.exportReports(format, filter);
245
+ };
246
+
219
247
  return _this;
220
248
  }
221
249
 
222
250
  _createClass(NewQuizAndItemAnalysisPresenter, [{
223
251
  key: "render",
224
252
  value: function render() {
225
- var _this$props3 = this.props,
226
- analysisFetchError = _this$props3.analysisFetchError,
227
- fetchInProgress = _this$props3.fetchInProgress;
253
+ var _this$props4 = this.props,
254
+ analysisFetchError = _this$props4.analysisFetchError,
255
+ fetchInProgress = _this$props4.fetchInProgress;
228
256
  return /*#__PURE__*/React.createElement("div", {
229
257
  className: "fs-mask"
230
258
  }, !fetchInProgress && (analysisFetchError ? this.renderTopOnFailedFetch() : this.renderTop()), analysisFetchError ? this.renderErrorBody() : this.renderBody());
@@ -241,7 +269,9 @@ NewQuizAndItemAnalysisPresenter.propTypes = {
241
269
  generationInProgress: PropTypes.bool.isRequired,
242
270
  analysisFetchError: PropTypes.bool.isRequired,
243
271
  analysisError: PropTypes.string,
244
- generateReports: PropTypes.func.isRequired
272
+ generateReports: PropTypes.func.isRequired,
273
+ exportReports: PropTypes.func.isRequired,
274
+ exportEnabled: PropTypes.bool.isRequired
245
275
  };
246
276
  NewQuizAndItemAnalysisPresenter.defaultProps = {
247
277
  analysisError: void 0,
@@ -26,6 +26,28 @@ export var quizAnalysisPropType = PropTypes.shape({
26
26
  average_attempts: PropTypes.number
27
27
  }).isRequired
28
28
  });
29
+ export var itemAnalysisPropType = PropTypes.shape({
30
+ attempts: PropTypes.shape({
31
+ students_responded: PropTypes.number,
32
+ students_without_response: PropTypes.number
33
+ }),
34
+ metadata: PropTypes.shape({
35
+ interaction_type: PropTypes.string,
36
+ item_body: PropTypes.string,
37
+ item_id: PropTypes.number,
38
+ item_title: PropTypes.string
39
+ }),
40
+ scores: PropTypes.shape({
41
+ difficulty_index: PropTypes.number,
42
+ discrimination_index: PropTypes.number,
43
+ mean: PropTypes.number,
44
+ median: PropTypes.number,
45
+ pearson_correlation: PropTypes.number,
46
+ points_possible: PropTypes.number,
47
+ quartile_distribution: PropTypes.arrayOf(PropTypes.number)
48
+ }),
49
+ answer_summary: answerSummaryPropType
50
+ });
29
51
  var aggregateDetailPropType = PropTypes.shape({
30
52
  count: PropTypes.number.isRequired,
31
53
  percentage: PropTypes.number.isRequired
@@ -60,28 +82,6 @@ export var matchingTypeAnswerSummaryPropType = PropTypes.shape({
60
82
  }))
61
83
  });
62
84
  export var answerSummaryPropType = PropTypes.oneOfType([choiceTypeAnswerSummaryPropType, onlyAggregatePropType, matchingTypeAnswerSummaryPropType]);
63
- export var itemAnalysisPropType = PropTypes.shape({
64
- attempts: PropTypes.shape({
65
- students_responded: PropTypes.number,
66
- students_without_response: PropTypes.number
67
- }),
68
- metadata: PropTypes.shape({
69
- interaction_type: PropTypes.string,
70
- item_body: PropTypes.string,
71
- item_id: PropTypes.number,
72
- item_title: PropTypes.string
73
- }),
74
- scores: PropTypes.shape({
75
- difficulty_index: PropTypes.number,
76
- discrimination_index: PropTypes.number,
77
- mean: PropTypes.number,
78
- median: PropTypes.number,
79
- pearson_correlation: PropTypes.number,
80
- points_possible: PropTypes.number,
81
- quartile_distribution: PropTypes.arrayOf(PropTypes.number)
82
- }),
83
- answer_summary: answerSummaryPropType
84
- });
85
85
  export var afsFlags = PropTypes.shape({
86
86
  formulaEnabled: PropTypes.bool.isRequired,
87
87
  matchingEnabled: PropTypes.bool.isRequired,
@@ -9,6 +9,7 @@ import { connect } from "../../../../common/react-redux.js";
9
9
  import { compose } from 'redux';
10
10
  import { getActiveQuizId } from "../../../../common/selectors/quizzes.js";
11
11
  import { addError } from "../../../../common/actions/alerts.js";
12
+ import { featureOn } from "../../../../common/util/featureCheck.js";
12
13
  var DEFAULT_POLLING_INTERVAL = 3000;
13
14
  export function mapStateToProps(state, ownProps) {
14
15
  return {
@@ -23,7 +24,8 @@ export function mapStateToProps(state, ownProps) {
23
24
  fetchItemAnalyses: fetchItemAnalyses,
24
25
  fetchAnalysesStatus: fetchAnalysesStatus,
25
26
  getAnalysesExport: getAnalysesExport,
26
- pollingInterval: ownProps.pollingInterval || DEFAULT_POLLING_INTERVAL
27
+ pollingInterval: ownProps.pollingInterval || DEFAULT_POLLING_INTERVAL,
28
+ exportEnabled: featureOn('item_analysis_csv')
27
29
  };
28
30
  }
29
31
  var mapDispatchToProps = {
@@ -303,7 +303,7 @@ var BanksList = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles), _de
303
303
  className: styles.bankTitle
304
304
  }, /*#__PURE__*/_react.default.createElement(_uiLink.Link, {
305
305
  onClick: navigateToBank(bank.id),
306
- themeOverride: {
306
+ theme: {
307
307
  color: _this.theme.bankTitleLinkColor,
308
308
  hoverColor: _this.theme.bankTitleLinkHoverColor
309
309
  },
@@ -72,7 +72,7 @@ var StimulusShowInfo = /*#__PURE__*/function (_Component) {
72
72
  as: "h2",
73
73
  color: "primary",
74
74
  margin: "0 0 small",
75
- themeOverride: {
75
+ theme: {
76
76
  h2FontWeight: '700'
77
77
  }
78
78
  }, this.props.stimulus.title), instructions, /*#__PURE__*/_react.default.createElement("div", {
@@ -76,7 +76,7 @@ var TagDisplay = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles), _d
76
76
  className: styles.tags,
77
77
  "aria-label": (0, _formatMessage.default)('question tags')
78
78
  }, visible, extra > 0 && /*#__PURE__*/_react.default.createElement(_uiTag.Tag, {
79
- themeOverride: {
79
+ theme: {
80
80
  defaultBackground: '#FFFFFF'
81
81
  },
82
82
  text: /*#__PURE__*/_react.default.createElement(_uiA11yContent.AccessibleContent, {
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.getAnalysesExport = exports.csvFormat = void 0;
8
+ exports.getAnalysesExport = void 0;
9
9
 
10
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
11
 
@@ -13,6 +13,8 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
13
13
 
14
14
  var _Fetcher = _interopRequireDefault(require("../../common/util/Fetcher.js"));
15
15
 
16
+ var _exportFormats = require("../components/resources/NewQuizAndItemAnalysis/exportFormats.js");
17
+
16
18
  var getFetcher = function getFetcher(format) {
17
19
  var mimeType = formatsToMimeTypes.get(format);
18
20
 
@@ -24,16 +26,14 @@ var getFetcher = function getFetcher(format) {
24
26
  headers: {
25
27
  'Accept': mimeType
26
28
  },
27
- injectUserToken: true,
29
+ injectMissingUserToken: true,
28
30
  asyncResponseHandler: function asyncResponseHandler(response) {
29
31
  return response;
30
32
  }
31
33
  });
32
34
  };
33
35
 
34
- var csvFormat = 'csv';
35
- exports.csvFormat = csvFormat;
36
- var formatsToMimeTypes = new Map().set(csvFormat, 'text/csv');
36
+ var formatsToMimeTypes = new Map().set(_exportFormats.csvFormat, 'text/csv');
37
37
 
38
38
  var getAnalysesExport = /*#__PURE__*/function () {
39
39
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(quizId, format) {
@@ -62,7 +62,7 @@ var AnalysisMetric = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles)
62
62
  "data-automation": dataAutomation,
63
63
  className: styles.metricWrapper
64
64
  }, /*#__PURE__*/_react.default.createElement(_uiMetric.Metric, {
65
- themeOverride: {
65
+ theme: {
66
66
  valueFontWeight: 500,
67
67
  padding: '0'
68
68
  },
@@ -71,7 +71,7 @@ var AnalysisPopoverMetric = (_dec = (0, _uiThemeable.themeable)(_theme.default,
71
71
  popoverDescription = _this$props.popoverDescription,
72
72
  value = _this$props.value;
73
73
  return /*#__PURE__*/_react.default.createElement(_uiMetric.Metric, {
74
- themeOverride: {
74
+ theme: {
75
75
  valueFontWeight: 500,
76
76
  padding: '0'
77
77
  },
@@ -110,19 +110,19 @@ var ChoiceTypeTableRow = (_dec = (0, _uiThemeable.themeable)(_theme.default, sty
110
110
  return /*#__PURE__*/_react.default.createElement(_uiTable.Table.Row, {
111
111
  key: _this.props.choiceIndex
112
112
  }, /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, {
113
- themeOverride: {
113
+ theme: {
114
114
  padding: '0px'
115
115
  }
116
116
  }, /*#__PURE__*/_react.default.createElement(_uiA11yContent.ScreenReaderContent, null, _this.answerLabel(correct)), _this.renderIcon(correct)), /*#__PURE__*/_react.default.createElement(_uiTable.Table.RowHeader, {
117
- themeOverride: {
117
+ theme: {
118
118
  padding: cellPadding
119
119
  }
120
120
  }, _this.renderMiddleCell(correct, _this.extractChoiceText(choiceBody, correct))), /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, {
121
- themeOverride: {
121
+ theme: {
122
122
  padding: cellPadding
123
123
  }
124
124
  }, _this.renderMiddleCell(correct, _this.props.choice.count)), /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, {
125
- themeOverride: {
125
+ theme: {
126
126
  padding: cellPadding
127
127
  },
128
128
  textAlign: "center"
@@ -113,7 +113,7 @@ var AggregationTable = (_dec = (0, _uiThemeable.themeable)(_theme.default, style
113
113
  return /*#__PURE__*/_react.default.createElement(_uiTable.Table.Row, {
114
114
  key: key
115
115
  }, /*#__PURE__*/_react.default.createElement(_uiTable.Table.RowHeader, {
116
- themeOverride: {
116
+ theme: {
117
117
  padding: '0px'
118
118
  }
119
119
  }, /*#__PURE__*/_react.default.createElement(_uiA11yContent.ScreenReaderContent, null, label), /*#__PURE__*/_react.default.createElement(_uiFlex.Flex, {
@@ -130,12 +130,12 @@ var AggregationTable = (_dec = (0, _uiThemeable.themeable)(_theme.default, style
130
130
  }, /*#__PURE__*/_react.default.createElement("div", {
131
131
  className: (0, _classnames.default)(styles.labelWrapper)
132
132
  }, /*#__PURE__*/_react.default.createElement(_uiText.Text, null, label))))), /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, {
133
- themeOverride: {
133
+ theme: {
134
134
  padding: '0px'
135
135
  },
136
136
  textAlign: "center"
137
137
  }, /*#__PURE__*/_react.default.createElement(_uiText.Text, null, count)), /*#__PURE__*/_react.default.createElement(_uiTable.Table.Cell, {
138
- themeOverride: {
138
+ theme: {
139
139
  padding: '0px'
140
140
  },
141
141
  textAlign: "center"
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = exports.ExportButton = void 0;
9
+
10
+ var _react = _interopRequireDefault(require("react"));
11
+
12
+ var _propTypes = _interopRequireDefault(require("prop-types"));
13
+
14
+ var _formatMessage = _interopRequireDefault(require("@instructure/quiz-i18n/es/format-message"));
15
+
16
+ var _propTypes2 = require("../propTypes.js");
17
+
18
+ var _uiText = require("@instructure/ui-text");
19
+
20
+ var _uiButtons = require("@instructure/ui-buttons");
21
+
22
+ var ExportButton = function ExportButton(_ref) {
23
+ var quizAnalysis = _ref.quizAnalysis,
24
+ generationInProgress = _ref.generationInProgress,
25
+ handleExport = _ref.handleExport;
26
+
27
+ var renderExportButton = function renderExportButton(enabled) {
28
+ var interaction = enabled ? 'enabled' : 'disabled';
29
+ var color = enabled ? 'secondary' : 'primary-inverse';
30
+ return /*#__PURE__*/_react.default.createElement(_uiButtons.Button, {
31
+ color: color,
32
+ interaction: interaction,
33
+ onClick: handleExport,
34
+ theme: {
35
+ lineHeight: '24px'
36
+ }
37
+ }, /*#__PURE__*/_react.default.createElement(_uiText.Text, {
38
+ size: "medium"
39
+ }, (0, _formatMessage.default)('Export CSV')));
40
+ };
41
+
42
+ if (generationInProgress || !quizAnalysis) {
43
+ return renderExportButton(false);
44
+ }
45
+
46
+ if (quizAnalysis) {
47
+ return renderExportButton(true);
48
+ }
49
+ };
50
+
51
+ exports.ExportButton = ExportButton;
52
+ ExportButton.propTypes = {
53
+ quizAnalysis: _propTypes2.quizAnalysisPropType.isRequired,
54
+ generationInProgress: _propTypes.default.bool.isRequired,
55
+ handleExport: _propTypes.default.func.isRequired
56
+ };
57
+ var _default = ExportButton;
58
+ exports.default = _default;
@@ -111,7 +111,7 @@ var MetricPopover = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
111
111
  className: styles.popoverTitle,
112
112
  level: "h3"
113
113
  }, _this.props.title)), /*#__PURE__*/_react.default.createElement("div", null, _this.props.subtitle && /*#__PURE__*/_react.default.createElement(_uiHeading.Heading, {
114
- themeOverride: {
114
+ theme: {
115
115
  h5FontWeight: 700
116
116
  },
117
117
  level: "h5"
@@ -128,7 +128,7 @@ var MetricPopover = (_dec = (0, _uiThemeable.themeable)(_theme.default, styles),
128
128
  value: function renderPopoverTrigger() {
129
129
  return /*#__PURE__*/_react.default.createElement(_uiButtons.IconButton, {
130
130
  size: "small",
131
- themeOverride: {
131
+ theme: {
132
132
  smallHeight: '18px',
133
133
  transform: 'translateY(-1px)'
134
134
  },
@@ -49,6 +49,10 @@ var _index3 = require("../AnalysisUpdateDate/index.js");
49
49
 
50
50
  var _propTypes2 = require("../propTypes.js");
51
51
 
52
+ var _exportFormats = require("../exportFormats.js");
53
+
54
+ var _index4 = require("../ExportButton/index.js");
55
+
52
56
  var _dec, _class, _class2, _temp;
53
57
 
54
58
  var styles = {
@@ -86,6 +90,13 @@ var NewQuizAndItemAnalysisReportCardPresenter = (_dec = (0, _uiThemeable.themeab
86
90
  _this.props.generateReports(filter);
87
91
  };
88
92
 
93
+ _this.handleExport = function (_event) {
94
+ var format = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : _exportFormats.csvFormat;
95
+ var filter = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 'last_attempt';
96
+
97
+ _this.props.exportReports(format, filter);
98
+ };
99
+
89
100
  _this.renderMetrics = function () {
90
101
  var _quizAnalysis$scores, _quizAnalysis$scores2, _quizAnalysis$scores3;
91
102
 
@@ -181,26 +192,48 @@ var NewQuizAndItemAnalysisReportCardPresenter = (_dec = (0, _uiThemeable.themeab
181
192
  }, generationInProgress ? _this.renderSpinner((0, _formatMessage.default)('Generation In Progress')) : _this.renderGenerateReportButton())));
182
193
  };
183
194
 
195
+ _this.renderExport = function () {
196
+ var _this$props3 = _this.props,
197
+ quizAnalysis = _this$props3.quizAnalysis,
198
+ generationInProgress = _this$props3.generationInProgress;
199
+ return /*#__PURE__*/_react.default.createElement(_index4.ExportButton, {
200
+ quizAnalysis: quizAnalysis,
201
+ generationInProgress: generationInProgress,
202
+ handleExport: _this.handleExport
203
+ });
204
+ };
205
+
206
+ _this.renderReportCardHeader = function () {
207
+ var _this$props4 = _this.props,
208
+ name = _this$props4.name,
209
+ exportEnabled = _this$props4.exportEnabled,
210
+ fetchInProgress = _this$props4.fetchInProgress;
211
+ return /*#__PURE__*/_react.default.createElement("div", {
212
+ className: styles.titleContainer
213
+ }, /*#__PURE__*/_react.default.createElement(_uiFlex.Flex, {
214
+ direction: "row",
215
+ wrap: "wrap",
216
+ justifyItems: "space-between"
217
+ }, /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, null, /*#__PURE__*/_react.default.createElement(_uiText.Text, {
218
+ size: "medium",
219
+ weight: "bold"
220
+ }, name)), exportEnabled && !fetchInProgress && /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, null, _this.renderExport())));
221
+ };
222
+
184
223
  return _this;
185
224
  }
186
225
 
187
226
  (0, _createClass2.default)(NewQuizAndItemAnalysisReportCardPresenter, [{
188
227
  key: "render",
189
228
  value: function render() {
190
- var _this$props3 = this.props,
191
- fetchInProgress = _this$props3.fetchInProgress,
192
- name = _this$props3.name,
193
- quizAnalysis = _this$props3.quizAnalysis,
194
- analysisError = _this$props3.analysisError;
229
+ var _this$props5 = this.props,
230
+ fetchInProgress = _this$props5.fetchInProgress,
231
+ quizAnalysis = _this$props5.quizAnalysis,
232
+ analysisError = _this$props5.analysisError;
195
233
  var reportCardStyles = (0, _classnames2.default)(styles.reportCard, (0, _defineProperty2.default)({}, styles.emptyReportCard, !quizAnalysis && !analysisError));
196
234
  return /*#__PURE__*/_react.default.createElement(_index.default, {
197
235
  className: reportCardStyles
198
- }, /*#__PURE__*/_react.default.createElement("div", {
199
- className: styles.titleContainer
200
- }, /*#__PURE__*/_react.default.createElement(_uiText.Text, {
201
- size: "medium",
202
- weight: "bold"
203
- }, name)), !fetchInProgress && quizAnalysis && this.renderQuizAnalysisSummary(), fetchInProgress && this.renderSpinner(), !fetchInProgress && this.renderReportCardFooter());
236
+ }, this.renderReportCardHeader(), !fetchInProgress && quizAnalysis && this.renderQuizAnalysisSummary(), fetchInProgress && this.renderSpinner(), !fetchInProgress && this.renderReportCardFooter());
204
237
  }
205
238
  }]);
206
239
  NewQuizAndItemAnalysisReportCardPresenter.displayName = "NewQuizAndItemAnalysisReportCardPresenter";
@@ -213,7 +246,9 @@ var NewQuizAndItemAnalysisReportCardPresenter = (_dec = (0, _uiThemeable.themeab
213
246
  fetchInProgress: _propTypes.default.bool.isRequired,
214
247
  generationInProgress: _propTypes.default.bool.isRequired,
215
248
  analysisError: _propTypes.default.string,
216
- generateReports: _propTypes.default.func.isRequired
249
+ generateReports: _propTypes.default.func.isRequired,
250
+ exportReports: _propTypes.default.func.isRequired,
251
+ exportEnabled: _propTypes.default.bool.isRequired
217
252
  }, _class2.defaultProps = {
218
253
  name: void 0,
219
254
  href: void 0,
@@ -91,7 +91,7 @@ var ScoreDistribution = (_dec = (0, _uiThemeable.themeable)(_theme.default, styl
91
91
  className: styles.headingContainer
92
92
  }, /*#__PURE__*/_react.default.createElement(_uiHeading.Heading, {
93
93
  level: "h3",
94
- themeOverride: {
94
+ theme: {
95
95
  h3FontWeight: 700
96
96
  }
97
97
  }, (0, _formatMessage.default)('Score Distribution'))), /*#__PURE__*/_react.default.createElement(_index.default, {
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.csvFormat = void 0;
7
+ var csvFormat = 'csv';
8
+ exports.csvFormat = csvFormat;
@@ -51,6 +51,10 @@ var _downForRepair = _interopRequireDefault(require("./downForRepair.svg"));
51
51
 
52
52
  var _uiA11yContent = require("@instructure/ui-a11y-content");
53
53
 
54
+ var _exportFormats = require("./exportFormats.js");
55
+
56
+ var _index4 = require("./ExportButton/index.js");
57
+
54
58
  var _ref = /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
55
59
  align: "center"
56
60
  }, /*#__PURE__*/_react.default.createElement(_uiA11yContent.PresentationContent, null, /*#__PURE__*/_react.default.createElement(_uiImg.Img, {
@@ -78,7 +82,7 @@ var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component) {
78
82
  var itemAnalyses = _this.props.itemAnalyses || [];
79
83
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_uiHeading.Heading, {
80
84
  level: "h2",
81
- themeOverride: {
85
+ theme: {
82
86
  h2FontWeight: 700
83
87
  },
84
88
  color: "primary"
@@ -132,7 +136,7 @@ var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component) {
132
136
  overflowY: "hidden"
133
137
  }, /*#__PURE__*/_react.default.createElement(_uiHeading.Heading, {
134
138
  level: "h2",
135
- themeOverride: {
139
+ theme: {
136
140
  h2FontWeight: 700
137
141
  },
138
142
  margin: "0 x-large 0 0",
@@ -161,6 +165,7 @@ var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component) {
161
165
  };
162
166
 
163
167
  _this.renderRightSide = function () {
168
+ var exportEnabled = _this.props.exportEnabled;
164
169
  return /*#__PURE__*/_react.default.createElement(_uiFlex.Flex, {
165
170
  alignItems: "center",
166
171
  justifyItems: "space-between",
@@ -170,11 +175,24 @@ var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component) {
170
175
  }, /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
171
176
  padding: "0 small 0 0",
172
177
  margin: "0 0 0 auto"
173
- }, _this.renderUpdateDateWithError()), /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
178
+ }, _this.renderUpdateDateWithError()), exportEnabled && /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
179
+ margin: "0 small 0 auto"
180
+ }, _this.renderExport()), /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
174
181
  margin: "0 0 0 auto"
175
182
  }, _this.renderGenerationButton()));
176
183
  };
177
184
 
185
+ _this.renderExport = function () {
186
+ var _this$props2 = _this.props,
187
+ quizAnalysis = _this$props2.quizAnalysis,
188
+ generationInProgress = _this$props2.generationInProgress;
189
+ return /*#__PURE__*/_react.default.createElement(_index4.ExportButton, {
190
+ quizAnalysis: quizAnalysis,
191
+ generationInProgress: generationInProgress,
192
+ handleExport: _this.handleExport
193
+ });
194
+ };
195
+
178
196
  _this.renderTop = function () {
179
197
  return /*#__PURE__*/_react.default.createElement(_uiFlex.Flex, {
180
198
  justifyItems: "space-between",
@@ -187,12 +205,17 @@ var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component) {
187
205
  };
188
206
 
189
207
  _this.renderTopOnFailedFetch = function () {
208
+ var exportEnabled = _this.props.exportEnabled;
190
209
  return /*#__PURE__*/_react.default.createElement(_uiFlex.Flex, {
191
- alignItems: "end",
192
- width: "82.5rem",
210
+ justifyItems: "end",
211
+ wrap: "wrap",
212
+ width: "auto",
193
213
  margin: "auto",
194
- direction: "column"
195
- }, /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
214
+ direction: "row"
215
+ }, exportEnabled && /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
216
+ margin: "small",
217
+ overflowY: "visible"
218
+ }, _this.renderExport()), /*#__PURE__*/_react.default.createElement(_uiFlex.Flex.Item, {
196
219
  overflowY: "visible"
197
220
  }, _this.renderGenerationButton()));
198
221
  };
@@ -216,7 +239,7 @@ var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component) {
216
239
  color: "secondary",
217
240
  margin: "auto",
218
241
  onClick: _this.handleGeneration,
219
- themeOverride: {
242
+ theme: {
220
243
  lineHeight: '24px'
221
244
  }
222
245
  }, /*#__PURE__*/_react.default.createElement(_uiText.Text, {
@@ -231,9 +254,9 @@ var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component) {
231
254
  };
232
255
 
233
256
  _this.renderBody = function () {
234
- var _this$props2 = _this.props,
235
- fetchInProgress = _this$props2.fetchInProgress,
236
- quizAnalysis = _this$props2.quizAnalysis; // TODO need to refactor the NewQuizAnalysis to move out spinner logic
257
+ var _this$props3 = _this.props,
258
+ fetchInProgress = _this$props3.fetchInProgress,
259
+ quizAnalysis = _this$props3.quizAnalysis; // TODO need to refactor the NewQuizAnalysis to move out spinner logic
237
260
 
238
261
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, (fetchInProgress || quizAnalysis) && /*#__PURE__*/_react.default.createElement(_index2.default, {
239
262
  quizAnalysis: quizAnalysis,
@@ -247,15 +270,22 @@ var NewQuizAndItemAnalysisPresenter = /*#__PURE__*/function (_Component) {
247
270
  _this.props.generateReports(filter);
248
271
  };
249
272
 
273
+ _this.handleExport = function (_event) {
274
+ var format = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : _exportFormats.csvFormat;
275
+ var filter = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 'last_attempt';
276
+
277
+ _this.props.exportReports(format, filter);
278
+ };
279
+
250
280
  return _this;
251
281
  }
252
282
 
253
283
  (0, _createClass2.default)(NewQuizAndItemAnalysisPresenter, [{
254
284
  key: "render",
255
285
  value: function render() {
256
- var _this$props3 = this.props,
257
- analysisFetchError = _this$props3.analysisFetchError,
258
- fetchInProgress = _this$props3.fetchInProgress;
286
+ var _this$props4 = this.props,
287
+ analysisFetchError = _this$props4.analysisFetchError,
288
+ fetchInProgress = _this$props4.fetchInProgress;
259
289
  return /*#__PURE__*/_react.default.createElement("div", {
260
290
  className: "fs-mask"
261
291
  }, !fetchInProgress && (analysisFetchError ? this.renderTopOnFailedFetch() : this.renderTop()), analysisFetchError ? this.renderErrorBody() : this.renderBody());
@@ -273,7 +303,9 @@ NewQuizAndItemAnalysisPresenter.propTypes = {
273
303
  generationInProgress: _propTypes2.default.bool.isRequired,
274
304
  analysisFetchError: _propTypes2.default.bool.isRequired,
275
305
  analysisError: _propTypes2.default.string,
276
- generateReports: _propTypes2.default.func.isRequired
306
+ generateReports: _propTypes2.default.func.isRequired,
307
+ exportReports: _propTypes2.default.func.isRequired,
308
+ exportEnabled: _propTypes2.default.bool.isRequired
277
309
  };
278
310
  NewQuizAndItemAnalysisPresenter.defaultProps = {
279
311
  analysisError: void 0,
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.afsFlags = exports.itemAnalysisPropType = exports.answerSummaryPropType = exports.matchingTypeAnswerSummaryPropType = exports.choiceTypeAnswerSummaryPropType = exports.onlyAggregatePropType = exports.quizAnalysisPropType = exports.quizAnalysisMetadata = void 0;
8
+ exports.afsFlags = exports.answerSummaryPropType = exports.matchingTypeAnswerSummaryPropType = exports.choiceTypeAnswerSummaryPropType = exports.onlyAggregatePropType = exports.itemAnalysisPropType = exports.quizAnalysisPropType = exports.quizAnalysisMetadata = void 0;
9
9
 
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
@@ -42,6 +42,31 @@ var quizAnalysisPropType = _propTypes.default.shape({
42
42
 
43
43
  exports.quizAnalysisPropType = quizAnalysisPropType;
44
44
 
45
+ var itemAnalysisPropType = _propTypes.default.shape({
46
+ attempts: _propTypes.default.shape({
47
+ students_responded: _propTypes.default.number,
48
+ students_without_response: _propTypes.default.number
49
+ }),
50
+ metadata: _propTypes.default.shape({
51
+ interaction_type: _propTypes.default.string,
52
+ item_body: _propTypes.default.string,
53
+ item_id: _propTypes.default.number,
54
+ item_title: _propTypes.default.string
55
+ }),
56
+ scores: _propTypes.default.shape({
57
+ difficulty_index: _propTypes.default.number,
58
+ discrimination_index: _propTypes.default.number,
59
+ mean: _propTypes.default.number,
60
+ median: _propTypes.default.number,
61
+ pearson_correlation: _propTypes.default.number,
62
+ points_possible: _propTypes.default.number,
63
+ quartile_distribution: _propTypes.default.arrayOf(_propTypes.default.number)
64
+ }),
65
+ answer_summary: answerSummaryPropType
66
+ });
67
+
68
+ exports.itemAnalysisPropType = itemAnalysisPropType;
69
+
45
70
  var aggregateDetailPropType = _propTypes.default.shape({
46
71
  count: _propTypes.default.number.isRequired,
47
72
  percentage: _propTypes.default.number.isRequired
@@ -90,31 +115,6 @@ var answerSummaryPropType = _propTypes.default.oneOfType([choiceTypeAnswerSummar
90
115
 
91
116
  exports.answerSummaryPropType = answerSummaryPropType;
92
117
 
93
- var itemAnalysisPropType = _propTypes.default.shape({
94
- attempts: _propTypes.default.shape({
95
- students_responded: _propTypes.default.number,
96
- students_without_response: _propTypes.default.number
97
- }),
98
- metadata: _propTypes.default.shape({
99
- interaction_type: _propTypes.default.string,
100
- item_body: _propTypes.default.string,
101
- item_id: _propTypes.default.number,
102
- item_title: _propTypes.default.string
103
- }),
104
- scores: _propTypes.default.shape({
105
- difficulty_index: _propTypes.default.number,
106
- discrimination_index: _propTypes.default.number,
107
- mean: _propTypes.default.number,
108
- median: _propTypes.default.number,
109
- pearson_correlation: _propTypes.default.number,
110
- points_possible: _propTypes.default.number,
111
- quartile_distribution: _propTypes.default.arrayOf(_propTypes.default.number)
112
- }),
113
- answer_summary: answerSummaryPropType
114
- });
115
-
116
- exports.itemAnalysisPropType = itemAnalysisPropType;
117
-
118
118
  var afsFlags = _propTypes.default.shape({
119
119
  formulaEnabled: _propTypes.default.bool.isRequired,
120
120
  matchingEnabled: _propTypes.default.bool.isRequired,
@@ -28,6 +28,8 @@ var _quizzes = require("../../../../common/selectors/quizzes.js");
28
28
 
29
29
  var _alerts = require("../../../../common/actions/alerts.js");
30
30
 
31
+ var _featureCheck = require("../../../../common/util/featureCheck.js");
32
+
31
33
  var DEFAULT_POLLING_INTERVAL = 3000;
32
34
 
33
35
  function mapStateToProps(state, ownProps) {
@@ -43,7 +45,8 @@ function mapStateToProps(state, ownProps) {
43
45
  fetchItemAnalyses: _getItemAnalyses.getItemAnalyses,
44
46
  fetchAnalysesStatus: _getAnalysesStatus.getAnalysesStatus,
45
47
  getAnalysesExport: _getAnalysesExport.getAnalysesExport,
46
- pollingInterval: ownProps.pollingInterval || DEFAULT_POLLING_INTERVAL
48
+ pollingInterval: ownProps.pollingInterval || DEFAULT_POLLING_INTERVAL,
49
+ exportEnabled: (0, _featureCheck.featureOn)('item_analysis_csv')
47
50
  };
48
51
  }
49
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/quiz-core",
3
- "version": "18.7.1-alpha.0+33092c184",
3
+ "version": "18.7.1-rc.1+c0cfb2272",
4
4
  "license": "MIT",
5
5
  "description": "The Quiz React SDK by Instructure Inc.",
6
6
  "author": "Instructure, Inc. Engineering and Product Design",
@@ -41,62 +41,61 @@
41
41
  "lib"
42
42
  ],
43
43
  "dependencies": {
44
- "@instructure/emotion": "^8.48.2",
45
44
  "@instructure/grading-utils": "^1.0.0",
46
45
  "@instructure/outcomes-ui": "^2.1.9",
47
- "@instructure/quiz-common": "18.7.1-alpha.0+33092c184",
48
- "@instructure/quiz-i18n": "18.7.1-alpha.0+33092c184",
49
- "@instructure/quiz-interactions": "18.7.1-alpha.0+33092c184",
50
- "@instructure/quiz-number-input": "18.7.1-alpha.0+33092c184",
51
- "@instructure/quiz-rce": "18.7.1-alpha.0+33092c184",
52
- "@instructure/ui-a11y-content": "^8.48.2",
53
- "@instructure/ui-alerts": "^8.48.2",
54
- "@instructure/ui-avatar": "^8.48.2",
55
- "@instructure/ui-billboard": "^8.48.2",
56
- "@instructure/ui-breadcrumb": "^8.48.2",
57
- "@instructure/ui-buttons": "^8.48.2",
58
- "@instructure/ui-checkbox": "^8.48.2",
59
- "@instructure/ui-color-utils": "^8.48.2",
60
- "@instructure/ui-dialog": "^8.48.2",
61
- "@instructure/ui-flex": "^8.48.2",
62
- "@instructure/ui-focusable": "^8.48.2",
63
- "@instructure/ui-form-field": "^8.48.2",
64
- "@instructure/ui-grid": "^8.48.2",
65
- "@instructure/ui-heading": "^8.48.2",
46
+ "@instructure/quiz-common": "18.7.1-rc.1+c0cfb2272",
47
+ "@instructure/quiz-i18n": "18.7.1-rc.1+c0cfb2272",
48
+ "@instructure/quiz-interactions": "18.7.1-rc.1+c0cfb2272",
49
+ "@instructure/quiz-number-input": "18.7.1-rc.1+c0cfb2272",
50
+ "@instructure/quiz-rce": "18.7.1-rc.1+c0cfb2272",
51
+ "@instructure/ui-a11y-content": "^7.22.1",
52
+ "@instructure/ui-alerts": "^7.22.1",
53
+ "@instructure/ui-avatar": "^7.22.1",
54
+ "@instructure/ui-billboard": "^7.22.1",
55
+ "@instructure/ui-breadcrumb": "^7.22.1",
56
+ "@instructure/ui-buttons": "^7.22.1",
57
+ "@instructure/ui-checkbox": "^7.22.1",
58
+ "@instructure/ui-color-utils": "^7.22.1",
59
+ "@instructure/ui-dialog": "^7.22.1",
60
+ "@instructure/ui-flex": "^7.22.1",
61
+ "@instructure/ui-focusable": "^7.22.1",
62
+ "@instructure/ui-form-field": "^7.22.1",
63
+ "@instructure/ui-grid": "^7.22.1",
64
+ "@instructure/ui-heading": "^7.22.1",
66
65
  "@instructure/ui-i18n": "^7.22.1",
67
- "@instructure/ui-icons": "^8.48.2",
68
- "@instructure/ui-img": "^8.48.2",
69
- "@instructure/ui-link": "^8.48.2",
70
- "@instructure/ui-list": "^8.48.2",
71
- "@instructure/ui-menu": "^8.48.2",
72
- "@instructure/ui-metric": "^8.48.2",
73
- "@instructure/ui-modal": "^8.48.2",
74
- "@instructure/ui-motion": "^8.48.2",
75
- "@instructure/ui-number-input": "^8.48.2",
76
- "@instructure/ui-overlays": "^8.48.2",
77
- "@instructure/ui-pagination": "^8.48.2",
78
- "@instructure/ui-popover": "^8.48.2",
79
- "@instructure/ui-portal": "^8.48.2",
80
- "@instructure/ui-progress": "^8.48.2",
81
- "@instructure/ui-prop-types": "^8.48.2",
82
- "@instructure/ui-radio-input": "^8.48.2",
83
- "@instructure/ui-react-utils": "^8.48.2",
84
- "@instructure/ui-select": "^8.48.2",
85
- "@instructure/ui-simple-select": "^8.48.2",
86
- "@instructure/ui-spinner": "^8.48.2",
87
- "@instructure/ui-table": "^8.48.2",
88
- "@instructure/ui-tabs": "^8.48.2",
89
- "@instructure/ui-tag": "^8.48.2",
90
- "@instructure/ui-text": "^8.48.2",
91
- "@instructure/ui-text-input": "^8.48.2",
66
+ "@instructure/ui-icons": "^7.22.1",
67
+ "@instructure/ui-img": "^7.22.1",
68
+ "@instructure/ui-link": "^7.22.1",
69
+ "@instructure/ui-list": "^7.22.1",
70
+ "@instructure/ui-menu": "^7.22.1",
71
+ "@instructure/ui-metric": "^7.22.1",
72
+ "@instructure/ui-modal": "^7.22.1",
73
+ "@instructure/ui-motion": "^7.22.1",
74
+ "@instructure/ui-number-input": "^7.22.1",
75
+ "@instructure/ui-overlays": "^7.22.1",
76
+ "@instructure/ui-pagination": "^7.22.1",
77
+ "@instructure/ui-popover": "^7.22.1",
78
+ "@instructure/ui-portal": "^7.22.1",
79
+ "@instructure/ui-progress": "^7.22.1",
80
+ "@instructure/ui-prop-types": "^7.22.1",
81
+ "@instructure/ui-radio-input": "^7.22.1",
82
+ "@instructure/ui-react-utils": "^7.22.1",
83
+ "@instructure/ui-select": "^7.22.1",
84
+ "@instructure/ui-simple-select": "^7.22.1",
85
+ "@instructure/ui-spinner": "^7.22.1",
86
+ "@instructure/ui-table": "^7.22.1",
87
+ "@instructure/ui-tabs": "^7.22.1",
88
+ "@instructure/ui-tag": "^7.22.1",
89
+ "@instructure/ui-text": "^7.22.1",
90
+ "@instructure/ui-text-input": "^7.22.1",
92
91
  "@instructure/ui-themeable": "^7.22.1",
93
- "@instructure/ui-themes": "^8.48.2",
94
- "@instructure/ui-toggle-details": "^8.48.2",
95
- "@instructure/ui-tooltip": "^8.48.2",
96
- "@instructure/ui-tray": "^8.48.2",
97
- "@instructure/ui-truncate-text": "^8.48.2",
98
- "@instructure/ui-utils": "^8.48.2",
99
- "@instructure/ui-view": "^8.48.2",
92
+ "@instructure/ui-themes": "^7.22.1",
93
+ "@instructure/ui-toggle-details": "^7.22.1",
94
+ "@instructure/ui-tooltip": "^7.22.1",
95
+ "@instructure/ui-tray": "^7.22.1",
96
+ "@instructure/ui-truncate-text": "^7.22.1",
97
+ "@instructure/ui-utils": "^7.22.1",
98
+ "@instructure/ui-view": "^7.22.1",
100
99
  "aws-sdk": "^2.3.2",
101
100
  "classnames": "^2.2.5",
102
101
  "content-disposition": "^0.5.2",
@@ -110,7 +109,7 @@
110
109
  "file-saver": "~2.0.5",
111
110
  "humps": "^2.0.0",
112
111
  "immutable": "^3.8.1",
113
- "instructure-validations": "18.7.1-alpha.0+33092c184",
112
+ "instructure-validations": "18.7.1-rc.1+c0cfb2272",
114
113
  "ipaddr.js": "^1.5.4",
115
114
  "isomorphic-fetch": "^2.2.0",
116
115
  "isuuid": "^0.1.0",
@@ -143,7 +142,7 @@
143
142
  },
144
143
  "devDependencies": {
145
144
  "@instructure/quiz-scripts": "18.7.0",
146
- "@instructure/ui-axe-check": "^8.48.2",
145
+ "@instructure/ui-axe-check": "^7.22.1",
147
146
  "@instructure/ui-babel-preset": "^7.22.1",
148
147
  "@instructure/ui-karma-config": "^7.22.1",
149
148
  "@instructure/ui-postcss-config": "^7.22.1",
@@ -161,7 +160,7 @@
161
160
  "intl": "^1.2.4",
162
161
  "jquery": "^2.2.3",
163
162
  "most-subject": "^5.3.0",
164
- "quiz-presets": "18.7.1-alpha.0+33092c184",
163
+ "quiz-presets": "18.7.1-rc.1+c0cfb2272",
165
164
  "react": "^16.8.6",
166
165
  "react-addons-test-utils": "^15.6.2",
167
166
  "react-dom": "^16.8.6",
@@ -177,5 +176,5 @@
177
176
  "publishConfig": {
178
177
  "access": "public"
179
178
  },
180
- "gitHead": "33092c1843a8616f0f0ca8e814a0ea78a9992d21"
179
+ "gitHead": "c0cfb227237518ef49a084eb0baf125c0218deda"
181
180
  }