dce-reactkit 4.0.0-beta.2 → 4.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/.vscode/settings.json +3 -1
- package/README.md +0 -20
- package/dist/cjs/index.js +218 -114
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/ItemPicker/index.d.ts +1 -0
- package/dist/cjs/types/components/Modal/ModalProps.d.ts +2 -0
- package/dist/cjs/types/components/TabBox.d.ts +1 -0
- package/dist/cjs/types/helpers/getWordCount.d.ts +10 -0
- package/dist/cjs/types/index.d.ts +2 -1
- package/dist/esm/index.js +219 -116
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/ItemPicker/index.d.ts +1 -0
- package/dist/esm/types/components/Modal/ModalProps.d.ts +2 -0
- package/dist/esm/types/components/TabBox.d.ts +1 -0
- package/dist/esm/types/helpers/getWordCount.d.ts +10 -0
- package/dist/esm/types/index.d.ts +2 -1
- package/dist/index.d.ts +15 -1
- package/package.json +3 -4
- package/rollup.config.js +0 -2
- package/src/components/IntelliTable.tsx +1 -1
- package/src/components/ItemPicker/NestableItemList.tsx +1 -0
- package/src/components/ItemPicker/index.tsx +96 -0
- package/src/components/Modal/ModalProps.ts +4 -0
- package/src/components/Modal/index.tsx +59 -20
- package/src/components/TabBox.tsx +27 -9
- package/src/helpers/getWordCount.ts +26 -0
- package/src/index.ts +2 -0
- package/genEncodedSecret.ts +0 -84
package/.vscode/settings.json
CHANGED
package/README.md
CHANGED
|
@@ -14,23 +14,3 @@ npm install dce-reactkit --save
|
|
|
14
14
|
```js
|
|
15
15
|
import { LoadingSpinner } from 'dce-reactkit';
|
|
16
16
|
```
|
|
17
|
-
|
|
18
|
-
## Cross-server Requests
|
|
19
|
-
|
|
20
|
-
If your server will be _accepting_ cross-server requests, include a `REACTKIT_CRED_ENCODING_SALT` environment variable with secure, secret text.
|
|
21
|
-
|
|
22
|
-
To generate new encoded secrets, use `npm run gen-reactkit-cross-server-secret`. You'll need to put credentials into a collection. Create that collection in your `mongo.ts` file:
|
|
23
|
-
|
|
24
|
-
```ts
|
|
25
|
-
// Import dce-reactkit
|
|
26
|
-
import { initCrossServerCredentialCollection, CrossServerCredential } from 'dce-reactkit';
|
|
27
|
-
|
|
28
|
-
...
|
|
29
|
-
|
|
30
|
-
// Cross-server Credentials
|
|
31
|
-
export const crossServerCredentialCollection = initCrossServerCredentialCollection(Collection) as Collection<CrossServerCredential>;
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
In that collection, manually insert into the database individual credentials, one for each service. You'll need to add a description, list of allowed scopes, and you'll need to come up with a public key.
|
|
35
|
-
|
|
36
|
-
If your server will be _sending_ cross-server requests, after creating a secret and key using the process above, in the server that will be _sending_ the cross-server requests, add the credential to the environment as `REACTKIT_CROSS_SERVER_KEY` and `REACTKIT_CROSS_SERVER_SECRET`.
|
package/dist/cjs/index.js
CHANGED
|
@@ -897,6 +897,98 @@ function requireReactDom_development () {
|
|
|
897
897
|
|
|
898
898
|
var ReactDOM = /*@__PURE__*/getDefaultExportFromCjs(reactDom.exports);
|
|
899
899
|
|
|
900
|
+
/**
|
|
901
|
+
* Loading spinner/indicator
|
|
902
|
+
* @author Gabe Abrams
|
|
903
|
+
*/
|
|
904
|
+
/*------------------------------------------------------------------------*/
|
|
905
|
+
/* -------------------------------- Style ------------------------------- */
|
|
906
|
+
/*------------------------------------------------------------------------*/
|
|
907
|
+
const style$a = `
|
|
908
|
+
/* Container fades in */
|
|
909
|
+
.LoadingSpinner-container {
|
|
910
|
+
animation-name: LoadingSpinner-container-fade-in;
|
|
911
|
+
animation-duration: 0.3s;
|
|
912
|
+
animation-delay: 0.4s;
|
|
913
|
+
animation-fill-mode: both;
|
|
914
|
+
animation-timing-function: ease-out;
|
|
915
|
+
}
|
|
916
|
+
@keyframes LoadingSpinner-container-fade-in {
|
|
917
|
+
0% {
|
|
918
|
+
opacity: 0;
|
|
919
|
+
}
|
|
920
|
+
100% {
|
|
921
|
+
opacity: 1;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
/* Blips */
|
|
926
|
+
.LoadingSpinner-blip-1,
|
|
927
|
+
.LoadingSpinner-blip-2,
|
|
928
|
+
.LoadingSpinner-blip-3,
|
|
929
|
+
.LoadingSpinner-blip-4 {
|
|
930
|
+
font-size: 1.8rem;
|
|
931
|
+
opacity: 0.6;
|
|
932
|
+
margin-top: 1rem;
|
|
933
|
+
margin-bottom: 1rem;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/* First Blip */
|
|
937
|
+
.LoadingSpinner-blip-1 {
|
|
938
|
+
animation: LoadingSpinner-pop-animation 2s infinite;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
/* Second Blip */
|
|
942
|
+
.LoadingSpinner-blip-2 {
|
|
943
|
+
animation: LoadingSpinner-pop-animation 2s infinite;
|
|
944
|
+
-webkit-animation-delay: 0.1s;
|
|
945
|
+
animation-delay: 0.1s;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/* Third Blip */
|
|
949
|
+
.LoadingSpinner-blip-3 {
|
|
950
|
+
animation: LoadingSpinner-pop-animation 2s infinite;
|
|
951
|
+
animation-delay: 0.2s;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
/* Fourth Blip */
|
|
955
|
+
.LoadingSpinner-blip-4 {
|
|
956
|
+
animation: LoadingSpinner-pop-animation 2s infinite;
|
|
957
|
+
animation-delay: 0.3s;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
/* Pop Animation for Each Blip */
|
|
961
|
+
@keyframes LoadingSpinner-pop-animation {
|
|
962
|
+
0% {
|
|
963
|
+
transform: scale(1.0);
|
|
964
|
+
}
|
|
965
|
+
10% {
|
|
966
|
+
transform: scale(1.5);
|
|
967
|
+
}
|
|
968
|
+
30% {
|
|
969
|
+
transform: scale(1.0);
|
|
970
|
+
}
|
|
971
|
+
100% {
|
|
972
|
+
transform: scale(1.0);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
`;
|
|
976
|
+
/*------------------------------------------------------------------------*/
|
|
977
|
+
/* ------------------------------ Component ----------------------------- */
|
|
978
|
+
/*------------------------------------------------------------------------*/
|
|
979
|
+
const LoadingSpinner = () => {
|
|
980
|
+
/*------------------------------------------------------------------------*/
|
|
981
|
+
/* ------------------------------- Render ------------------------------- */
|
|
982
|
+
/*------------------------------------------------------------------------*/
|
|
983
|
+
// Add all four blips to a container
|
|
984
|
+
return (React__default["default"].createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
|
|
985
|
+
React__default["default"].createElement("style", null, style$a),
|
|
986
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-1 me-1" }),
|
|
987
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-2 me-1" }),
|
|
988
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-3 me-1" }),
|
|
989
|
+
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-4" })));
|
|
990
|
+
};
|
|
991
|
+
|
|
900
992
|
/**
|
|
901
993
|
* Wait for a certain number of ms
|
|
902
994
|
* @author Gabe Abrams
|
|
@@ -1040,6 +1132,7 @@ const BASE_Z_INDEX = 1000000000;
|
|
|
1040
1132
|
const BASE_Z_INDEX_ON_TOP = 2000000000;
|
|
1041
1133
|
// Constants
|
|
1042
1134
|
const MS_TO_ANIMATE = 200; // Animation duration
|
|
1135
|
+
const MS_TO_WAIT_BEFORE_SHOWING_LOADING_INDICATOR = 1000;
|
|
1043
1136
|
// Modal type to list of buttons
|
|
1044
1137
|
const modalTypeToModalButtonTypes = {
|
|
1045
1138
|
[ModalType$1.Okay]: [
|
|
@@ -1153,7 +1246,7 @@ const getNextUniqueId = () => {
|
|
|
1153
1246
|
/*------------------------------------------------------------------------*/
|
|
1154
1247
|
/* -------------------------------- Style ------------------------------- */
|
|
1155
1248
|
/*------------------------------------------------------------------------*/
|
|
1156
|
-
const style$
|
|
1249
|
+
const style$9 = `
|
|
1157
1250
|
.Modal-backdrop {
|
|
1158
1251
|
position: fixed;
|
|
1159
1252
|
top: 0;
|
|
@@ -1225,13 +1318,14 @@ const Modal = (props) => {
|
|
|
1225
1318
|
/*------------------------------------------------------------------------*/
|
|
1226
1319
|
var _a;
|
|
1227
1320
|
/* -------------- Props ------------- */
|
|
1228
|
-
const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, largeTitle, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, } = props;
|
|
1321
|
+
const { type = ModalType$1.NoButtons, size = ModalSize$1.Large, title, largeTitle, children, onClose, dontAllowBackdropExit, dontShowXButton, onTopOfOtherModals, isLoading, isLoadingCancelable, } = props;
|
|
1229
1322
|
// Determine if no header either
|
|
1230
1323
|
const noHeader = (!title && type === ModalType$1.NoButtons);
|
|
1231
1324
|
/* -------------- State ------------- */
|
|
1232
1325
|
// True if animation is in use
|
|
1233
1326
|
const [animatingIn, setAnimatingIn] = React.useState(true);
|
|
1234
1327
|
const [animatingPop, setAnimatingPop] = React.useState(false);
|
|
1328
|
+
const [showModal, setShowModal] = React.useState(false);
|
|
1235
1329
|
/* -------------- Refs -------------- */
|
|
1236
1330
|
// Keep track of whether modal is still mounted
|
|
1237
1331
|
const mounted = React.useRef(false);
|
|
@@ -1258,6 +1352,16 @@ const Modal = (props) => {
|
|
|
1258
1352
|
if (mounted.current) {
|
|
1259
1353
|
setAnimatingIn(false);
|
|
1260
1354
|
}
|
|
1355
|
+
if (isLoading) {
|
|
1356
|
+
// wait before showing modal
|
|
1357
|
+
yield waitMs(MS_TO_WAIT_BEFORE_SHOWING_LOADING_INDICATOR);
|
|
1358
|
+
if (mounted.current) {
|
|
1359
|
+
setShowModal(true);
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
else {
|
|
1363
|
+
setShowModal(true);
|
|
1364
|
+
}
|
|
1261
1365
|
}))();
|
|
1262
1366
|
return () => {
|
|
1263
1367
|
mounted.current = false;
|
|
@@ -1324,6 +1428,15 @@ const Modal = (props) => {
|
|
|
1324
1428
|
else if (animatingPop) {
|
|
1325
1429
|
animationClass = 'Modal-animating-pop';
|
|
1326
1430
|
}
|
|
1431
|
+
// default to show close button when not loading and not show close button when loading
|
|
1432
|
+
// unless downShowXButton or isLoadingCancelable
|
|
1433
|
+
const showCloseButton = (
|
|
1434
|
+
// The modal must have an onClose function
|
|
1435
|
+
onClose
|
|
1436
|
+
// ...and the close button is allowed to be visible
|
|
1437
|
+
&& !dontShowXButton
|
|
1438
|
+
// ...and should not be shown if the modal is loading and not cancelable
|
|
1439
|
+
&& !(isLoading && !isLoadingCancelable));
|
|
1327
1440
|
// Render the modal
|
|
1328
1441
|
const contentToRender = (React__default["default"].createElement("div", { className: "modal show", tabIndex: -1, style: {
|
|
1329
1442
|
zIndex: baseZIndex,
|
|
@@ -1332,7 +1445,7 @@ const Modal = (props) => {
|
|
|
1332
1445
|
left: 0,
|
|
1333
1446
|
right: 0,
|
|
1334
1447
|
} },
|
|
1335
|
-
React__default["default"].createElement("style", null, style$
|
|
1448
|
+
React__default["default"].createElement("style", null, style$9),
|
|
1336
1449
|
React__default["default"].createElement("div", { className: `Modal-backdrop ${backdropAnimationClass}`, style: {
|
|
1337
1450
|
zIndex: baseZIndex + 1,
|
|
1338
1451
|
}, onClick: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -1350,7 +1463,7 @@ const Modal = (props) => {
|
|
|
1350
1463
|
// Handle close
|
|
1351
1464
|
handleClose(ModalButtonType$1.Cancel);
|
|
1352
1465
|
}) }),
|
|
1353
|
-
React__default["default"].createElement("div", { className: `modal-dialog modal-${size} ${animationClass} modal-dialog-scrollable modal-dialog-centered`, style: {
|
|
1466
|
+
showModal && (React__default["default"].createElement("div", { className: `modal-dialog modal-${size} ${animationClass} modal-dialog-scrollable modal-dialog-centered`, style: {
|
|
1354
1467
|
zIndex: baseZIndex + 2,
|
|
1355
1468
|
// Override sizes for even larger for XL
|
|
1356
1469
|
width: (size === ModalSize$1.ExtraLarge
|
|
@@ -1382,7 +1495,7 @@ const Modal = (props) => {
|
|
|
1382
1495
|
? '1.6rem'
|
|
1383
1496
|
: undefined),
|
|
1384
1497
|
} }, title),
|
|
1385
|
-
|
|
1498
|
+
showCloseButton && (React__default["default"].createElement("button", { type: "button", className: "Modal-x-button btn-close", "aria-label": "Close", style: {
|
|
1386
1499
|
backgroundColor: (isDarkModeOn()
|
|
1387
1500
|
? 'white'
|
|
1388
1501
|
: undefined),
|
|
@@ -1390,14 +1503,18 @@ const Modal = (props) => {
|
|
|
1390
1503
|
// Handle close
|
|
1391
1504
|
handleClose(ModalButtonType$1.Cancel);
|
|
1392
1505
|
} })))),
|
|
1393
|
-
|
|
1506
|
+
React__default["default"].createElement("div", { className: "modal-body", style: {
|
|
1394
1507
|
color: (isDarkModeOn()
|
|
1395
1508
|
? 'white'
|
|
1396
1509
|
: undefined),
|
|
1397
1510
|
backgroundColor: (isDarkModeOn()
|
|
1398
1511
|
? '#444'
|
|
1399
1512
|
: undefined),
|
|
1400
|
-
} },
|
|
1513
|
+
} }, isLoading
|
|
1514
|
+
? (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
1515
|
+
React__default["default"].createElement(LoadingSpinner, null),
|
|
1516
|
+
React__default["default"].createElement("span", { className: "sr-only" }, "Content loading")))
|
|
1517
|
+
: children),
|
|
1401
1518
|
footer && (React__default["default"].createElement("div", { className: "modal-footer pt-1 pb-1", style: {
|
|
1402
1519
|
color: (isDarkModeOn()
|
|
1403
1520
|
? 'white'
|
|
@@ -1408,7 +1525,7 @@ const Modal = (props) => {
|
|
|
1408
1525
|
borderTop: (isDarkModeOn()
|
|
1409
1526
|
? '0.1rem solid gray'
|
|
1410
1527
|
: undefined),
|
|
1411
|
-
} }, footer))))));
|
|
1528
|
+
} }, footer)))))));
|
|
1412
1529
|
// Determine which portal to use
|
|
1413
1530
|
const portalNumber = id.current % NUM_MODAL_PORTALS;
|
|
1414
1531
|
// Render in a portal
|
|
@@ -1979,7 +2096,7 @@ const showSessionExpiredMessage = () => __awaiter(void 0, void 0, void 0, functi
|
|
|
1979
2096
|
/*------------------------------------------------------------------------*/
|
|
1980
2097
|
/* -------------------------------- Style ------------------------------- */
|
|
1981
2098
|
/*------------------------------------------------------------------------*/
|
|
1982
|
-
const style$
|
|
2099
|
+
const style$8 = `
|
|
1983
2100
|
.AppWrapper-leave-to-url-notice {
|
|
1984
2101
|
opacity: 0;
|
|
1985
2102
|
|
|
@@ -2193,105 +2310,13 @@ const AppWrapper = (props) => {
|
|
|
2193
2310
|
/* --------------- Main UI -------------- */
|
|
2194
2311
|
/*----------------------------------------*/
|
|
2195
2312
|
return (React__default["default"].createElement(React__default["default"].Fragment, null,
|
|
2196
|
-
React__default["default"].createElement("style", null, style$
|
|
2313
|
+
React__default["default"].createElement("style", null, style$8),
|
|
2197
2314
|
React__default["default"].createElement("style", null, tooltipStyle),
|
|
2198
2315
|
modal,
|
|
2199
2316
|
customModalPortals,
|
|
2200
2317
|
body));
|
|
2201
2318
|
};
|
|
2202
2319
|
|
|
2203
|
-
/**
|
|
2204
|
-
* Loading spinner/indicator
|
|
2205
|
-
* @author Gabe Abrams
|
|
2206
|
-
*/
|
|
2207
|
-
/*------------------------------------------------------------------------*/
|
|
2208
|
-
/* -------------------------------- Style ------------------------------- */
|
|
2209
|
-
/*------------------------------------------------------------------------*/
|
|
2210
|
-
const style$8 = `
|
|
2211
|
-
/* Container fades in */
|
|
2212
|
-
.LoadingSpinner-container {
|
|
2213
|
-
animation-name: LoadingSpinner-container-fade-in;
|
|
2214
|
-
animation-duration: 0.3s;
|
|
2215
|
-
animation-delay: 0.4s;
|
|
2216
|
-
animation-fill-mode: both;
|
|
2217
|
-
animation-timing-function: ease-out;
|
|
2218
|
-
}
|
|
2219
|
-
@keyframes LoadingSpinner-container-fade-in {
|
|
2220
|
-
0% {
|
|
2221
|
-
opacity: 0;
|
|
2222
|
-
}
|
|
2223
|
-
100% {
|
|
2224
|
-
opacity: 1;
|
|
2225
|
-
}
|
|
2226
|
-
}
|
|
2227
|
-
|
|
2228
|
-
/* Blips */
|
|
2229
|
-
.LoadingSpinner-blip-1,
|
|
2230
|
-
.LoadingSpinner-blip-2,
|
|
2231
|
-
.LoadingSpinner-blip-3,
|
|
2232
|
-
.LoadingSpinner-blip-4 {
|
|
2233
|
-
font-size: 1.8rem;
|
|
2234
|
-
opacity: 0.6;
|
|
2235
|
-
margin-top: 1rem;
|
|
2236
|
-
margin-bottom: 1rem;
|
|
2237
|
-
}
|
|
2238
|
-
|
|
2239
|
-
/* First Blip */
|
|
2240
|
-
.LoadingSpinner-blip-1 {
|
|
2241
|
-
animation: LoadingSpinner-pop-animation 2s infinite;
|
|
2242
|
-
}
|
|
2243
|
-
|
|
2244
|
-
/* Second Blip */
|
|
2245
|
-
.LoadingSpinner-blip-2 {
|
|
2246
|
-
animation: LoadingSpinner-pop-animation 2s infinite;
|
|
2247
|
-
-webkit-animation-delay: 0.1s;
|
|
2248
|
-
animation-delay: 0.1s;
|
|
2249
|
-
}
|
|
2250
|
-
|
|
2251
|
-
/* Third Blip */
|
|
2252
|
-
.LoadingSpinner-blip-3 {
|
|
2253
|
-
animation: LoadingSpinner-pop-animation 2s infinite;
|
|
2254
|
-
animation-delay: 0.2s;
|
|
2255
|
-
}
|
|
2256
|
-
|
|
2257
|
-
/* Fourth Blip */
|
|
2258
|
-
.LoadingSpinner-blip-4 {
|
|
2259
|
-
animation: LoadingSpinner-pop-animation 2s infinite;
|
|
2260
|
-
animation-delay: 0.3s;
|
|
2261
|
-
}
|
|
2262
|
-
|
|
2263
|
-
/* Pop Animation for Each Blip */
|
|
2264
|
-
@keyframes LoadingSpinner-pop-animation {
|
|
2265
|
-
0% {
|
|
2266
|
-
transform: scale(1.0);
|
|
2267
|
-
}
|
|
2268
|
-
10% {
|
|
2269
|
-
transform: scale(1.5);
|
|
2270
|
-
}
|
|
2271
|
-
30% {
|
|
2272
|
-
transform: scale(1.0);
|
|
2273
|
-
}
|
|
2274
|
-
100% {
|
|
2275
|
-
transform: scale(1.0);
|
|
2276
|
-
}
|
|
2277
|
-
}
|
|
2278
|
-
`;
|
|
2279
|
-
/*------------------------------------------------------------------------*/
|
|
2280
|
-
/* ------------------------------ Component ----------------------------- */
|
|
2281
|
-
/*------------------------------------------------------------------------*/
|
|
2282
|
-
const LoadingSpinner = () => {
|
|
2283
|
-
/*------------------------------------------------------------------------*/
|
|
2284
|
-
/* ------------------------------- Render ------------------------------- */
|
|
2285
|
-
/*------------------------------------------------------------------------*/
|
|
2286
|
-
// Add all four blips to a container
|
|
2287
|
-
return (React__default["default"].createElement("div", { className: "text-center LoadingSpinner LoadingSpinner-container" },
|
|
2288
|
-
React__default["default"].createElement("style", null, style$8),
|
|
2289
|
-
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-1 me-1" }),
|
|
2290
|
-
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-2 me-1" }),
|
|
2291
|
-
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-3 me-1" }),
|
|
2292
|
-
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faCircle, className: "LoadingSpinner-blip-4" })));
|
|
2293
|
-
};
|
|
2294
|
-
|
|
2295
2320
|
/**
|
|
2296
2321
|
* A box with a tab on the top that holds buttons and other content
|
|
2297
2322
|
* @author Gabe Abrams
|
|
@@ -2323,7 +2348,9 @@ const style$7 = `
|
|
|
2323
2348
|
|
|
2324
2349
|
/* Container for Title */
|
|
2325
2350
|
.TabBox-title-container {
|
|
2326
|
-
|
|
2351
|
+
display: flex;
|
|
2352
|
+
justify-content: space-between;
|
|
2353
|
+
align-items: center;
|
|
2327
2354
|
position: relative;
|
|
2328
2355
|
left: 0;
|
|
2329
2356
|
text-align: left;
|
|
@@ -2356,6 +2383,19 @@ const style$7 = `
|
|
|
2356
2383
|
background: #fdfdfd;
|
|
2357
2384
|
}
|
|
2358
2385
|
|
|
2386
|
+
.TabBox-title-right-container {
|
|
2387
|
+
display: flex;
|
|
2388
|
+
flex-direction: row;
|
|
2389
|
+
align-items: bottom;
|
|
2390
|
+
height: 2.4rem;
|
|
2391
|
+
overflow: visible;
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
.TabBox-title-right-contents {
|
|
2395
|
+
margin-right: 0.5rem;
|
|
2396
|
+
margin-bottom: 0.2rem;
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2359
2399
|
/* Make the TabBox's Children Appear Above Title if Overlap Occurs */
|
|
2360
2400
|
.TabBox-children {
|
|
2361
2401
|
position: relative;
|
|
@@ -2369,19 +2409,16 @@ const TabBox = (props) => {
|
|
|
2369
2409
|
/*------------------------------------------------------------------------*/
|
|
2370
2410
|
/* -------------------------------- Setup ------------------------------- */
|
|
2371
2411
|
/*------------------------------------------------------------------------*/
|
|
2372
|
-
|
|
2373
|
-
const { title, children, noBottomPadding, noBottomMargin, } = props;
|
|
2412
|
+
const { title, children, topRightChildren, noBottomPadding, noBottomMargin, } = props;
|
|
2374
2413
|
/*------------------------------------------------------------------------*/
|
|
2375
2414
|
/* ------------------------------- Render ------------------------------- */
|
|
2376
2415
|
/*------------------------------------------------------------------------*/
|
|
2377
|
-
/*----------------------------------------*/
|
|
2378
|
-
/* --------------- Main UI -------------- */
|
|
2379
|
-
/*----------------------------------------*/
|
|
2380
|
-
// Full UI
|
|
2381
2416
|
return (React__default["default"].createElement("div", { className: `TabBox-container ${noBottomMargin ? '' : 'mb-2'}` },
|
|
2382
2417
|
React__default["default"].createElement("style", null, style$7),
|
|
2383
2418
|
React__default["default"].createElement("div", { className: "TabBox-title-container" },
|
|
2384
|
-
React__default["default"].createElement("div", { className: "TabBox-title" }, title)
|
|
2419
|
+
React__default["default"].createElement("div", { className: "TabBox-title" }, title),
|
|
2420
|
+
topRightChildren && (React__default["default"].createElement("div", { className: "TabBox-title-right-container" },
|
|
2421
|
+
React__default["default"].createElement("div", { className: "TabBox-title-right-contents" }, topRightChildren)))),
|
|
2385
2422
|
React__default["default"].createElement("div", { className: `TabBox-box ps-2 pt-2 pe-2 ${noBottomPadding ? '' : 'pb-2'}` },
|
|
2386
2423
|
React__default["default"].createElement("div", { className: "TabBox-children" }, children))));
|
|
2387
2424
|
};
|
|
@@ -3368,7 +3405,7 @@ const NestableItemList = (props) => {
|
|
|
3368
3405
|
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: childExpanded[item.id] ? freeSolidSvgIcons.faChevronDown : freeSolidSvgIcons.faChevronRight })))),
|
|
3369
3406
|
React__default["default"].createElement(CheckboxButton, { className: `NestableItemList-CheckboxButton-${item.id}`, text: item.name, checked: item.isGroup ? allChecked(item.children) : item.checked, dashed: item.isGroup ? !noneChecked(item.children) : false, onChanged: (checked) => {
|
|
3370
3407
|
onChanged(changeChecked(item.id, checked, items));
|
|
3371
|
-
}, ariaLabel: `Select ${item.name}`, checkedVariant: Variant$1.Light }),
|
|
3408
|
+
}, ariaLabel: `Select ${item.name}`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }),
|
|
3372
3409
|
(item.isGroup && childExpanded[item.id]) && (React__default["default"].createElement("div", { className: "NestableItemList-children-container", style: {
|
|
3373
3410
|
paddingLeft: '2.2rem',
|
|
3374
3411
|
} },
|
|
@@ -3391,17 +3428,62 @@ const ItemPicker = (props) => {
|
|
|
3391
3428
|
/*------------------------------------------------------------------------*/
|
|
3392
3429
|
/* -------------- Props ------------- */
|
|
3393
3430
|
// Destructure all props
|
|
3394
|
-
const { title, items, onChanged, noBottomMargin, } = props;
|
|
3431
|
+
const { title, items, onChanged, noBottomMargin, hideSelectAllOrNoneButtons, } = props;
|
|
3395
3432
|
/*------------------------------------------------------------------------*/
|
|
3396
3433
|
/* ------------------------- Component Functions ------------------------ */
|
|
3397
3434
|
/*------------------------------------------------------------------------*/
|
|
3435
|
+
/**
|
|
3436
|
+
* Updates the checked state of an item (including all children)
|
|
3437
|
+
* @author Yuen Ler Chow
|
|
3438
|
+
* @param item the item to update
|
|
3439
|
+
* @param checked the new checked state
|
|
3440
|
+
* @returns the updated item
|
|
3441
|
+
*/
|
|
3442
|
+
const updateItemChecked = (item, checked) => {
|
|
3443
|
+
if (item.isGroup) {
|
|
3444
|
+
return Object.assign(Object.assign({}, item), { children: item.children.map((child) => {
|
|
3445
|
+
return updateItemChecked(child, checked);
|
|
3446
|
+
}) });
|
|
3447
|
+
}
|
|
3448
|
+
return Object.assign(Object.assign({}, item), { checked });
|
|
3449
|
+
};
|
|
3450
|
+
/**
|
|
3451
|
+
* Selects all items in the list
|
|
3452
|
+
* @author Yuen Ler Chow
|
|
3453
|
+
*/
|
|
3454
|
+
const handleSelectAll = () => {
|
|
3455
|
+
const updatedItems = items.map((item) => {
|
|
3456
|
+
return updateItemChecked(item, true);
|
|
3457
|
+
});
|
|
3458
|
+
onChanged(updatedItems);
|
|
3459
|
+
};
|
|
3460
|
+
/**
|
|
3461
|
+
* Deselects all items in the list
|
|
3462
|
+
* @author Yuen Ler Chow
|
|
3463
|
+
*/
|
|
3464
|
+
const handleDeselectAll = () => {
|
|
3465
|
+
const updatedItems = items.map((item) => {
|
|
3466
|
+
return updateItemChecked(item, false);
|
|
3467
|
+
});
|
|
3468
|
+
onChanged(updatedItems);
|
|
3469
|
+
};
|
|
3398
3470
|
/*------------------------------------------------------------------------*/
|
|
3399
3471
|
/* ------------------------------- Render ------------------------------- */
|
|
3400
3472
|
/*------------------------------------------------------------------------*/
|
|
3401
3473
|
/*----------------------------------------*/
|
|
3402
3474
|
/* --------------- Main UI -------------- */
|
|
3403
3475
|
/*----------------------------------------*/
|
|
3404
|
-
|
|
3476
|
+
// Select all/none
|
|
3477
|
+
const selectAllOrNone = (!hideSelectAllOrNoneButtons
|
|
3478
|
+
? (React__default["default"].createElement("div", { className: "d-flex h-100 align-items-end flex-row" },
|
|
3479
|
+
React__default["default"].createElement("div", { className: "d-flex justify-content-end" },
|
|
3480
|
+
React__default["default"].createElement("div", { className: "me-2", style: { fontSize: '1.2rem' } }, "Select"),
|
|
3481
|
+
React__default["default"].createElement("div", { className: "btn-group", role: "group" },
|
|
3482
|
+
React__default["default"].createElement("button", { type: "button", style: { borderRight: '0.1rem solid white' }, "aria-label": "Select all contexts", className: "btn btn-secondary py-0", onClick: handleSelectAll }, "All"),
|
|
3483
|
+
React__default["default"].createElement("button", { type: "button", "aria-label": "Deselect all contexts", className: "btn btn-secondary py-0", onClick: handleDeselectAll }, "None")))))
|
|
3484
|
+
: undefined);
|
|
3485
|
+
// Main UI
|
|
3486
|
+
return (React__default["default"].createElement(TabBox, { title: title, noBottomMargin: noBottomMargin, topRightChildren: selectAllOrNone },
|
|
3405
3487
|
React__default["default"].createElement("div", { style: { overflowX: 'auto' } },
|
|
3406
3488
|
React__default["default"].createElement(NestableItemList, { items: items, onChanged: onChanged }))));
|
|
3407
3489
|
};
|
|
@@ -3773,7 +3855,7 @@ const IntelliTable = (props) => {
|
|
|
3773
3855
|
param: column.param,
|
|
3774
3856
|
visible: checked,
|
|
3775
3857
|
});
|
|
3776
|
-
}, checked: columnVisibilityMap[column.param], ariaLabel: `show "${column.title}" column in the ${title} table`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.
|
|
3858
|
+
}, checked: columnVisibilityMap[column.param], ariaLabel: `show "${column.title}" column in the ${title} table`, checkedVariant: Variant$1.Light, uncheckedVariant: Variant$1.Light }));
|
|
3777
3859
|
}),
|
|
3778
3860
|
React__default["default"].createElement("div", { className: "mt-3" }, "Or you can:"),
|
|
3779
3861
|
React__default["default"].createElement("button", { type: "button", id: `IntelliTable-${id}-select-all-columns`, className: "btn btn-secondary me-2", "aria-label": `show all columns in the ${title} table`, onClick: () => {
|
|
@@ -16107,6 +16189,27 @@ const shuffleArray = (arr) => {
|
|
|
16107
16189
|
return newArr;
|
|
16108
16190
|
};
|
|
16109
16191
|
|
|
16192
|
+
const punctuationRegex = /[!@#$%^&*(),.?\/;:'"\-\[\]]/g;
|
|
16193
|
+
/**
|
|
16194
|
+
* Get number of words in string
|
|
16195
|
+
* @author Gardenia Liu
|
|
16196
|
+
* @author Allison Zhang
|
|
16197
|
+
* @author Gabe Abrams
|
|
16198
|
+
* @param text the string to check
|
|
16199
|
+
* @returns number of words in the string
|
|
16200
|
+
*/
|
|
16201
|
+
const getWordCount = (text) => {
|
|
16202
|
+
const trimmedTextWithoutPunctuation = (text
|
|
16203
|
+
// Remove leading and trailing whitespace
|
|
16204
|
+
.trim()
|
|
16205
|
+
// Remove punctuation
|
|
16206
|
+
.replace(punctuationRegex, ''));
|
|
16207
|
+
if (trimmedTextWithoutPunctuation.length === 0) {
|
|
16208
|
+
return 0;
|
|
16209
|
+
}
|
|
16210
|
+
return trimmedTextWithoutPunctuation.split(/\s+/g).length;
|
|
16211
|
+
};
|
|
16212
|
+
|
|
16110
16213
|
/**
|
|
16111
16214
|
* Days of the week
|
|
16112
16215
|
* @author Gabe Abrams
|
|
@@ -16193,6 +16296,7 @@ exports.getMonthName = getMonthName;
|
|
|
16193
16296
|
exports.getOrdinal = getOrdinal;
|
|
16194
16297
|
exports.getPartOfDay = getPartOfDay;
|
|
16195
16298
|
exports.getTimeInfoInET = getTimeInfoInET;
|
|
16299
|
+
exports.getWordCount = getWordCount;
|
|
16196
16300
|
exports.idify = idify;
|
|
16197
16301
|
exports.initClient = initClient;
|
|
16198
16302
|
exports.isMobileOrTablet = isMobileOrTablet;
|