dce-reactkit 1.0.20 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +95 -0
- package/lib/components/LoadingSpinner.d.ts +7 -0
- package/lib/components/LoadingSpinner.js +39 -0
- package/lib/components/LoadingSpinner.js.map +1 -0
- package/lib/components/Modal.d.ts +69 -0
- package/lib/components/Modal.js +311 -0
- package/lib/components/Modal.js.map +1 -0
- package/lib/helpers/abbreviate.d.ts +9 -0
- package/lib/helpers/abbreviate.js +21 -0
- package/lib/helpers/abbreviate.js.map +1 -0
- package/lib/helpers/avg.d.ts +8 -0
- package/lib/helpers/avg.js +24 -0
- package/lib/helpers/avg.js.map +1 -0
- package/lib/helpers/ceilToNumDecimals.d.ts +9 -0
- package/lib/helpers/ceilToNumDecimals.js +15 -0
- package/lib/helpers/ceilToNumDecimals.js.map +1 -0
- package/lib/helpers/floorToNumDecimals.d.ts +9 -0
- package/lib/helpers/floorToNumDecimals.js +15 -0
- package/lib/helpers/floorToNumDecimals.js.map +1 -0
- package/lib/helpers/forceNumIntoBounds.d.ts +10 -0
- package/lib/helpers/forceNumIntoBounds.js +15 -0
- package/lib/helpers/forceNumIntoBounds.js.map +1 -0
- package/lib/helpers/padDecimalZeros.d.ts +10 -0
- package/lib/helpers/padDecimalZeros.js +30 -0
- package/lib/helpers/padDecimalZeros.js.map +1 -0
- package/lib/helpers/padZerosLeft.d.ts +9 -0
- package/lib/helpers/padZerosLeft.js +21 -0
- package/lib/helpers/padZerosLeft.js.map +1 -0
- package/lib/helpers/roundToNumDecimals.d.ts +9 -0
- package/lib/helpers/roundToNumDecimals.js +15 -0
- package/lib/helpers/roundToNumDecimals.js.map +1 -0
- package/lib/helpers/sum.d.ts +8 -0
- package/lib/helpers/sum.js +15 -0
- package/lib/helpers/sum.js.map +1 -0
- package/lib/helpers/waitMs.d.ts +7 -0
- package/lib/helpers/waitMs.js +55 -0
- package/lib/helpers/waitMs.js.map +1 -0
- package/lib/types/Variant.d.ts +15 -0
- package/lib/types/Variant.js +19 -0
- package/lib/types/Variant.js.map +1 -0
- package/package.json +22 -40
- package/src/components/LoadingSpinner.scss +50 -0
- package/src/components/LoadingSpinner.tsx +50 -0
- package/src/components/Modal.scss +48 -0
- package/src/components/Modal.tsx +391 -0
- package/src/helpers/abbreviate.tsx +23 -0
- package/src/helpers/avg.tsx +22 -0
- package/src/helpers/ceilToNumDecimals.tsx +13 -0
- package/src/helpers/floorToNumDecimals.tsx +13 -0
- package/src/helpers/forceNumIntoBounds.tsx +19 -0
- package/src/helpers/padDecimalZeros.tsx +32 -0
- package/src/helpers/padZerosLeft.tsx +21 -0
- package/src/helpers/roundToNumDecimals.tsx +13 -0
- package/src/helpers/sum.tsx +16 -0
- package/src/helpers/waitMs.tsx +12 -0
- package/src/types/Variant.tsx +16 -0
- package/tsconfig.json +24 -0
- package/index.js +0 -1
- package/lib/Bar.js +0 -169
- package/lib/Donut.js +0 -145
- package/lib/DownloadButton.js +0 -81
- package/lib/Histogram.js +0 -193
- package/lib/Scatter.js +0 -162
- package/lib/StackedBar.js +0 -243
- package/lib/common/chart/Holder/index.js +0 -182
- package/lib/common/chart/Holder/style.css +0 -41
- package/lib/common/chart/colors.js +0 -12
- package/lib/common/csvToString.js +0 -23
- package/lib/common/isFloat.js +0 -14
- package/lib/common/isInteger.js +0 -24
- package/lib/common/math.js +0 -21
- package/lib/common/validators.js +0 -18
- package/lib/glyph/Adjust.js +0 -13
- package/lib/glyph/Angle.js +0 -44
- package/lib/glyph/Archive.js +0 -13
- package/lib/glyph/Arrow.js +0 -49
- package/lib/glyph/ArrowsHorizontal.js +0 -13
- package/lib/glyph/ArrowsVertical.js +0 -13
- package/lib/glyph/Award.js +0 -13
- package/lib/glyph/Ban.js +0 -13
- package/lib/glyph/Barcode.js +0 -13
- package/lib/glyph/Bed.js +0 -13
- package/lib/glyph/Bell.js +0 -35
- package/lib/glyph/Bolt.js +0 -13
- package/lib/glyph/Bookmark.js +0 -37
- package/lib/glyph/Bug.js +0 -13
- package/lib/glyph/Calendar.js +0 -13
- package/lib/glyph/Check.js +0 -36
- package/lib/glyph/Checkbox.js +0 -40
- package/lib/glyph/Chevron.js +0 -63
- package/lib/glyph/Circle.js +0 -15
- package/lib/glyph/Cog.js +0 -13
- package/lib/glyph/DoubleAngle.js +0 -45
- package/lib/glyph/Download.js +0 -13
- package/lib/glyph/Ellipsis.js +0 -36
- package/lib/glyph/Envelope.js +0 -13
- package/lib/glyph/File.js +0 -37
- package/lib/glyph/IdCard.js +0 -13
- package/lib/glyph/Menu.js +0 -13
- package/lib/glyph/Minus.js +0 -13
- package/lib/glyph/Move.js +0 -13
- package/lib/glyph/Plus.js +0 -13
- package/lib/glyph/Square.js +0 -47
- package/lib/glyph/Teacher.js +0 -13
- package/lib/glyph/TextAlign.js +0 -53
- package/lib/glyph/Times.js +0 -36
- package/lib/glyph/WarningTriangle.js +0 -13
- package/lib/index.js +0 -1
- package/src-old/common/csvToString.js +0 -5
- package/src-old/common/isFloat.js +0 -3
- package/src-old/common/isInteger.js +0 -14
- package/src-old/common/math.js +0 -16
- package/src-old/common/validators.js +0 -14
- package/src-old/components/Alert.js +0 -79
- package/src-old/components/Button.js +0 -64
- package/src-old/components/CSV/autoMatch.js +0 -174
- package/src-old/components/CSV/getNumCols.js +0 -15
- package/src-old/components/CSV/index.js +0 -743
- package/src-old/components/Card.js +0 -64
- package/src-old/components/Chart/Bar.js +0 -169
- package/src-old/components/Chart/Donut.js +0 -160
- package/src-old/components/Chart/Histogram.js +0 -189
- package/src-old/components/Chart/Scatter.js +0 -162
- package/src-old/components/Chart/colors.js +0 -20
- package/src-old/components/Checkbox/index.js +0 -106
- package/src-old/components/Checkbox/style.css +0 -11
- package/src-old/components/DatePicker.js +0 -59
- package/src-old/components/DownloadButton.js +0 -72
- package/src-old/components/Dropdown.js +0 -120
- package/src-old/components/Layout/LeftAddon.js +0 -63
- package/src-old/components/Layout/RightAddon.js +0 -64
- package/src-old/components/Layout/TwoCol.js +0 -67
- package/src-old/components/Modal.js +0 -161
- package/src-old/components/PhotoRoster.js +0 -152
- package/src-old/components/Pills.js +0 -117
- package/src-old/components/Radio.js +0 -94
- package/src-old/components/Splash/Error.js +0 -62
- package/src-old/components/Splash/Load/index.js +0 -32
- package/src-old/components/Splash/Load/style.css +0 -51
- package/src-old/components/Stat/General.js +0 -252
- package/src-old/components/Stat/helpers/calcAverage.js +0 -20
- package/src-old/components/Stat/helpers/calcExtremes.js +0 -27
- package/src-old/components/Stat/helpers/calcMedian.js +0 -32
- package/src-old/components/Stat/helpers/calcStdDev.js +0 -30
- package/src-old/components/Stat/helpers/calcSum.js +0 -8
- package/src-old/components/UserProfile/index.js +0 -151
- package/src-old/components/UserProfile/style.css +0 -33
- package/src-old/components/Well.js +0 -28
- package/src-old/components/Wizard/Question/CSV.js +0 -307
- package/src-old/components/Wizard/Question/Chooser/Assignment.js +0 -108
- package/src-old/components/Wizard/Question/Chooser/Course.js +0 -214
- package/src-old/components/Wizard/Question/Chooser/helpers/divideIntoSections.js +0 -16
- package/src-old/components/Wizard/Question/Chooser/helpers/genGetItemsPromise.js +0 -20
- package/src-old/components/Wizard/Question/Chooser/helpers/preprocessSections.js +0 -36
- package/src-old/components/Wizard/Question/Chooser/index.js +0 -306
- package/src-old/components/Wizard/Question/Form/Field/CheckableItem.js +0 -155
- package/src-old/components/Wizard/Question/Form/Field/Input.js +0 -149
- package/src-old/components/Wizard/Question/Form/Field/NumberItem.js +0 -374
- package/src-old/components/Wizard/Question/Form/Field/index.js +0 -34
- package/src-old/components/Wizard/Question/Form/Field/readme.md +0 -7
- package/src-old/components/Wizard/Question/Form/index.js +0 -175
- package/src-old/components/Wizard/Question/Form/style.css +0 -3
- package/src-old/components/Wizard/Question/OneButton.js +0 -80
- package/src-old/components/Wizard/Question/index.js +0 -46
- package/src-old/components/Wizard/Question/readme.md +0 -10
- package/src-old/components/Wizard/QuestionGroup/AnswerAll.js +0 -126
- package/src-old/components/Wizard/QuestionGroup/AnswerAny.js +0 -60
- package/src-old/components/Wizard/index.js +0 -233
- package/src-old/components/Wizard/style.css +0 -21
- package/src-old/glyphs/Adjust.js +0 -13
- package/src-old/glyphs/Angle.js +0 -57
- package/src-old/glyphs/Archive.js +0 -13
- package/src-old/glyphs/Arrow.js +0 -85
- package/src-old/glyphs/ArrowsHorizontal.js +0 -13
- package/src-old/glyphs/ArrowsVertical.js +0 -13
- package/src-old/glyphs/Award.js +0 -13
- package/src-old/glyphs/Ban.js +0 -13
- package/src-old/glyphs/Barcode.js +0 -13
- package/src-old/glyphs/Bed.js +0 -13
- package/src-old/glyphs/Bell.js +0 -34
- package/src-old/glyphs/Bolt.js +0 -13
- package/src-old/glyphs/Bookmark.js +0 -36
- package/src-old/glyphs/Bug.js +0 -13
- package/src-old/glyphs/Calendar.js +0 -13
- package/src-old/glyphs/Check.js +0 -34
- package/src-old/glyphs/Checkbox.js +0 -42
- package/src-old/glyphs/Chevron.js +0 -88
- package/src-old/glyphs/Circle.js +0 -16
- package/src-old/glyphs/Cog.js +0 -13
- package/src-old/glyphs/DoubleAngle.js +0 -58
- package/src-old/glyphs/Download.js +0 -13
- package/src-old/glyphs/Ellipsis.js +0 -35
- package/src-old/glyphs/Envelope.js +0 -13
- package/src-old/glyphs/File.js +0 -40
- package/src-old/glyphs/IdCard.js +0 -13
- package/src-old/glyphs/Menu.js +0 -13
- package/src-old/glyphs/Minus.js +0 -13
- package/src-old/glyphs/Move.js +0 -13
- package/src-old/glyphs/Plus.js +0 -13
- package/src-old/glyphs/Square.js +0 -48
- package/src-old/glyphs/Teacher.js +0 -13
- package/src-old/glyphs/TextAlign.js +0 -58
- package/src-old/glyphs/Times.js +0 -34
- package/src-old/glyphs/WarningTriangle.js +0 -13
- package/src-old/index.js +0 -1
|
@@ -1,307 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import CSVParser from 'papaparse';
|
|
4
|
-
import genUUID from 'uuid/v1';
|
|
5
|
-
|
|
6
|
-
// Import bootstrap components
|
|
7
|
-
import { Label, Input } from 'reactstrap';
|
|
8
|
-
// Import bootstrap stylesheet
|
|
9
|
-
import 'bootstrap/dist/css/bootstrap.min.css';
|
|
10
|
-
|
|
11
|
-
// Import other components
|
|
12
|
-
import CSVPreview from '../../CSV';
|
|
13
|
-
import Alert from '../../Alert';
|
|
14
|
-
import Button from '../../Button';
|
|
15
|
-
import LoadSplash from '../../Splash/Load';
|
|
16
|
-
import ErrorSplash from '../../Splash/Error';
|
|
17
|
-
import Question from '.';
|
|
18
|
-
|
|
19
|
-
// Import glyphs
|
|
20
|
-
import File from '../../../glyphs/File';
|
|
21
|
-
import Chevron from '../../../glyphs/Chevron';
|
|
22
|
-
import Check from '../../../glyphs/Check';
|
|
23
|
-
|
|
24
|
-
const STAGE = {
|
|
25
|
-
CHOOSING_FILE: 1,
|
|
26
|
-
PROCESSING_FILE: 2,
|
|
27
|
-
MATCHING_COLUMNS: 3,
|
|
28
|
-
PREVIEW: 4,
|
|
29
|
-
ERROR: 6,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* onAnswered is called with the following:
|
|
34
|
-
* {
|
|
35
|
-
* header: list of header column names
|
|
36
|
-
* data: row object { header: column cell value }
|
|
37
|
-
* }
|
|
38
|
-
*/
|
|
39
|
-
|
|
40
|
-
class CSV extends Component {
|
|
41
|
-
constructor(props) {
|
|
42
|
-
super(props);
|
|
43
|
-
|
|
44
|
-
this.id = genUUID();
|
|
45
|
-
|
|
46
|
-
// Initialize state
|
|
47
|
-
this.state = {
|
|
48
|
-
stage: STAGE.CHOOSING_FILE,
|
|
49
|
-
csv: [],
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// Bind functions
|
|
53
|
-
this.endChoosingFileStage = this.endChoosingFileStage.bind(this);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
endChoosingFileStage(file) {
|
|
57
|
-
// Deconstruct props
|
|
58
|
-
const {
|
|
59
|
-
noHeader,
|
|
60
|
-
noPreview,
|
|
61
|
-
onAnswered,
|
|
62
|
-
headersToMatch, // [{ key, title, description, required, validator }]
|
|
63
|
-
} = this.props;
|
|
64
|
-
|
|
65
|
-
// Determine the next stage
|
|
66
|
-
let nextStage;
|
|
67
|
-
if (headersToMatch) {
|
|
68
|
-
nextStage = STAGE.MATCHING_COLUMNS;
|
|
69
|
-
} else {
|
|
70
|
-
nextStage = STAGE.PREVIEW;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Set state
|
|
74
|
-
this.setState({
|
|
75
|
-
stage: STAGE.PROCESSING_FILE,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// Advance to next stage
|
|
79
|
-
CSVParser.parse(file, {
|
|
80
|
-
header: !noHeader,
|
|
81
|
-
complete: (results) => {
|
|
82
|
-
// CSV processed successfully
|
|
83
|
-
|
|
84
|
-
// Deconstruct results from csv parser
|
|
85
|
-
const {
|
|
86
|
-
data,
|
|
87
|
-
errors,
|
|
88
|
-
meta,
|
|
89
|
-
} = results;
|
|
90
|
-
|
|
91
|
-
// Check for errors
|
|
92
|
-
let csv;
|
|
93
|
-
if (errors && errors.length > 0) {
|
|
94
|
-
// An error occurred
|
|
95
|
-
nextStage = STAGE.ERROR;
|
|
96
|
-
} else {
|
|
97
|
-
// Build csv file
|
|
98
|
-
csv = {
|
|
99
|
-
data,
|
|
100
|
-
headers: meta.fields,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// If next stage is preview but noPreview is true, just finish
|
|
105
|
-
if (nextStage === STAGE.PREVIEW && noPreview) {
|
|
106
|
-
// Just finish now
|
|
107
|
-
onAnswered(csv);
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Save results and move on to next stage
|
|
112
|
-
this.setState({
|
|
113
|
-
csv,
|
|
114
|
-
stage: nextStage,
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
render() {
|
|
121
|
-
// Deconstruct props
|
|
122
|
-
const {
|
|
123
|
-
title,
|
|
124
|
-
subtitle,
|
|
125
|
-
uploadButtonTitle,
|
|
126
|
-
noHeader,
|
|
127
|
-
headersToMatch,
|
|
128
|
-
onAnswered,
|
|
129
|
-
} = this.props;
|
|
130
|
-
|
|
131
|
-
// Deconstruct state
|
|
132
|
-
const {
|
|
133
|
-
stage,
|
|
134
|
-
csv,
|
|
135
|
-
} = this.state;
|
|
136
|
-
|
|
137
|
-
let body;
|
|
138
|
-
|
|
139
|
-
// Error
|
|
140
|
-
if (stage === STAGE.ERROR) {
|
|
141
|
-
body = (
|
|
142
|
-
<ErrorSplash
|
|
143
|
-
title="Invalid CSV"
|
|
144
|
-
body="The CSV you chose could not be processed. Please check your CSV file and try again."
|
|
145
|
-
buttons={[{
|
|
146
|
-
text: 'Try Again',
|
|
147
|
-
onClick: () => {
|
|
148
|
-
this.setState({
|
|
149
|
-
stage: STAGE.CHOOSING_FILE,
|
|
150
|
-
});
|
|
151
|
-
},
|
|
152
|
-
}]}
|
|
153
|
-
/>
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// File chooser
|
|
158
|
-
if (stage === STAGE.CHOOSING_FILE) {
|
|
159
|
-
body = (
|
|
160
|
-
<div className="text-center">
|
|
161
|
-
<Label className="btn btn-info btn-lg" for={this.id}>
|
|
162
|
-
<File
|
|
163
|
-
type="csv"
|
|
164
|
-
className="mr-2"
|
|
165
|
-
/>
|
|
166
|
-
{uploadButtonTitle}
|
|
167
|
-
<Input
|
|
168
|
-
type="file"
|
|
169
|
-
accept=".csv"
|
|
170
|
-
id={this.id}
|
|
171
|
-
className="d-none"
|
|
172
|
-
onChange={(e) => {
|
|
173
|
-
this.endChoosingFileStage(e.target.files[0]);
|
|
174
|
-
}}
|
|
175
|
-
/>
|
|
176
|
-
</Label>
|
|
177
|
-
</div>
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Processing file
|
|
182
|
-
if (stage === STAGE.PROCESSING_FILE) {
|
|
183
|
-
body = (
|
|
184
|
-
<LoadSplash
|
|
185
|
-
message="Processing CSV"
|
|
186
|
-
/>
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Preview
|
|
191
|
-
if (stage === STAGE.PREVIEW) {
|
|
192
|
-
body = (
|
|
193
|
-
<div>
|
|
194
|
-
<Alert
|
|
195
|
-
color="info"
|
|
196
|
-
className="text-center"
|
|
197
|
-
>
|
|
198
|
-
<h3>
|
|
199
|
-
CSV Preview
|
|
200
|
-
</h3>
|
|
201
|
-
Please double check the preview below before continuing.
|
|
202
|
-
<div
|
|
203
|
-
className="mt-2"
|
|
204
|
-
>
|
|
205
|
-
<Button
|
|
206
|
-
text={(
|
|
207
|
-
<span>
|
|
208
|
-
<Chevron direction="left" className="mr-2" />
|
|
209
|
-
Choose New File
|
|
210
|
-
</span>
|
|
211
|
-
)}
|
|
212
|
-
onClick={() => {
|
|
213
|
-
this.setState({
|
|
214
|
-
stage: STAGE.CHOOSING_FILE,
|
|
215
|
-
});
|
|
216
|
-
}}
|
|
217
|
-
className="mr-2"
|
|
218
|
-
color="secondary"
|
|
219
|
-
size="lg"
|
|
220
|
-
/>
|
|
221
|
-
<Button
|
|
222
|
-
color="success"
|
|
223
|
-
size="lg"
|
|
224
|
-
onClick={() => {
|
|
225
|
-
onAnswered(csv);
|
|
226
|
-
}}
|
|
227
|
-
>
|
|
228
|
-
<Check
|
|
229
|
-
className="mr-2"
|
|
230
|
-
/>
|
|
231
|
-
Looks Good
|
|
232
|
-
</Button>
|
|
233
|
-
</div>
|
|
234
|
-
</Alert>
|
|
235
|
-
<CSVPreview
|
|
236
|
-
noHeader={noHeader}
|
|
237
|
-
csv={csv}
|
|
238
|
-
numRowsToPreview={4}
|
|
239
|
-
onReupload={() => {
|
|
240
|
-
this.setState({
|
|
241
|
-
stage: STAGE.CHOOSING_FILE,
|
|
242
|
-
});
|
|
243
|
-
}}
|
|
244
|
-
/>
|
|
245
|
-
</div>
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Matching
|
|
250
|
-
if (stage === STAGE.MATCHING_COLUMNS) {
|
|
251
|
-
body = (
|
|
252
|
-
<CSVPreview
|
|
253
|
-
noHeader={noHeader}
|
|
254
|
-
csv={csv}
|
|
255
|
-
numRowsToPreview={4}
|
|
256
|
-
headersToMatch={headersToMatch}
|
|
257
|
-
onReupload={() => {
|
|
258
|
-
this.setState({
|
|
259
|
-
stage: STAGE.CHOOSING_FILE,
|
|
260
|
-
});
|
|
261
|
-
}}
|
|
262
|
-
onFinished={(newCSV) => {
|
|
263
|
-
onAnswered(newCSV);
|
|
264
|
-
}}
|
|
265
|
-
/>
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Render the question with its appropriate body
|
|
270
|
-
return (
|
|
271
|
-
<Question
|
|
272
|
-
title={title}
|
|
273
|
-
subtitle={subtitle}
|
|
274
|
-
>
|
|
275
|
-
{body}
|
|
276
|
-
</Question>
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
CSV.propTypes = {
|
|
282
|
-
/* The title of the question */
|
|
283
|
-
title: PropTypes.string,
|
|
284
|
-
/* The subtitle of the question */
|
|
285
|
-
subtitle: PropTypes.string,
|
|
286
|
-
/* The title of the "upload file" button */
|
|
287
|
-
uploadButtonTitle: PropTypes.string,
|
|
288
|
-
/* If true, we don't use the first row of the csv as a header row */
|
|
289
|
-
noHeader: PropTypes.bool,
|
|
290
|
-
/* If true and no matching is occurring, no preview will be shown */
|
|
291
|
-
noPreview: PropTypes.bool,
|
|
292
|
-
/* A function to call when the csv is properly uploaded and processed */
|
|
293
|
-
onAnswered: PropTypes.func.isRequired,
|
|
294
|
-
/* For full description of headersToMatch, see /autoMatch.js */
|
|
295
|
-
headersToMatch: PropTypes.arrayOf(PropTypes.object),
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
CSV.defaultProps = {
|
|
299
|
-
title: 'Upload CSV',
|
|
300
|
-
subtitle: null,
|
|
301
|
-
uploadButtonTitle: 'Choose File',
|
|
302
|
-
noHeader: false,
|
|
303
|
-
noPreview: false,
|
|
304
|
-
headersToMatch: null,
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
export default CSV;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import initCACCL from 'caccl/client/cached';
|
|
4
|
-
import CACCLInstance from 'caccl/APIInstanceClass';
|
|
5
|
-
|
|
6
|
-
// Import other components
|
|
7
|
-
import Chooser from '.';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* onAnswered is called with the following:
|
|
11
|
-
* {
|
|
12
|
-
* dropdownItem: dropdownItems[].name OR undefined (if choose button clicked),
|
|
13
|
-
* value: the chosen assignment
|
|
14
|
-
* }
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
class AssignmentChooser extends Component {
|
|
18
|
-
render() {
|
|
19
|
-
// Deconstruct props
|
|
20
|
-
const {
|
|
21
|
-
title,
|
|
22
|
-
subtitle,
|
|
23
|
-
courseId,
|
|
24
|
-
onAnswered,
|
|
25
|
-
loadMessage,
|
|
26
|
-
buttonTitle,
|
|
27
|
-
buttonColor,
|
|
28
|
-
dropdownTitle,
|
|
29
|
-
dropdownColor,
|
|
30
|
-
dropdownItems,
|
|
31
|
-
filter,
|
|
32
|
-
api,
|
|
33
|
-
} = this.props;
|
|
34
|
-
|
|
35
|
-
// Set up chooser
|
|
36
|
-
const getItems = () => {
|
|
37
|
-
return api.course.assignment.list({ courseId })
|
|
38
|
-
.then((assignments) => {
|
|
39
|
-
if (filter) {
|
|
40
|
-
return assignments.filter(filter);
|
|
41
|
-
}
|
|
42
|
-
return assignments;
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// Render a chooser
|
|
47
|
-
return (
|
|
48
|
-
<Chooser
|
|
49
|
-
title={title || 'Choose an Assignment'}
|
|
50
|
-
subtitle={subtitle}
|
|
51
|
-
getItems={getItems}
|
|
52
|
-
onAnswered={onAnswered}
|
|
53
|
-
buttonTitle={buttonTitle}
|
|
54
|
-
buttonColor={buttonColor}
|
|
55
|
-
dropdownTitle={dropdownTitle}
|
|
56
|
-
dropdownColor={dropdownColor}
|
|
57
|
-
dropdownItems={dropdownItems}
|
|
58
|
-
loadMessage={loadMessage || 'Waiting on Canvas'}
|
|
59
|
-
/>
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
AssignmentChooser.propTypes = {
|
|
65
|
-
/* Title of the chooser */
|
|
66
|
-
title: PropTypes.string,
|
|
67
|
-
/* Subtitle of the chooser */
|
|
68
|
-
subtitle: PropTypes.string,
|
|
69
|
-
/* The course ID to query for assignments */
|
|
70
|
-
courseId: PropTypes.number.isRequired,
|
|
71
|
-
/* Filter function (for assignments.filter) to filter the assignment list */
|
|
72
|
-
filter: PropTypes.func,
|
|
73
|
-
/* Handler for when the question is answered */
|
|
74
|
-
onAnswered: PropTypes.func.isRequired,
|
|
75
|
-
/* Message to display while loading assignments */
|
|
76
|
-
loadMessage: PropTypes.string,
|
|
77
|
-
/* Title of the "choose" button (also displayed if no dropdown) */
|
|
78
|
-
buttonTitle: PropTypes.string,
|
|
79
|
-
/* Color of the "choose" button (also displayed if no dropdown) */
|
|
80
|
-
buttonColor: PropTypes.string,
|
|
81
|
-
/* Title of the dropdown menu (not displayed if no dropdown items) */
|
|
82
|
-
dropdownTitle: PropTypes.string,
|
|
83
|
-
/* Color of the dropdown menu (not displayed if no dropdown items) */
|
|
84
|
-
dropdownColor: PropTypes.string,
|
|
85
|
-
/* Dropdown items (mostly same definition as those in /components/Dropdown)
|
|
86
|
-
* but also an additional 'name' prop that is passed when the dropdown is
|
|
87
|
-
* clicked. */
|
|
88
|
-
dropdownItems: PropTypes.arrayOf(PropTypes.object),
|
|
89
|
-
/* CACCL instance to use to get the list of assignment */
|
|
90
|
-
api: PropTypes.instanceOf(CACCLInstance),
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const { api } = initCACCL();
|
|
94
|
-
|
|
95
|
-
AssignmentChooser.defaultProps = {
|
|
96
|
-
api,
|
|
97
|
-
title: 'Choose an Assignment:',
|
|
98
|
-
subtitle: null,
|
|
99
|
-
filter: null,
|
|
100
|
-
loadMessage: 'Waiting on Canvas',
|
|
101
|
-
buttonTitle: 'Choose',
|
|
102
|
-
buttonColor: 'info',
|
|
103
|
-
dropdownTitle: null,
|
|
104
|
-
dropdownColor: null,
|
|
105
|
-
dropdownItems: null,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
export default AssignmentChooser;
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import React, { Component } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import initCACCL from 'caccl/client/cached';
|
|
4
|
-
import CACCLInstance from 'caccl/APIInstanceClass';
|
|
5
|
-
|
|
6
|
-
// Import other components
|
|
7
|
-
import Chooser from '.';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* onAnswered is called with the following:
|
|
11
|
-
* {
|
|
12
|
-
* dropdownItem: dropdownItems[].name OR undefined (if choose button clicked),
|
|
13
|
-
* value: the chosen course
|
|
14
|
-
* }
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
class CourseChooser extends Component {
|
|
18
|
-
render() {
|
|
19
|
-
// Deconstruct props
|
|
20
|
-
const {
|
|
21
|
-
title,
|
|
22
|
-
subtitle,
|
|
23
|
-
onAnswered,
|
|
24
|
-
loadMessage,
|
|
25
|
-
buttonTitle,
|
|
26
|
-
buttonColor,
|
|
27
|
-
dropdownTitle,
|
|
28
|
-
dropdownColor,
|
|
29
|
-
dropdownItems,
|
|
30
|
-
filter,
|
|
31
|
-
api,
|
|
32
|
-
} = this.props;
|
|
33
|
-
|
|
34
|
-
// Set up chooser
|
|
35
|
-
const getItems = () => {
|
|
36
|
-
return api.user.self.listCourses({ includeTerm: true })
|
|
37
|
-
.then((courses) => {
|
|
38
|
-
// Filter courses
|
|
39
|
-
let filteredCourses = courses;
|
|
40
|
-
if (filter) {
|
|
41
|
-
filteredCourses = courses.filter(filter);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Pre-process courses
|
|
45
|
-
// > Add user's role
|
|
46
|
-
// > Divide into terms
|
|
47
|
-
const terms = {}; // Name to [] list of courses
|
|
48
|
-
filteredCourses.forEach((course) => {
|
|
49
|
-
const updatedCourse = course;
|
|
50
|
-
// Get role in course
|
|
51
|
-
updatedCourse.subtitle = 'You\'re a member of this course.';
|
|
52
|
-
if (
|
|
53
|
-
course.enrollments
|
|
54
|
-
&& course.enrollments.length > 0
|
|
55
|
-
) {
|
|
56
|
-
let isTeacher;
|
|
57
|
-
let isTA;
|
|
58
|
-
let isDesigner;
|
|
59
|
-
let isStudent;
|
|
60
|
-
let isObserver;
|
|
61
|
-
course.enrollments.forEach((enrollment) => {
|
|
62
|
-
switch (enrollment.type) {
|
|
63
|
-
case 'teacher':
|
|
64
|
-
isTeacher = true;
|
|
65
|
-
break;
|
|
66
|
-
case 'ta':
|
|
67
|
-
isTA = true;
|
|
68
|
-
break;
|
|
69
|
-
case 'designer':
|
|
70
|
-
isDesigner = true;
|
|
71
|
-
break;
|
|
72
|
-
case 'student':
|
|
73
|
-
isStudent = true;
|
|
74
|
-
break;
|
|
75
|
-
case 'observer':
|
|
76
|
-
isObserver = true;
|
|
77
|
-
break;
|
|
78
|
-
default:
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
if (isTeacher) {
|
|
83
|
-
updatedCourse.subtitle = (
|
|
84
|
-
<span>
|
|
85
|
-
You're a
|
|
86
|
-
<em> teacher </em>
|
|
87
|
-
in this course.
|
|
88
|
-
</span>
|
|
89
|
-
);
|
|
90
|
-
} else if (isTA) {
|
|
91
|
-
updatedCourse.subtitle = (
|
|
92
|
-
<span>
|
|
93
|
-
You're a
|
|
94
|
-
<em> TA </em>
|
|
95
|
-
in this course.
|
|
96
|
-
</span>
|
|
97
|
-
);
|
|
98
|
-
} else if (isDesigner) {
|
|
99
|
-
updatedCourse.subtitle = (
|
|
100
|
-
<span>
|
|
101
|
-
You're a
|
|
102
|
-
<em> designer </em>
|
|
103
|
-
for this course.
|
|
104
|
-
</span>
|
|
105
|
-
);
|
|
106
|
-
} else if (isStudent) {
|
|
107
|
-
updatedCourse.subtitle = (
|
|
108
|
-
<span>
|
|
109
|
-
You're a
|
|
110
|
-
<em> student </em>
|
|
111
|
-
in this course.
|
|
112
|
-
</span>
|
|
113
|
-
);
|
|
114
|
-
} else if (isObserver) {
|
|
115
|
-
updatedCourse.subtitle = (
|
|
116
|
-
<span>
|
|
117
|
-
You're an
|
|
118
|
-
<em> observer </em>
|
|
119
|
-
of this course.
|
|
120
|
-
</span>
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Prepare the term
|
|
126
|
-
const termName = course.term.name;
|
|
127
|
-
if (!terms[termName]) {
|
|
128
|
-
terms[termName] = {
|
|
129
|
-
title: termName,
|
|
130
|
-
items: [],
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
terms[termName].items.push(updatedCourse);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
// Sort terms
|
|
137
|
-
const termsList = Object.values(terms);
|
|
138
|
-
function _compareFunction(a, b) {
|
|
139
|
-
if (a.title < b.title) {
|
|
140
|
-
return 1;
|
|
141
|
-
}
|
|
142
|
-
if (a.title > b.title) {
|
|
143
|
-
return -1;
|
|
144
|
-
}
|
|
145
|
-
return 0;
|
|
146
|
-
}
|
|
147
|
-
termsList.sort(_compareFunction);
|
|
148
|
-
|
|
149
|
-
// Resolve with list of terms
|
|
150
|
-
return Promise.resolve(termsList);
|
|
151
|
-
});
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
// Render a chooser
|
|
155
|
-
return (
|
|
156
|
-
<Chooser
|
|
157
|
-
title={title || 'Choose a Course'}
|
|
158
|
-
subtitle={subtitle}
|
|
159
|
-
getItems={getItems}
|
|
160
|
-
onAnswered={onAnswered}
|
|
161
|
-
buttonTitle={buttonTitle}
|
|
162
|
-
buttonColor={buttonColor}
|
|
163
|
-
dropdownTitle={dropdownTitle}
|
|
164
|
-
dropdownColor={dropdownColor}
|
|
165
|
-
dropdownItems={dropdownItems}
|
|
166
|
-
loadMessage={loadMessage || 'Waiting on Canvas'}
|
|
167
|
-
/>
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
CourseChooser.propTypes = {
|
|
173
|
-
/* Title of the chooser */
|
|
174
|
-
title: PropTypes.string,
|
|
175
|
-
/* Subtitle of the chooser */
|
|
176
|
-
subtitle: PropTypes.string,
|
|
177
|
-
/* Filter function (for courses.filter) to filter the course list */
|
|
178
|
-
filter: PropTypes.func,
|
|
179
|
-
/* Handler for when the question is answered */
|
|
180
|
-
onAnswered: PropTypes.func.isRequired,
|
|
181
|
-
/* Message to display while loading courses */
|
|
182
|
-
loadMessage: PropTypes.string,
|
|
183
|
-
/* Title of the "choose" button (also displayed if no dropdown) */
|
|
184
|
-
buttonTitle: PropTypes.string,
|
|
185
|
-
/* Color of the "choose" button (also displayed if no dropdown) */
|
|
186
|
-
buttonColor: PropTypes.string,
|
|
187
|
-
/* Title of the dropdown menu (not displayed if no dropdown items) */
|
|
188
|
-
dropdownTitle: PropTypes.string,
|
|
189
|
-
/* Color of the dropdown menu (not displayed if no dropdown items) */
|
|
190
|
-
dropdownColor: PropTypes.string,
|
|
191
|
-
/* Dropdown items (mostly same definition as those in /components/Dropdown)
|
|
192
|
-
* but also an additional 'name' prop that is passed when the dropdown is
|
|
193
|
-
* clicked. */
|
|
194
|
-
dropdownItems: PropTypes.arrayOf(PropTypes.object),
|
|
195
|
-
/* CACCL instance to use to get the list of assignment */
|
|
196
|
-
api: PropTypes.instanceOf(CACCLInstance),
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const { api } = initCACCL();
|
|
200
|
-
|
|
201
|
-
CourseChooser.defaultProps = {
|
|
202
|
-
api,
|
|
203
|
-
title: 'Choose a Course:',
|
|
204
|
-
subtitle: null,
|
|
205
|
-
filter: null,
|
|
206
|
-
loadMessage: 'Waiting on Canvas',
|
|
207
|
-
buttonTitle: 'Choose',
|
|
208
|
-
buttonColor: 'info',
|
|
209
|
-
dropdownTitle: null,
|
|
210
|
-
dropdownColor: null,
|
|
211
|
-
dropdownItems: null,
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
export default CourseChooser;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// Sections are defined: [{title, items}]
|
|
2
|
-
export default (items) => {
|
|
3
|
-
// Detect sections
|
|
4
|
-
const isDividedIntoSections = (
|
|
5
|
-
items
|
|
6
|
-
&& items.length > 0
|
|
7
|
-
&& items[0].title
|
|
8
|
-
&& items[0].items
|
|
9
|
-
&& items[0].items.length > 0
|
|
10
|
-
);
|
|
11
|
-
return (
|
|
12
|
-
isDividedIntoSections
|
|
13
|
-
? items
|
|
14
|
-
: [{ items }]
|
|
15
|
-
);
|
|
16
|
-
};
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export default (items, getItems) => {
|
|
2
|
-
// Use either items or getItems (whichever is included)
|
|
3
|
-
let lst = items || getItems;
|
|
4
|
-
|
|
5
|
-
// If no items, just resolve with empty list
|
|
6
|
-
if (!lst) {
|
|
7
|
-
return Promise.resolve([]);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// Call functions if type is function
|
|
11
|
-
if (typeof lst === 'function') {
|
|
12
|
-
lst = lst();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Return a promise
|
|
16
|
-
if (lst) {
|
|
17
|
-
return Promise.resolve(lst);
|
|
18
|
-
}
|
|
19
|
-
return Promise.resolve([]);
|
|
20
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// Given an option to be displayed in a list, infer the title of the option
|
|
2
|
-
// Supports course, assignment, quiz, etc. types of Canvas objects
|
|
3
|
-
export default (sections) => {
|
|
4
|
-
return sections.map((section) => {
|
|
5
|
-
const newSection = section;
|
|
6
|
-
|
|
7
|
-
// Add titles, subtitles
|
|
8
|
-
newSection.items = section.items.map((item) => {
|
|
9
|
-
const newItem = item;
|
|
10
|
-
|
|
11
|
-
// Add basic title fields
|
|
12
|
-
newItem.title = (
|
|
13
|
-
item.title
|
|
14
|
-
|| item.name
|
|
15
|
-
|| item.description
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
// Add user-based titles
|
|
19
|
-
if (
|
|
20
|
-
!newItem.title
|
|
21
|
-
&& (item.user && item.user.name)
|
|
22
|
-
) {
|
|
23
|
-
newItem.title = item.user.name;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Add default title if no other title is added
|
|
27
|
-
if (!newItem.title) {
|
|
28
|
-
newItem.title = 'Untitled Option';
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return newItem;
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
return newSection;
|
|
35
|
-
});
|
|
36
|
-
};
|