dce-reactkit 3.0.0-beta.3 → 3.0.0-beta.32
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/README.md +1 -546
- package/dist/cjs/index.js +787 -35684
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/AppWrapper.d.ts +26 -1
- package/dist/cjs/types/components/TabBox.d.ts +1 -0
- package/dist/cjs/types/helpers/genRouteHandler.d.ts +30 -0
- package/dist/cjs/types/helpers/handleError.d.ts +18 -0
- package/dist/cjs/types/helpers/handleSuccess.d.ts +8 -0
- package/dist/cjs/types/helpers/visitServerEndpoint.d.ts +23 -0
- package/dist/cjs/types/index.d.ts +7 -1
- package/dist/cjs/types/server/initServer.d.ts +21 -0
- package/dist/cjs/types/types/ParamType.d.ts +17 -0
- package/dist/cjs/types/types/ReactKitErrorCode.d.ts +3 -1
- package/dist/esm/index.js +717 -35602
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/AppWrapper.d.ts +26 -1
- package/dist/esm/types/components/TabBox.d.ts +1 -0
- package/dist/esm/types/helpers/genRouteHandler.d.ts +30 -0
- package/dist/esm/types/helpers/handleError.d.ts +18 -0
- package/dist/esm/types/helpers/handleSuccess.d.ts +8 -0
- package/dist/esm/types/helpers/visitServerEndpoint.d.ts +23 -0
- package/dist/esm/types/index.d.ts +7 -1
- package/dist/esm/types/server/initServer.d.ts +21 -0
- package/dist/esm/types/types/ParamType.d.ts +17 -0
- package/dist/esm/types/types/ReactKitErrorCode.d.ts +3 -1
- package/dist/index.d.ts +125 -3
- package/package.json +13 -3
- package/rollup.config.js +0 -1
- package/src/components/AppWrapper.tsx +72 -12
- package/src/components/ErrorBox.tsx +4 -4
- package/src/components/LoadingSpinner.tsx +3 -3
- package/src/components/Modal.tsx +214 -97
- package/src/components/TabBox.tsx +65 -58
- package/src/helpers/genRouteHandler.ts +326 -0
- package/src/helpers/handleError.ts +65 -0
- package/src/helpers/handleSuccess.ts +18 -0
- package/src/helpers/visitServerEndpoint.tsx +110 -0
- package/src/index.ts +15 -0
- package/src/server/initServer.ts +53 -0
- package/src/types/ParamType.tsx +18 -0
- package/src/types/ReactKitErrorCode.tsx +3 -1
|
@@ -1,14 +1,39 @@
|
|
|
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
|
import React from 'react';
|
|
7
7
|
declare type Props = {
|
|
8
8
|
children: React.ReactNode;
|
|
9
|
+
sendRequest: SendRequestFunction;
|
|
9
10
|
dark?: boolean;
|
|
10
11
|
sessionExpiredMessage?: string;
|
|
11
12
|
};
|
|
13
|
+
declare type SendRequestFunction = (opts: {
|
|
14
|
+
path: string;
|
|
15
|
+
method: ('GET' | 'POST' | 'DELETE' | 'PUT');
|
|
16
|
+
params?: {
|
|
17
|
+
[x: string]: any;
|
|
18
|
+
} | undefined;
|
|
19
|
+
headers?: {
|
|
20
|
+
[x: string]: any;
|
|
21
|
+
} | undefined;
|
|
22
|
+
numRetries?: number | undefined;
|
|
23
|
+
}) => Promise<{
|
|
24
|
+
body: any;
|
|
25
|
+
status: number;
|
|
26
|
+
headers: {
|
|
27
|
+
[x: string]: any;
|
|
28
|
+
};
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Send a request using caccl's send request feature
|
|
32
|
+
* @author Gabe Abrams
|
|
33
|
+
* @param opts send request options
|
|
34
|
+
* @returns send request response
|
|
35
|
+
*/
|
|
36
|
+
export declare const cacclSendRequest: SendRequestFunction;
|
|
12
37
|
/**
|
|
13
38
|
* Show an alert modal with an "Okay" button
|
|
14
39
|
* @author Gabe Abrams
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import ParamType from '../types/ParamType';
|
|
2
|
+
import handleError from './handleError';
|
|
3
|
+
import handleSuccess from './handleSuccess';
|
|
4
|
+
/**
|
|
5
|
+
* Generate an express API route handler
|
|
6
|
+
* @author Gabe Abrams
|
|
7
|
+
* @param opts object containing all arguments
|
|
8
|
+
* @param opts.paramTypes map containing the types for each parameter that is
|
|
9
|
+
* included in the request (map: param name => type)
|
|
10
|
+
* @param opts.handler function that processes the request
|
|
11
|
+
* @returns express route handler that takes the following arguments:
|
|
12
|
+
* params (map: param name => value), handleSuccess (function for handling
|
|
13
|
+
* successful requests), handleError (function for handling failed requests),
|
|
14
|
+
* req (express request object), res (express response object)
|
|
15
|
+
*/
|
|
16
|
+
declare const genRouteHandler: (opts: {
|
|
17
|
+
paramTypes?: {
|
|
18
|
+
[k: string]: ParamType;
|
|
19
|
+
} | undefined;
|
|
20
|
+
handler: (opts: {
|
|
21
|
+
params: {
|
|
22
|
+
[k: string]: any;
|
|
23
|
+
};
|
|
24
|
+
handleSuccess: (body: any) => void;
|
|
25
|
+
handleError: (error: any) => void;
|
|
26
|
+
req: any;
|
|
27
|
+
res: any;
|
|
28
|
+
}) => void;
|
|
29
|
+
}) => (req: any, res: any) => Promise<undefined>;
|
|
30
|
+
export default genRouteHandler;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handle an error and respond to the client
|
|
3
|
+
* @author Gabe Abrams
|
|
4
|
+
* @param res express response
|
|
5
|
+
* @param error error info
|
|
6
|
+
* @param opts.err the error to send to the client
|
|
7
|
+
* or the error message
|
|
8
|
+
* @param [opts.code] an error code (only used if err.code is not
|
|
9
|
+
* included)
|
|
10
|
+
* @param [opts.status=500] the https status code to use
|
|
11
|
+
* defined)
|
|
12
|
+
*/
|
|
13
|
+
declare const handleError: (res: any, error: ({
|
|
14
|
+
message: any;
|
|
15
|
+
code?: string;
|
|
16
|
+
status?: number;
|
|
17
|
+
} | Error | string | any)) => undefined;
|
|
18
|
+
export default handleError;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set the session expiry handler
|
|
3
|
+
* @author Gabe Abrams
|
|
4
|
+
* @param handler new handler to use when session expires
|
|
5
|
+
*/
|
|
6
|
+
export declare const setSessionExpiryHandler: (handler: () => void) => void;
|
|
7
|
+
/**
|
|
8
|
+
* Visit an endpoint on the server [for client only]
|
|
9
|
+
* @author Gabe Abrams
|
|
10
|
+
* @param opts object containing all arguments
|
|
11
|
+
* @param opts.path - the path of the server endpoint
|
|
12
|
+
* @param [opts.method=GET] - the method of the endpoint
|
|
13
|
+
* @param [opts.params] - query/body parameters to include
|
|
14
|
+
* @returns response from server
|
|
15
|
+
*/
|
|
16
|
+
declare const visitServerEndpoint: (opts: {
|
|
17
|
+
path: string;
|
|
18
|
+
method?: "GET" | "POST" | "DELETE" | "PUT" | undefined;
|
|
19
|
+
params?: {
|
|
20
|
+
[x: string]: any;
|
|
21
|
+
} | undefined;
|
|
22
|
+
}) => Promise<any>;
|
|
23
|
+
export default visitServerEndpoint;
|
|
@@ -14,9 +14,15 @@ import padZerosLeft from './helpers/padZerosLeft';
|
|
|
14
14
|
import roundToNumDecimals from './helpers/roundToNumDecimals';
|
|
15
15
|
import sum from './helpers/sum';
|
|
16
16
|
import waitMs from './helpers/waitMs';
|
|
17
|
+
import visitServerEndpoint from './helpers/visitServerEndpoint';
|
|
18
|
+
import genRouteHandler from './helpers/genRouteHandler';
|
|
19
|
+
import handleError from './helpers/handleError';
|
|
20
|
+
import handleSuccess from './helpers/handleSuccess';
|
|
21
|
+
import initServer from './server/initServer';
|
|
17
22
|
import ModalButtonType from './types/ModalButtonType';
|
|
18
23
|
import ModalSize from './types/ModalSize';
|
|
19
24
|
import ModalType from './types/ModalType';
|
|
20
25
|
import ReactKitErrorCode from './types/ReactKitErrorCode';
|
|
21
26
|
import Variant from './types/Variant';
|
|
22
|
-
|
|
27
|
+
import ParamType from './types/ParamType';
|
|
28
|
+
export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, alert, confirm, showFatalError, ErrorWithCode, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, visitServerEndpoint, initServer, genRouteHandler, handleError, handleSuccess, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, ParamType, };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare type GetLaunchInfoFunction = (req: any) => {
|
|
2
|
+
launched: boolean;
|
|
3
|
+
launchInfo?: any;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Get launch info via CACCL
|
|
7
|
+
* @author Gabe Abrams
|
|
8
|
+
* @param req express request object
|
|
9
|
+
* @returns object { launched, launchInfo }
|
|
10
|
+
*/
|
|
11
|
+
export declare const cacclGetLaunchInfo: GetLaunchInfoFunction;
|
|
12
|
+
/**
|
|
13
|
+
* Prepare dce-reactkit to run on the server
|
|
14
|
+
* @author Gabe Abrams
|
|
15
|
+
* @param opts object containing all arguments
|
|
16
|
+
* @param opts.getLaunchInfo CACCL LTI's get launch info function
|
|
17
|
+
*/
|
|
18
|
+
declare const initServer: (opts: {
|
|
19
|
+
getLaunchInfo: GetLaunchInfoFunction;
|
|
20
|
+
}) => void;
|
|
21
|
+
export default initServer;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side API param types
|
|
3
|
+
* @author Gabe Abrams
|
|
4
|
+
*/
|
|
5
|
+
declare enum ParamType {
|
|
6
|
+
Boolean = "boolean",
|
|
7
|
+
BooleanOptional = "boolean-optional",
|
|
8
|
+
Float = "float",
|
|
9
|
+
FloatOptional = "float-optional",
|
|
10
|
+
Int = "int",
|
|
11
|
+
IntOptional = "int-optional",
|
|
12
|
+
JSON = "json",
|
|
13
|
+
JSONOptional = "json-optional",
|
|
14
|
+
String = "string",
|
|
15
|
+
StringOptional = "string-optional"
|
|
16
|
+
}
|
|
17
|
+
export default ParamType;
|
|
@@ -8,6 +8,8 @@ declare enum ReactKitErrorCode {
|
|
|
8
8
|
SessionExpired = "DRK3",
|
|
9
9
|
MissingParameter = "DRK4",
|
|
10
10
|
InvalidParameter = "DRK5",
|
|
11
|
-
WrongCourse = "DRK6"
|
|
11
|
+
WrongCourse = "DRK6",
|
|
12
|
+
NoCACCLSendRequestFunction = "DRK7",
|
|
13
|
+
NoCACCLGetLaunchInfoFunction = "DRK8"
|
|
12
14
|
}
|
|
13
15
|
export default ReactKitErrorCode;
|
package/dist/index.d.ts
CHANGED
|
@@ -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
10
|
declare type Props$3 = {
|
|
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
|
|
@@ -157,6 +175,7 @@ declare const Modal: React.FC<Props$1>;
|
|
|
157
175
|
declare type Props = {
|
|
158
176
|
title: React.ReactNode;
|
|
159
177
|
children: React.ReactNode;
|
|
178
|
+
noBottomPadding?: boolean;
|
|
160
179
|
};
|
|
161
180
|
declare const TabBox: React.FC<Props>;
|
|
162
181
|
|
|
@@ -258,6 +277,107 @@ declare const sum: (nums: number[]) => number;
|
|
|
258
277
|
*/
|
|
259
278
|
declare const waitMs: (ms?: number) => Promise<unknown>;
|
|
260
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Visit an endpoint on the server [for client only]
|
|
282
|
+
* @author Gabe Abrams
|
|
283
|
+
* @param opts object containing all arguments
|
|
284
|
+
* @param opts.path - the path of the server endpoint
|
|
285
|
+
* @param [opts.method=GET] - the method of the endpoint
|
|
286
|
+
* @param [opts.params] - query/body parameters to include
|
|
287
|
+
* @returns response from server
|
|
288
|
+
*/
|
|
289
|
+
declare const visitServerEndpoint: (opts: {
|
|
290
|
+
path: string;
|
|
291
|
+
method?: "GET" | "POST" | "DELETE" | "PUT" | undefined;
|
|
292
|
+
params?: {
|
|
293
|
+
[x: string]: any;
|
|
294
|
+
} | undefined;
|
|
295
|
+
}) => Promise<any>;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Server-side API param types
|
|
299
|
+
* @author Gabe Abrams
|
|
300
|
+
*/
|
|
301
|
+
declare enum ParamType {
|
|
302
|
+
Boolean = "boolean",
|
|
303
|
+
BooleanOptional = "boolean-optional",
|
|
304
|
+
Float = "float",
|
|
305
|
+
FloatOptional = "float-optional",
|
|
306
|
+
Int = "int",
|
|
307
|
+
IntOptional = "int-optional",
|
|
308
|
+
JSON = "json",
|
|
309
|
+
JSONOptional = "json-optional",
|
|
310
|
+
String = "string",
|
|
311
|
+
StringOptional = "string-optional"
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Handle an error and respond to the client
|
|
316
|
+
* @author Gabe Abrams
|
|
317
|
+
* @param res express response
|
|
318
|
+
* @param error error info
|
|
319
|
+
* @param opts.err the error to send to the client
|
|
320
|
+
* or the error message
|
|
321
|
+
* @param [opts.code] an error code (only used if err.code is not
|
|
322
|
+
* included)
|
|
323
|
+
* @param [opts.status=500] the https status code to use
|
|
324
|
+
* defined)
|
|
325
|
+
*/
|
|
326
|
+
declare const handleError: (res: any, error: ({
|
|
327
|
+
message: any;
|
|
328
|
+
code?: string;
|
|
329
|
+
status?: number;
|
|
330
|
+
} | Error | string | any)) => undefined;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Send successful API response
|
|
334
|
+
* @author Gabe Abrams
|
|
335
|
+
* @param res express response
|
|
336
|
+
* @param body the body of the response to send to the client
|
|
337
|
+
*/
|
|
338
|
+
declare const handleSuccess: (res: any, body: any) => undefined;
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Generate an express API route handler
|
|
342
|
+
* @author Gabe Abrams
|
|
343
|
+
* @param opts object containing all arguments
|
|
344
|
+
* @param opts.paramTypes map containing the types for each parameter that is
|
|
345
|
+
* included in the request (map: param name => type)
|
|
346
|
+
* @param opts.handler function that processes the request
|
|
347
|
+
* @returns express route handler that takes the following arguments:
|
|
348
|
+
* params (map: param name => value), handleSuccess (function for handling
|
|
349
|
+
* successful requests), handleError (function for handling failed requests),
|
|
350
|
+
* req (express request object), res (express response object)
|
|
351
|
+
*/
|
|
352
|
+
declare const genRouteHandler: (opts: {
|
|
353
|
+
paramTypes?: {
|
|
354
|
+
[k: string]: ParamType;
|
|
355
|
+
} | undefined;
|
|
356
|
+
handler: (opts: {
|
|
357
|
+
params: {
|
|
358
|
+
[k: string]: any;
|
|
359
|
+
};
|
|
360
|
+
handleSuccess: (body: any) => void;
|
|
361
|
+
handleError: (error: any) => void;
|
|
362
|
+
req: any;
|
|
363
|
+
res: any;
|
|
364
|
+
}) => void;
|
|
365
|
+
}) => (req: any, res: any) => Promise<undefined>;
|
|
366
|
+
|
|
367
|
+
declare type GetLaunchInfoFunction = (req: any) => {
|
|
368
|
+
launched: boolean;
|
|
369
|
+
launchInfo?: any;
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Prepare dce-reactkit to run on the server
|
|
373
|
+
* @author Gabe Abrams
|
|
374
|
+
* @param opts object containing all arguments
|
|
375
|
+
* @param opts.getLaunchInfo CACCL LTI's get launch info function
|
|
376
|
+
*/
|
|
377
|
+
declare const initServer: (opts: {
|
|
378
|
+
getLaunchInfo: GetLaunchInfoFunction;
|
|
379
|
+
}) => void;
|
|
380
|
+
|
|
261
381
|
/**
|
|
262
382
|
* List of error codes built into the react kit
|
|
263
383
|
* @author Gabe Abrams
|
|
@@ -268,7 +388,9 @@ declare enum ReactKitErrorCode {
|
|
|
268
388
|
SessionExpired = "DRK3",
|
|
269
389
|
MissingParameter = "DRK4",
|
|
270
390
|
InvalidParameter = "DRK5",
|
|
271
|
-
WrongCourse = "DRK6"
|
|
391
|
+
WrongCourse = "DRK6",
|
|
392
|
+
NoCACCLSendRequestFunction = "DRK7",
|
|
393
|
+
NoCACCLGetLaunchInfoFunction = "DRK8"
|
|
272
394
|
}
|
|
273
395
|
|
|
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 };
|
|
396
|
+
export { AppWrapper, ErrorBox, ErrorWithCode, LoadingSpinner, Modal, ModalButtonType, ModalSize, ModalType, ParamType, ReactKitErrorCode, TabBox, Variant, abbreviate, alert, avg, ceilToNumDecimals, confirm, floorToNumDecimals, forceNumIntoBounds, genRouteHandler, handleError, handleSuccess, initServer, padDecimalZeros, padZerosLeft, roundToNumDecimals, showFatalError, sum, visitServerEndpoint, waitMs };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dce-reactkit",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.32",
|
|
4
4
|
"description": "Shared components for Harvard DCE apps",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -21,14 +21,24 @@
|
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"@fortawesome/free-solid-svg-icons": "^6.1.1",
|
|
23
23
|
"@fortawesome/react-fontawesome": "^0.1.18",
|
|
24
|
-
"
|
|
25
|
-
"react
|
|
24
|
+
"bootstrap": "^5.1.3",
|
|
25
|
+
"react": "^18.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@rollup/plugin-commonjs": "^22.0.0",
|
|
29
|
+
"@rollup/plugin-json": "^4.1.0",
|
|
29
30
|
"@rollup/plugin-node-resolve": "^13.2.1",
|
|
30
31
|
"@rollup/plugin-typescript": "^8.3.2",
|
|
31
32
|
"@types/react": "^18.0.7",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^5.21.0",
|
|
34
|
+
"@typescript-eslint/parser": "^5.21.0",
|
|
35
|
+
"eslint": "^8.14.0",
|
|
36
|
+
"eslint-config-airbnb": "^19.0.4",
|
|
37
|
+
"eslint-config-airbnb-typescript": "^17.0.0",
|
|
38
|
+
"eslint-plugin-import": "^2.26.0",
|
|
39
|
+
"eslint-plugin-jsx-a11y": "^6.5.1",
|
|
40
|
+
"eslint-plugin-react": "^7.29.4",
|
|
41
|
+
"eslint-plugin-react-hooks": "^4.4.0",
|
|
32
42
|
"rollup": "^2.70.2",
|
|
33
43
|
"rollup-plugin-dts": "^4.2.1",
|
|
34
44
|
"rollup-plugin-sourcemaps": "^0.6.3",
|
package/rollup.config.js
CHANGED
|
@@ -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
|
-
|
|
222
|
-
|
|
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
|
-
|
|
232
|
-
|
|
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
|
|
@@ -260,6 +318,7 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
260
318
|
type={ModalType.Okay}
|
|
261
319
|
onClose={() => {
|
|
262
320
|
// Alert closed
|
|
321
|
+
setAlertInfo(undefined);
|
|
263
322
|
if (onAlertClosed) {
|
|
264
323
|
onAlertClosed();
|
|
265
324
|
}
|
|
@@ -279,13 +338,14 @@ const AppWrapper: React.FC<Props> = (props: Props): React.ReactElement => {
|
|
|
279
338
|
title={confirmInfo.title}
|
|
280
339
|
type={ModalType.OkayCancel}
|
|
281
340
|
onClose={(buttonType) => {
|
|
341
|
+
setConfirmInfo(undefined);
|
|
282
342
|
if (onConfirmClosed) {
|
|
283
343
|
onConfirmClosed(buttonType === ModalButtonType.Okay);
|
|
284
344
|
}
|
|
285
345
|
}}
|
|
286
346
|
dontAllowBackdropExit
|
|
287
347
|
>
|
|
288
|
-
|
|
348
|
+
{confirmInfo.text}
|
|
289
349
|
</Modal>
|
|
290
350
|
);
|
|
291
351
|
}
|
|
@@ -63,9 +63,9 @@ const ErrorBox: React.FC<Props> = (props) => {
|
|
|
63
63
|
<span
|
|
64
64
|
style={{
|
|
65
65
|
backgroundColor: 'white',
|
|
66
|
-
borderRadius: '
|
|
67
|
-
paddingLeft: '
|
|
68
|
-
paddingRight: '
|
|
66
|
+
borderRadius: '0.3rem',
|
|
67
|
+
paddingLeft: '0.2rem',
|
|
68
|
+
paddingRight: '0.2rem',
|
|
69
69
|
color: '#DC4150',
|
|
70
70
|
fontVariant: 'small-caps',
|
|
71
71
|
fontSize: '80%',
|
|
@@ -85,7 +85,7 @@ const ErrorBox: React.FC<Props> = (props) => {
|
|
|
85
85
|
<div
|
|
86
86
|
className="alert alert-danger text-center"
|
|
87
87
|
style={{
|
|
88
|
-
maxWidth: '
|
|
88
|
+
maxWidth: '40rem',
|
|
89
89
|
margin: 'auto',
|
|
90
90
|
}}
|
|
91
91
|
>
|
|
@@ -20,10 +20,10 @@ const style = `
|
|
|
20
20
|
.LoadingSpinner-blip-2,
|
|
21
21
|
.LoadingSpinner-blip-3,
|
|
22
22
|
.LoadingSpinner-blip-4 {
|
|
23
|
-
font-size:
|
|
23
|
+
font-size: 1.8rem;
|
|
24
24
|
opacity: 0.6;
|
|
25
|
-
margin-top:
|
|
26
|
-
margin-bottom:
|
|
25
|
+
margin-top: 1rem;
|
|
26
|
+
margin-bottom: 1rem;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/* First Blip */
|