dce-reactkit 3.0.1 → 3.0.2

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 (162) hide show
  1. package/README.md +1 -546
  2. package/dist/cjs/index.js +1782 -0
  3. package/dist/cjs/index.js.map +1 -0
  4. package/{lib/esm → dist/cjs}/types/components/AppWrapper.d.ts +26 -1
  5. package/dist/cjs/types/components/ButtonInputGroup.d.ts +12 -0
  6. package/dist/cjs/types/components/CheckboxButton.d.ts +20 -0
  7. package/{lib/cjs/lib → dist/cjs/types}/components/ErrorBox.d.ts +0 -0
  8. package/{lib/cjs/lib → dist/cjs/types}/components/LoadingSpinner.d.ts +0 -0
  9. package/{lib/cjs/lib → dist/cjs/types}/components/Modal.d.ts +0 -0
  10. package/dist/cjs/types/components/RadioButton.d.ts +20 -0
  11. package/dist/cjs/types/components/SimpleDateChooser.d.ts +22 -0
  12. package/{lib/esm/lib → dist/cjs/types}/components/TabBox.d.ts +1 -0
  13. package/{lib/cjs/lib → dist/cjs/types}/errors/ErrorWithCode.d.ts +0 -0
  14. package/{lib/cjs/lib → dist/cjs/types}/helpers/abbreviate.d.ts +0 -0
  15. package/{lib/cjs/lib → dist/cjs/types}/helpers/avg.d.ts +0 -0
  16. package/{lib/cjs/lib → dist/cjs/types}/helpers/ceilToNumDecimals.d.ts +0 -0
  17. package/{lib/cjs/lib → dist/cjs/types}/helpers/floorToNumDecimals.d.ts +0 -0
  18. package/{lib/cjs/lib → dist/cjs/types}/helpers/forceNumIntoBounds.d.ts +0 -0
  19. package/dist/cjs/types/helpers/genRouteHandler.d.ts +32 -0
  20. package/dist/cjs/types/helpers/getOrdinal.d.ts +8 -0
  21. package/dist/cjs/types/helpers/getTimeInfoInET.d.ts +17 -0
  22. package/{lib/cjs/lib → dist/cjs/types}/helpers/handleError.d.ts +5 -1
  23. package/{lib/cjs/lib → dist/cjs/types}/helpers/handleSuccess.d.ts +0 -0
  24. package/{lib/cjs/lib → dist/cjs/types}/helpers/padDecimalZeros.d.ts +0 -0
  25. package/{lib/cjs/lib → dist/cjs/types}/helpers/padZerosLeft.d.ts +0 -0
  26. package/{lib/cjs/lib → dist/cjs/types}/helpers/roundToNumDecimals.d.ts +0 -0
  27. package/{lib/cjs/lib → dist/cjs/types}/helpers/sum.d.ts +0 -0
  28. package/{lib/cjs/lib → dist/cjs/types}/helpers/visitServerEndpoint.d.ts +0 -0
  29. package/{lib/cjs/lib → dist/cjs/types}/helpers/waitMs.d.ts +0 -0
  30. package/{lib/cjs/lib → dist/cjs/types}/index.d.ts +13 -6
  31. package/dist/cjs/types/server/initServer.d.ts +21 -0
  32. package/{lib/cjs/lib → dist/cjs/types}/types/ModalButtonType.d.ts +0 -0
  33. package/{lib/cjs/lib → dist/cjs/types}/types/ModalSize.d.ts +0 -0
  34. package/{lib/cjs/lib → dist/cjs/types}/types/ModalType.d.ts +0 -0
  35. package/{lib → dist}/cjs/types/types/ParamType.d.ts +1 -1
  36. package/{lib → dist}/cjs/types/types/ReactKitErrorCode.d.ts +3 -1
  37. package/{lib/cjs/lib → dist/cjs/types}/types/Variant.d.ts +0 -0
  38. package/dist/esm/index.js +1739 -0
  39. package/dist/esm/index.js.map +1 -0
  40. package/{lib/cjs → dist/esm}/types/components/AppWrapper.d.ts +26 -1
  41. package/dist/esm/types/components/ButtonInputGroup.d.ts +12 -0
  42. package/dist/esm/types/components/CheckboxButton.d.ts +20 -0
  43. package/{lib/cjs → dist/esm}/types/components/ErrorBox.d.ts +0 -0
  44. package/{lib/cjs → dist/esm}/types/components/LoadingSpinner.d.ts +0 -0
  45. package/{lib/cjs → dist/esm}/types/components/Modal.d.ts +0 -0
  46. package/dist/esm/types/components/RadioButton.d.ts +20 -0
  47. package/dist/esm/types/components/SimpleDateChooser.d.ts +22 -0
  48. package/{lib/cjs/lib → dist/esm/types}/components/TabBox.d.ts +1 -0
  49. package/{lib/cjs → dist/esm}/types/errors/ErrorWithCode.d.ts +0 -0
  50. package/{lib/cjs → dist/esm}/types/helpers/abbreviate.d.ts +0 -0
  51. package/{lib/cjs → dist/esm}/types/helpers/avg.d.ts +0 -0
  52. package/{lib/cjs → dist/esm}/types/helpers/ceilToNumDecimals.d.ts +0 -0
  53. package/{lib/cjs → dist/esm}/types/helpers/floorToNumDecimals.d.ts +0 -0
  54. package/{lib/cjs → dist/esm}/types/helpers/forceNumIntoBounds.d.ts +0 -0
  55. package/dist/esm/types/helpers/genRouteHandler.d.ts +32 -0
  56. package/dist/esm/types/helpers/getOrdinal.d.ts +8 -0
  57. package/dist/esm/types/helpers/getTimeInfoInET.d.ts +17 -0
  58. package/{lib/cjs → dist/esm}/types/helpers/handleError.d.ts +5 -1
  59. package/{lib/cjs → dist/esm}/types/helpers/handleSuccess.d.ts +0 -0
  60. package/{lib/cjs → dist/esm}/types/helpers/padDecimalZeros.d.ts +0 -0
  61. package/{lib/cjs → dist/esm}/types/helpers/padZerosLeft.d.ts +0 -0
  62. package/{lib/cjs → dist/esm}/types/helpers/roundToNumDecimals.d.ts +0 -0
  63. package/{lib/cjs → dist/esm}/types/helpers/sum.d.ts +0 -0
  64. package/{lib/cjs → dist/esm}/types/helpers/visitServerEndpoint.d.ts +0 -0
  65. package/{lib/cjs → dist/esm}/types/helpers/waitMs.d.ts +0 -0
  66. package/{lib/esm/lib → dist/esm/types}/index.d.ts +13 -6
  67. package/dist/esm/types/server/initServer.d.ts +21 -0
  68. package/{lib/cjs → dist/esm}/types/types/ModalButtonType.d.ts +0 -0
  69. package/{lib/cjs → dist/esm}/types/types/ModalSize.d.ts +0 -0
  70. package/{lib/cjs → dist/esm}/types/types/ModalType.d.ts +0 -0
  71. package/{lib/esm/lib → dist/esm/types}/types/ParamType.d.ts +1 -1
  72. package/{lib/esm/lib → dist/esm/types}/types/ReactKitErrorCode.d.ts +3 -1
  73. package/{lib/cjs → dist/esm}/types/types/Variant.d.ts +0 -0
  74. package/{lib → dist}/index.d.ts +232 -11
  75. package/package.json +18 -29
  76. package/rollup.config.js +14 -13
  77. package/src/components/AppWrapper.tsx +74 -12
  78. package/src/components/ButtonInputGroup.tsx +89 -0
  79. package/src/components/CheckboxButton.tsx +100 -0
  80. package/src/components/ErrorBox.tsx +4 -4
  81. package/src/components/LoadingSpinner.tsx +3 -3
  82. package/src/components/Modal.tsx +214 -97
  83. package/src/components/RadioButton.tsx +102 -0
  84. package/src/components/SimpleDateChooser.tsx +222 -0
  85. package/src/components/TabBox.tsx +65 -58
  86. package/src/helpers/genRouteHandler.ts +329 -0
  87. package/src/helpers/getOrdinal.tsx +13 -0
  88. package/src/helpers/getTimeInfoInET.tsx +56 -0
  89. package/src/helpers/handleError.ts +65 -0
  90. package/src/helpers/handleSuccess.ts +18 -0
  91. package/src/helpers/visitServerEndpoint.tsx +110 -0
  92. package/src/index.ts +27 -0
  93. package/src/server/initServer.ts +53 -0
  94. package/src/types/ParamType.ts +18 -0
  95. package/src/types/ReactKitErrorCode.tsx +3 -1
  96. package/tsconfig.json +9 -7
  97. package/lib/cjs/index.js +0 -2
  98. package/lib/cjs/index.js.map +0 -1
  99. package/lib/cjs/lib/components/AppWrapper.d.ts +0 -35
  100. package/lib/cjs/lib/helpers/parseRequest.d.ts +0 -21
  101. package/lib/cjs/lib/types/ParamType.d.ts +0 -17
  102. package/lib/cjs/lib/types/ReactKitErrorCode.d.ts +0 -13
  103. package/lib/cjs/types/components/TabBox.d.ts +0 -11
  104. package/lib/cjs/types/helpers/alert.d.ts +0 -2
  105. package/lib/cjs/types/helpers/confirm.d.ts +0 -2
  106. package/lib/cjs/types/helpers/parseRequest.d.ts +0 -21
  107. package/lib/cjs/types/helpers/showFatalError.d.ts +0 -2
  108. package/lib/cjs/types/index.d.ts +0 -22
  109. package/lib/esm/index.js +0 -16
  110. package/lib/esm/index.js.map +0 -1
  111. package/lib/esm/lib/components/AppWrapper.d.ts +0 -35
  112. package/lib/esm/lib/components/ErrorBox.d.ts +0 -12
  113. package/lib/esm/lib/components/LoadingSpinner.d.ts +0 -7
  114. package/lib/esm/lib/components/Modal.d.ts +0 -40
  115. package/lib/esm/lib/errors/ErrorWithCode.d.ts +0 -9
  116. package/lib/esm/lib/helpers/abbreviate.d.ts +0 -10
  117. package/lib/esm/lib/helpers/avg.d.ts +0 -8
  118. package/lib/esm/lib/helpers/ceilToNumDecimals.d.ts +0 -9
  119. package/lib/esm/lib/helpers/floorToNumDecimals.d.ts +0 -9
  120. package/lib/esm/lib/helpers/forceNumIntoBounds.d.ts +0 -10
  121. package/lib/esm/lib/helpers/handleError.d.ts +0 -14
  122. package/lib/esm/lib/helpers/handleSuccess.d.ts +0 -8
  123. package/lib/esm/lib/helpers/padDecimalZeros.d.ts +0 -10
  124. package/lib/esm/lib/helpers/padZerosLeft.d.ts +0 -9
  125. package/lib/esm/lib/helpers/parseRequest.d.ts +0 -21
  126. package/lib/esm/lib/helpers/roundToNumDecimals.d.ts +0 -9
  127. package/lib/esm/lib/helpers/sum.d.ts +0 -8
  128. package/lib/esm/lib/helpers/visitServerEndpoint.d.ts +0 -23
  129. package/lib/esm/lib/helpers/waitMs.d.ts +0 -7
  130. package/lib/esm/lib/types/ModalButtonType.d.ts +0 -17
  131. package/lib/esm/lib/types/ModalSize.d.ts +0 -11
  132. package/lib/esm/lib/types/ModalType.d.ts +0 -16
  133. package/lib/esm/lib/types/Variant.d.ts +0 -15
  134. package/lib/esm/types/components/ErrorBox.d.ts +0 -12
  135. package/lib/esm/types/components/LoadingSpinner.d.ts +0 -7
  136. package/lib/esm/types/components/Modal.d.ts +0 -40
  137. package/lib/esm/types/components/TabBox.d.ts +0 -11
  138. package/lib/esm/types/errors/ErrorWithCode.d.ts +0 -9
  139. package/lib/esm/types/helpers/abbreviate.d.ts +0 -10
  140. package/lib/esm/types/helpers/alert.d.ts +0 -2
  141. package/lib/esm/types/helpers/avg.d.ts +0 -8
  142. package/lib/esm/types/helpers/ceilToNumDecimals.d.ts +0 -9
  143. package/lib/esm/types/helpers/confirm.d.ts +0 -2
  144. package/lib/esm/types/helpers/floorToNumDecimals.d.ts +0 -9
  145. package/lib/esm/types/helpers/forceNumIntoBounds.d.ts +0 -10
  146. package/lib/esm/types/helpers/handleError.d.ts +0 -14
  147. package/lib/esm/types/helpers/handleSuccess.d.ts +0 -8
  148. package/lib/esm/types/helpers/padDecimalZeros.d.ts +0 -10
  149. package/lib/esm/types/helpers/padZerosLeft.d.ts +0 -9
  150. package/lib/esm/types/helpers/parseRequest.d.ts +0 -21
  151. package/lib/esm/types/helpers/roundToNumDecimals.d.ts +0 -9
  152. package/lib/esm/types/helpers/showFatalError.d.ts +0 -2
  153. package/lib/esm/types/helpers/sum.d.ts +0 -8
  154. package/lib/esm/types/helpers/visitServerEndpoint.d.ts +0 -23
  155. package/lib/esm/types/helpers/waitMs.d.ts +0 -7
  156. package/lib/esm/types/index.d.ts +0 -22
  157. package/lib/esm/types/types/ModalButtonType.d.ts +0 -17
  158. package/lib/esm/types/types/ModalSize.d.ts +0 -11
  159. package/lib/esm/types/types/ModalType.d.ts +0 -16
  160. package/lib/esm/types/types/ParamType.d.ts +0 -17
  161. package/lib/esm/types/types/ReactKitErrorCode.d.ts +0 -13
  162. package/lib/esm/types/types/Variant.d.ts +0 -15
@@ -3,15 +3,33 @@ import React from 'react';
3
3
 
4
4
  /**
5
5
  * A wrapper for the entire React app that adds global functionality like
6
- * handling for fatal error messages
6
+ * handling for fatal error messages, adds bootstrap support
7
7
  * @author Gabe Abrams
8
8
  */
9
9
 
10
- declare type Props$3 = {
10
+ declare type Props$7 = {
11
11
  children: React.ReactNode;
12
+ sendRequest: SendRequestFunction;
12
13
  dark?: boolean;
13
14
  sessionExpiredMessage?: string;
14
15
  };
16
+ declare type SendRequestFunction = (opts: {
17
+ path: string;
18
+ method: ('GET' | 'POST' | 'DELETE' | 'PUT');
19
+ params?: {
20
+ [x: string]: any;
21
+ } | undefined;
22
+ headers?: {
23
+ [x: string]: any;
24
+ } | undefined;
25
+ numRetries?: number | undefined;
26
+ }) => Promise<{
27
+ body: any;
28
+ status: number;
29
+ headers: {
30
+ [x: string]: any;
31
+ };
32
+ }>;
15
33
  /**
16
34
  * Show an alert modal with an "Okay" button
17
35
  * @author Gabe Abrams
@@ -34,7 +52,7 @@ declare const confirm: (title: string, text: string) => Promise<boolean>;
34
52
  * @param [errorTitle] title of the error box
35
53
  */
36
54
  declare const showFatalError: (error: any, errorTitle?: string) => undefined;
37
- declare const AppWrapper: React.FC<Props$3>;
55
+ declare const AppWrapper: React.FC<Props$7>;
38
56
 
39
57
  /**
40
58
  * Loading spinner/indicator
@@ -47,12 +65,12 @@ declare const LoadingSpinner: () => JSX.Element;
47
65
  * @author Gabe Abrams
48
66
  */
49
67
 
50
- declare type Props$2 = {
68
+ declare type Props$6 = {
51
69
  error: any;
52
70
  title?: string;
53
71
  onClose?: () => void;
54
72
  };
55
- declare const ErrorBox: React.FC<Props$2>;
73
+ declare const ErrorBox: React.FC<Props$6>;
56
74
 
57
75
  /**
58
76
  * Bootstrap variants
@@ -118,7 +136,7 @@ declare enum ModalType {
118
136
  * @author Gabe Abrams
119
137
  */
120
138
 
121
- declare type Props$1 = {
139
+ declare type Props$5 = {
122
140
  type?: ModalType;
123
141
  size?: ModalSize;
124
142
  title?: React.ReactNode;
@@ -147,18 +165,91 @@ declare type Props$1 = {
147
165
  confirmVariant?: Variant;
148
166
  onTopOfOtherModals?: boolean;
149
167
  };
150
- declare const Modal: React.FC<Props$1>;
168
+ declare const Modal: React.FC<Props$5>;
151
169
 
152
170
  /**
153
171
  * A box with a tab on the top that holds buttons and other content
154
172
  * @author Gabe Abrams
155
173
  */
156
174
 
157
- declare type Props = {
175
+ declare type Props$4 = {
158
176
  title: React.ReactNode;
159
177
  children: React.ReactNode;
178
+ noBottomPadding?: boolean;
179
+ };
180
+ declare const TabBox: React.FC<Props$4>;
181
+
182
+ /**
183
+ * A radio selection button
184
+ * @author Gabe Abrams
185
+ */
186
+
187
+ declare type Props$3 = {
188
+ text: string;
189
+ onSelected: () => void;
190
+ ariaLabel: string;
191
+ title?: string;
192
+ selected?: boolean;
193
+ id?: string;
194
+ noMarginOnRight?: boolean;
195
+ selectedVariant?: Variant;
196
+ unselectedVariant?: Variant;
197
+ small?: boolean;
198
+ };
199
+ declare const RadioButton: React.FC<Props$3>;
200
+
201
+ /**
202
+ * A checkbox button
203
+ * @author Gabe Abrams
204
+ */
205
+
206
+ declare type Props$2 = {
207
+ text: string;
208
+ onChanged: (checked: boolean) => void;
209
+ ariaLabel: string;
210
+ title?: string;
211
+ checked?: boolean;
212
+ id?: string;
213
+ noMarginOnRight?: boolean;
214
+ checkedVariant?: Variant;
215
+ uncheckedVariant?: Variant;
216
+ small?: boolean;
217
+ };
218
+ declare const CheckboxButton: React.FC<Props$2>;
219
+
220
+ /**
221
+ * Input group with a title and space for buttons
222
+ * @author Gabe Abrams
223
+ */
224
+
225
+ declare type Props$1 = {
226
+ label: string;
227
+ minLabelWidth?: string;
228
+ children: React.ReactNode;
229
+ };
230
+ declare const ButtonInputGroup: React.FC<Props$1>;
231
+
232
+ /**
233
+ * A very simple, lightweight date chooser
234
+ * @author Gabe Abrams
235
+ */
236
+
237
+ declare type Props = {
238
+ ariaLabel: string;
239
+ name: string;
240
+ month: number;
241
+ day: number;
242
+ year: number;
243
+ /**
244
+ * Handler for when date changes
245
+ * @param month new 1-indexed month number
246
+ * @param day new 1-indexed day number
247
+ * @param year new full year number
248
+ */
249
+ onChange: (month: number, day: number, year: number) => void;
250
+ numMonthsToShow?: number;
160
251
  };
161
- declare const TabBox: React.FC<Props>;
252
+ declare const SimpleDateChooser: React.FC<Props>;
162
253
 
163
254
  /**
164
255
  * An error with a code
@@ -258,6 +349,134 @@ declare const sum: (nums: number[]) => number;
258
349
  */
259
350
  declare const waitMs: (ms?: number) => Promise<unknown>;
260
351
 
352
+ /**
353
+ * Visit an endpoint on the server [for client only]
354
+ * @author Gabe Abrams
355
+ * @param opts object containing all arguments
356
+ * @param opts.path - the path of the server endpoint
357
+ * @param [opts.method=GET] - the method of the endpoint
358
+ * @param [opts.params] - query/body parameters to include
359
+ * @returns response from server
360
+ */
361
+ declare const visitServerEndpoint: (opts: {
362
+ path: string;
363
+ method?: "GET" | "POST" | "DELETE" | "PUT" | undefined;
364
+ params?: {
365
+ [x: string]: any;
366
+ } | undefined;
367
+ }) => Promise<any>;
368
+
369
+ /**
370
+ * Server-side API param types
371
+ * @author Gabe Abrams
372
+ */
373
+ declare enum ParamType {
374
+ Boolean = "boolean",
375
+ BooleanOptional = "boolean-optional",
376
+ Float = "float",
377
+ FloatOptional = "float-optional",
378
+ Int = "int",
379
+ IntOptional = "int-optional",
380
+ JSON = "json",
381
+ JSONOptional = "json-optional",
382
+ String = "string",
383
+ StringOptional = "string-optional"
384
+ }
385
+
386
+ /**
387
+ * Handle an error and respond to the client
388
+ * @author Gabe Abrams
389
+ * @param res express response
390
+ * @param error error info
391
+ * @param opts.err the error to send to the client
392
+ * or the error message
393
+ * @param [opts.code] an error code (only used if err.code is not
394
+ * included)
395
+ * @param [opts.status=500] the https status code to use
396
+ * defined)
397
+ */
398
+ declare const handleError: (res: any, error: ({
399
+ message: any;
400
+ code?: string;
401
+ status?: number;
402
+ } | Error | string | any)) => undefined;
403
+
404
+ /**
405
+ * Send successful API response
406
+ * @author Gabe Abrams
407
+ * @param res express response
408
+ * @param body the body of the response to send to the client
409
+ */
410
+ declare const handleSuccess: (res: any, body: any) => undefined;
411
+
412
+ /**
413
+ * Generate an express API route handler
414
+ * @author Gabe Abrams
415
+ * @param opts object containing all arguments
416
+ * @param opts.paramTypes map containing the types for each parameter that is
417
+ * included in the request (map: param name => type)
418
+ * @param opts.handler function that processes the request
419
+ * @returns express route handler that takes the following arguments:
420
+ * params (map: param name => value), handleSuccess (function for handling
421
+ * successful requests), handleError (function for handling failed requests),
422
+ * req (express request object), res (express response object),
423
+ * next (express next function)
424
+ */
425
+ declare const genRouteHandler: (opts: {
426
+ paramTypes?: {
427
+ [k: string]: ParamType;
428
+ } | undefined;
429
+ handler: (opts: {
430
+ params: {
431
+ [k: string]: any;
432
+ };
433
+ handleSuccess: (body: any) => void;
434
+ handleError: (error: any) => void;
435
+ req: any;
436
+ res: any;
437
+ next: () => void;
438
+ }) => void;
439
+ }) => (req: any, res: any, next: () => void) => Promise<undefined>;
440
+
441
+ declare type GetLaunchInfoFunction = (req: any) => {
442
+ launched: boolean;
443
+ launchInfo?: any;
444
+ };
445
+ /**
446
+ * Prepare dce-reactkit to run on the server
447
+ * @author Gabe Abrams
448
+ * @param opts object containing all arguments
449
+ * @param opts.getLaunchInfo CACCL LTI's get launch info function
450
+ */
451
+ declare const initServer: (opts: {
452
+ getLaunchInfo: GetLaunchInfoFunction;
453
+ }) => void;
454
+
455
+ /**
456
+ * Get a number's ordinal
457
+ * @author Gabe Abrams
458
+ * @param num the number being analyzed
459
+ * @returns ordinal
460
+ */
461
+ declare const getOrdinal: (num: number) => string;
462
+
463
+ /**
464
+ * Get current time info in US Boston Eastern Time, independent of machine
465
+ * timezone
466
+ * @author Gabe Abrams
467
+ * @param {Date} [date=now] the date to get info on
468
+ * @returns object with timestamp (ms since epoch) and numbers
469
+ * corresponding to ET time values for year, month, day, hour, minute
470
+ */
471
+ declare const getTimeInfoInET: (date?: Date | undefined) => {
472
+ timestamp: number;
473
+ year: number;
474
+ month: number;
475
+ day: number;
476
+ hour: number;
477
+ minute: number;
478
+ };
479
+
261
480
  /**
262
481
  * List of error codes built into the react kit
263
482
  * @author Gabe Abrams
@@ -268,7 +487,9 @@ declare enum ReactKitErrorCode {
268
487
  SessionExpired = "DRK3",
269
488
  MissingParameter = "DRK4",
270
489
  InvalidParameter = "DRK5",
271
- WrongCourse = "DRK6"
490
+ WrongCourse = "DRK6",
491
+ NoCACCLSendRequestFunction = "DRK7",
492
+ NoCACCLGetLaunchInfoFunction = "DRK8"
272
493
  }
273
494
 
274
- export { AppWrapper, ErrorBox, ErrorWithCode, LoadingSpinner, Modal, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, TabBox, Variant, abbreviate, alert, avg, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, showFatalError, sum, waitMs };
495
+ export { AppWrapper, ButtonInputGroup, CheckboxButton, ErrorBox, ErrorWithCode, LoadingSpinner, Modal, ModalButtonType, ModalSize, ModalType, ParamType, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, Variant, abbreviate, alert, avg, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, genRouteHandler, getOrdinal, getTimeInfoInET, handleError, handleSuccess, initServer, padDecimalZeros, padZerosLeft, roundToNumDecimals, showFatalError, sum, visitServerEndpoint, waitMs };
package/package.json CHANGED
@@ -1,59 +1,48 @@
1
1
  {
2
2
  "name": "dce-reactkit",
3
- "version": "3.0.1",
4
- "main": "lib/cjs/index.js",
5
- "module": "lib/esm/index.js",
6
- "types": "lib/index.d.ts",
3
+ "version": "3.0.2",
4
+ "description": "Shared components for Harvard DCE apps",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/index.d.ts",
7
8
  "scripts": {
8
- "build": "rollup -c"
9
+ "build": "rm -rf dist && rollup -c"
9
10
  },
10
11
  "repository": {
11
12
  "type": "git",
12
- "url": "git+https://github.com/harvard-edtech/dce-reactkit"
13
+ "url": "git+https://github.com/harvard-edtech/dce-reactkit.git"
13
14
  },
14
15
  "author": "Gabe Abrams <gabeabrams@gmail.com>",
15
16
  "license": "MIT",
17
+ "bugs": {
18
+ "url": "https://github.com/harvard-edtech/dce-reactkit/issues"
19
+ },
16
20
  "homepage": "https://github.com/harvard-edtech/dce-reactkit#readme",
17
- "dependencies": {
18
- "@fortawesome/fontawesome-svg-core": "^6.1.1",
21
+ "peerDependencies": {
19
22
  "@fortawesome/free-regular-svg-icons": "^6.1.1",
20
23
  "@fortawesome/free-solid-svg-icons": "^6.1.1",
21
24
  "@fortawesome/react-fontawesome": "^0.1.18",
22
- "caccl": "^2.0.0-beta.39",
23
- "react-bootstrap": "^2.2.3",
25
+ "bootstrap": "^5.1.3",
24
26
  "react": "^18.0.0"
25
27
  },
26
28
  "devDependencies": {
27
- "@rollup/plugin-commonjs": "^21.1.0",
29
+ "@rollup/plugin-commonjs": "^22.0.0",
28
30
  "@rollup/plugin-json": "^4.1.0",
29
31
  "@rollup/plugin-node-resolve": "^13.2.1",
30
32
  "@rollup/plugin-typescript": "^8.3.2",
31
- "@types/express": "^4.17.13",
32
- "@types/react": "^18.0.5",
33
- "@typescript-eslint/eslint-plugin": "^5.18.0",
34
- "@typescript-eslint/parser": "^5.18.0",
35
- "eslint": "^8.12.0",
33
+ "@types/react": "^18.0.7",
34
+ "@typescript-eslint/eslint-plugin": "^5.21.0",
35
+ "@typescript-eslint/parser": "^5.21.0",
36
+ "eslint": "^8.14.0",
36
37
  "eslint-config-airbnb": "^19.0.4",
37
38
  "eslint-config-airbnb-typescript": "^17.0.0",
38
39
  "eslint-plugin-import": "^2.26.0",
39
- "eslint-plugin-jest": "^26.1.3",
40
40
  "eslint-plugin-jsx-a11y": "^6.5.1",
41
41
  "eslint-plugin-react": "^7.29.4",
42
42
  "eslint-plugin-react-hooks": "^4.4.0",
43
- "react": "^18.0.0",
44
43
  "rollup": "^2.70.2",
45
44
  "rollup-plugin-dts": "^4.2.1",
46
- "rollup-plugin-peer-deps-external": "^2.2.4",
47
- "rollup-plugin-terser": "^7.0.2",
45
+ "rollup-plugin-sourcemaps": "^0.6.3",
48
46
  "typescript": "^4.6.3"
49
- },
50
- "peerDependencies": {
51
- "@fortawesome/fontawesome-svg-core": "^6.1.1",
52
- "@fortawesome/free-regular-svg-icons": "^6.1.1",
53
- "@fortawesome/free-solid-svg-icons": "^6.1.1",
54
- "@fortawesome/react-fontawesome": "^0.1.18",
55
- "caccl": "^2.0.0-beta.39",
56
- "react-bootstrap": "^2.2.3",
57
- "react": "^18.0.0"
58
47
  }
59
48
  }
package/rollup.config.js CHANGED
@@ -2,9 +2,7 @@ import resolve from "@rollup/plugin-node-resolve";
2
2
  import commonjs from "@rollup/plugin-commonjs";
3
3
  import typescript from "@rollup/plugin-typescript";
4
4
  import dts from "rollup-plugin-dts";
5
- import { terser } from "rollup-plugin-terser";
6
- import peerDepsExternal from 'rollup-plugin-peer-deps-external';
7
- import json from "@rollup/plugin-json";
5
+ import sourcemaps from 'rollup-plugin-sourcemaps';
8
6
 
9
7
  const packageJson = require("./package.json");
10
8
 
@@ -24,20 +22,23 @@ export default [
24
22
  },
25
23
  ],
26
24
  plugins: [
27
- peerDepsExternal(),
28
- resolve({
29
- preferBuiltins: false,
30
- }),
25
+ resolve(),
31
26
  commonjs(),
32
27
  typescript({ tsconfig: "./tsconfig.json" }),
33
- terser(),
34
- json(),
28
+ sourcemaps(),
29
+ ],
30
+ external: [
31
+ ...Object.keys(packageJson.dependencies || {}),
32
+ ...Object.keys(packageJson.peerDependencies || {}),
35
33
  ],
36
- external: ["react", "react-dom", "styled-components"]
37
34
  },
38
35
  {
39
- input: "lib/esm/types/index.d.ts",
40
- output: [{ file: "lib/index.d.ts", format: "esm" }],
36
+ input: "dist/esm/types/index.d.ts",
37
+ output: [{ file: "dist/index.d.ts", format: "esm" }],
41
38
  plugins: [dts()],
39
+ external: [
40
+ ...Object.keys(packageJson.dependencies || {}),
41
+ ...Object.keys(packageJson.peerDependencies || {}),
42
+ ],
42
43
  },
43
- ];
44
+ ];
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * A wrapper for the entire React app that adds global functionality like
3
- * handling for fatal error messages
3
+ * handling for fatal error messages, adds bootstrap support
4
4
  * @author Gabe Abrams
5
5
  */
6
6
 
@@ -28,22 +28,70 @@ import ErrorWithCode from '../errors/ErrorWithCode';
28
28
  type Props = {
29
29
  // The entire app
30
30
  children: React.ReactNode,
31
+ // Copy of CACCL's send request function
32
+ sendRequest: SendRequestFunction,
31
33
  // True if this app is a dark-themed app
32
34
  dark?: boolean,
33
35
  // Custom session expired message
34
36
  sessionExpiredMessage?: string,
35
37
  };
36
38
 
39
+ // Type of CACCL's send request function
40
+ type SendRequestFunction = (
41
+ opts: {
42
+ path: string;
43
+ method: ('GET' | 'POST' | 'DELETE' | 'PUT');
44
+ params?: {
45
+ [x: string]: any;
46
+ } | undefined;
47
+ headers?: {
48
+ [x: string]: any;
49
+ } | undefined;
50
+ numRetries?: number | undefined;
51
+ },
52
+ ) => Promise<{
53
+ body: any;
54
+ status: number;
55
+ headers: {
56
+ [x: string]: any;
57
+ };
58
+ }>;
59
+
37
60
  /*------------------------------------------------------------------------*/
38
61
  /* Static Helpers */
39
62
  /*------------------------------------------------------------------------*/
40
63
 
64
+ /*----------------------------------------*/
65
+ /* Send Request */
66
+ /*----------------------------------------*/
67
+
68
+ // Store copy of caccl send request
69
+ let _cacclSendRequest: SendRequestFunction;
70
+
71
+ /**
72
+ * Send a request using caccl's send request feature
73
+ * @author Gabe Abrams
74
+ * @param opts send request options
75
+ * @returns send request response
76
+ */
77
+ export const cacclSendRequest: SendRequestFunction = async (opts) => {
78
+ // Make sure send request has been passed in
79
+ if (!_cacclSendRequest) {
80
+ throw new ErrorWithCode(
81
+ 'The request could not be sent because the AppWrapper component does not have a copy of sendRequest from CACCL.',
82
+ ReactKitErrorCode.NoCACCLSendRequestFunction,
83
+ );
84
+ }
85
+
86
+ return _cacclSendRequest(opts);
87
+ };
88
+
41
89
  /*----------------------------------------*/
42
90
  /* Alert */
43
91
  /*----------------------------------------*/
44
92
 
45
93
  // Stored copies of setters
46
- let setAlertInfo: (info: { title: string, text: string }) => void;
94
+ let setAlertInfo: (info: undefined | { title: string, text: string }) => void;
47
95
  let onAlertClosed: () => void;
48
96
 
49
97
  /**
@@ -79,7 +127,7 @@ export const alert = async (title: string, text: string): Promise<undefined> =>
79
127
  /*----------------------------------------*/
80
128
 
81
129
  // Stored copies of setters
82
- let setConfirmInfo: (info: { title: string, text: string }) => void;
130
+ let setConfirmInfo: (info: undefined | { title: string, text: string }) => void;
83
131
  let onConfirmClosed: (confirmed: boolean) => void;
84
132
 
85
133
  /**
@@ -190,10 +238,14 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
190
238
 
191
239
  const {
192
240
  children,
241
+ sendRequest,
193
242
  dark,
194
243
  sessionExpiredMessage = 'Your session has expired. Please go back to Canvas and start over.',
195
244
  } = props;
196
245
 
246
+ // Store copy of send request
247
+ _cacclSendRequest = sendRequest;
248
+
197
249
  /* -------------- State ------------- */
198
250
 
199
251
  // Fatal error
@@ -217,20 +269,26 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
217
269
  const [
218
270
  alertInfo,
219
271
  setAlertInfoInner,
220
- ] = useState<{
221
- title: string,
222
- text: string
223
- }>();
272
+ ] = useState<
273
+ undefined
274
+ | {
275
+ title: string,
276
+ text: string
277
+ }
278
+ >(undefined);
224
279
  setAlertInfo = setAlertInfoInner;
225
280
 
226
281
  // Confirm
227
282
  const [
228
283
  confirmInfo,
229
284
  setConfirmInfoInner,
230
- ] = useState<{
231
- title: string,
232
- text: string
233
- }>();
285
+ ] = useState<
286
+ undefined
287
+ | {
288
+ title: string,
289
+ text: string
290
+ }
291
+ >(undefined);
234
292
  setConfirmInfo = setConfirmInfoInner;
235
293
 
236
294
  // Session expired
@@ -256,10 +314,12 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
256
314
  if (alertInfo) {
257
315
  modal = (
258
316
  <Modal
317
+ key={`alert-${alertInfo.title}-${alertInfo.text}`}
259
318
  title={alertInfo.title}
260
319
  type={ModalType.Okay}
261
320
  onClose={() => {
262
321
  // Alert closed
322
+ setAlertInfo(undefined);
263
323
  if (onAlertClosed) {
264
324
  onAlertClosed();
265
325
  }
@@ -276,16 +336,18 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
276
336
  if (confirmInfo) {
277
337
  modal = (
278
338
  <Modal
339
+ key={`confirm-${confirmInfo.title}-${confirmInfo.text}`}
279
340
  title={confirmInfo.title}
280
341
  type={ModalType.OkayCancel}
281
342
  onClose={(buttonType) => {
343
+ setConfirmInfo(undefined);
282
344
  if (onConfirmClosed) {
283
345
  onConfirmClosed(buttonType === ModalButtonType.Okay);
284
346
  }
285
347
  }}
286
348
  dontAllowBackdropExit
287
349
  >
288
-
350
+ {confirmInfo.text}
289
351
  </Modal>
290
352
  );
291
353
  }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Input group with a title and space for buttons
3
+ * @author Gabe Abrams
4
+ */
5
+
6
+ // Import React
7
+ import React from 'react';
8
+
9
+ /*------------------------------------------------------------------------*/
10
+ /* Types */
11
+ /*------------------------------------------------------------------------*/
12
+
13
+ // Props definition
14
+ type Props = {
15
+ // Label text
16
+ label: string,
17
+ // Minimum width of the label (css units)
18
+ minLabelWidth?: string,
19
+ // Buttons
20
+ children: React.ReactNode,
21
+ };
22
+
23
+ /*------------------------------------------------------------------------*/
24
+ /* Component */
25
+ /*------------------------------------------------------------------------*/
26
+
27
+ const ButtonInputGroup: React.FC<Props> = (props) => {
28
+ /*------------------------------------------------------------------------*/
29
+ /* Setup */
30
+ /*------------------------------------------------------------------------*/
31
+
32
+ /* -------------- Props ------------- */
33
+
34
+ // Destructure all props
35
+ const {
36
+ label,
37
+ minLabelWidth,
38
+ children,
39
+ } = props;
40
+
41
+ /*------------------------------------------------------------------------*/
42
+ /* Render */
43
+ /*------------------------------------------------------------------------*/
44
+
45
+ /*----------------------------------------*/
46
+ /* Main UI */
47
+ /*----------------------------------------*/
48
+
49
+ return (
50
+ <div className="input-group">
51
+ <div className="input-group-prepend d-flex w-100">
52
+ {/* Label */}
53
+ <span
54
+ className="input-group-text"
55
+ style={{
56
+ minWidth: (
57
+ minLabelWidth
58
+ ?? undefined
59
+ ),
60
+ borderTopRightRadius: 0,
61
+ borderBottomRightRadius: 0,
62
+ }}
63
+ >
64
+ {label}
65
+ </span>
66
+
67
+ {/* Contents */}
68
+ <span
69
+ className="input-group-text flex-grow-1 rounded-right"
70
+ style={{
71
+ backgroundColor: 'white',
72
+ borderTopLeftRadius: 0,
73
+ borderBottomLeftRadius: 0,
74
+ borderLeftWidth: 0,
75
+ }}
76
+ >
77
+ {children}
78
+ </span>
79
+ </div>
80
+ </div>
81
+ );
82
+ };
83
+
84
+ /*------------------------------------------------------------------------*/
85
+ /* Wrap Up */
86
+ /*------------------------------------------------------------------------*/
87
+
88
+ // Export component
89
+ export default ButtonInputGroup;