dce-reactkit 3.5.1-beta.1 → 3.5.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.
- package/.eslintrc.js +0 -2
- package/dist/cjs/index.js +319 -26
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/client/initClient.d.ts +1 -1
- package/dist/cjs/types/components/AppWrapper.d.ts +6 -6
- package/dist/cjs/types/components/ButtonInputGroup.d.ts +1 -1
- package/dist/cjs/types/components/CSVDownloadButton.d.ts +1 -1
- package/dist/cjs/types/components/CheckboxButton.d.ts +1 -1
- package/dist/cjs/types/components/CopiableBox.d.ts +1 -1
- package/dist/cjs/types/components/DBEntryManagerPanel/AddOrEditDBEntry/CreatableMultiselect.d.ts +7 -1
- package/dist/cjs/types/components/DBEntryManagerPanel/AddOrEditDBEntry/index.d.ts +5 -4
- package/dist/cjs/types/components/DBEntryManagerPanel/helpers/generateEndpointPath.d.ts +1 -1
- package/dist/cjs/types/components/DBEntryManagerPanel/index.d.ts +13 -2
- package/dist/cjs/types/components/DBEntryManagerPanel/types/DBEntry.d.ts +1 -1
- package/dist/cjs/types/components/DBEntryManagerPanel/types/DBEntryField.d.ts +1 -1
- package/dist/cjs/types/components/Drawer.d.ts +1 -1
- package/dist/cjs/types/components/ErrorBox.d.ts +1 -1
- package/dist/cjs/types/components/IntelliTable.d.ts +1 -1
- package/dist/cjs/types/components/ItemPicker/NestableItemList.d.ts +1 -1
- package/dist/cjs/types/components/ItemPicker/index.d.ts +1 -1
- package/dist/cjs/types/components/ItemPicker/types/PickableItem.d.ts +1 -1
- package/dist/cjs/types/components/LogReviewer.d.ts +1 -1
- package/dist/cjs/types/components/Modal.d.ts +1 -1
- package/dist/cjs/types/components/PopFailureMark.d.ts +1 -1
- package/dist/cjs/types/components/PopPendingMark.d.ts +1 -1
- package/dist/cjs/types/components/PopSuccessMark.d.ts +1 -1
- package/dist/cjs/types/components/RadioButton.d.ts +1 -1
- package/dist/cjs/types/components/SimpleDateChooser.d.ts +1 -1
- package/dist/cjs/types/components/TabBox.d.ts +1 -1
- package/dist/cjs/types/helpers/abbreviate.test.d.ts +5 -0
- package/dist/cjs/types/helpers/addDBEditorEndpoints.d.ts +4 -3
- package/dist/cjs/types/helpers/avg.test.d.ts +5 -0
- package/dist/cjs/types/helpers/canReviewLogs.d.ts +5 -0
- package/dist/cjs/types/helpers/canReviewLogs.test.d.ts +5 -0
- package/dist/cjs/types/helpers/ceilToNumDecimals.test.d.ts +5 -0
- package/dist/cjs/types/helpers/compareArraysByProp.d.ts +3 -2
- package/dist/cjs/types/helpers/compareArraysByProp.test.d.ts +5 -0
- package/dist/cjs/types/helpers/extractProp.test.d.ts +5 -0
- package/dist/cjs/types/helpers/floorToNumDecimals.test.d.ts +5 -0
- package/dist/cjs/types/helpers/forceNumIntoBounds.test.d.ts +5 -0
- package/dist/cjs/types/helpers/genCSV.test.d.ts +5 -0
- package/dist/cjs/types/helpers/genCommaList.d.ts +12 -0
- package/dist/cjs/types/helpers/genCommaList.test.d.ts +1 -0
- package/dist/cjs/types/helpers/genRouteHandler.d.ts +7 -7
- package/dist/cjs/types/helpers/getHumanReadableDate.d.ts +1 -1
- package/dist/cjs/types/helpers/getHumanReadableDate.test.d.ts +5 -0
- package/dist/cjs/types/helpers/getLocalTimeInfo.d.ts +1 -1
- package/dist/cjs/types/helpers/getLocalTimeInfo.test.d.ts +6 -0
- package/dist/cjs/types/helpers/getMonthName.test.d.ts +5 -0
- package/dist/cjs/types/helpers/getOrdinal.test.d.ts +5 -0
- package/dist/cjs/types/helpers/getPartOfDay.test.d.ts +5 -0
- package/dist/cjs/types/helpers/getTimeInfoInET.d.ts +1 -1
- package/dist/cjs/types/helpers/getTimeInfoInET.test.d.ts +5 -0
- package/dist/cjs/types/helpers/parallelLimit.d.ts +1 -1
- package/dist/cjs/types/helpers/validators/shared/constants/ERROR_MESSAGES.d.ts +10 -0
- package/dist/cjs/types/helpers/validators/shared/helpers/validateRegex.d.ts +19 -0
- package/dist/cjs/types/helpers/validators/shared/types/ValidationResult.d.ts +12 -0
- package/dist/cjs/types/helpers/validators/validateEmail.d.ts +11 -0
- package/dist/cjs/types/helpers/validators/validateEmail.test.d.ts +1 -0
- package/dist/cjs/types/helpers/validators/validatePhoneNumber.d.ts +11 -0
- package/dist/cjs/types/helpers/validators/validatePhoneNumber.test.d.ts +1 -0
- package/dist/cjs/types/helpers/validators/validateString.d.ts +22 -0
- package/dist/cjs/types/helpers/validators/validateString.test.d.ts +1 -0
- package/dist/cjs/types/index.d.ts +5 -1
- package/dist/cjs/types/server/initServer.d.ts +1 -1
- package/dist/cjs/types/types/IntelliTableColumn.d.ts +1 -1
- package/dist/cjs/types/types/Log/LogMainInfo.d.ts +1 -1
- package/dist/cjs/types/types/Log/LogSourceSpecificInfo.d.ts +1 -1
- package/dist/cjs/types/types/Log/LogTypeSpecificInfo.d.ts +1 -1
- package/dist/cjs/types/types/Log/index.d.ts +1 -1
- package/dist/cjs/types/types/LogFunction.d.ts +1 -1
- package/dist/cjs/types/types/LogMetadataContextMap.d.ts +1 -1
- package/dist/cjs/types/types/LogMetadataTagMap.d.ts +1 -1
- package/dist/cjs/types/types/LogMetadataTargetMap.d.ts +1 -1
- package/dist/cjs/types/types/LogMetadataType.d.ts +1 -1
- package/dist/esm/index.js +316 -27
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/client/initClient.d.ts +1 -1
- package/dist/esm/types/components/AppWrapper.d.ts +6 -6
- package/dist/esm/types/components/ButtonInputGroup.d.ts +1 -1
- package/dist/esm/types/components/CSVDownloadButton.d.ts +1 -1
- package/dist/esm/types/components/CheckboxButton.d.ts +1 -1
- package/dist/esm/types/components/CopiableBox.d.ts +1 -1
- package/dist/esm/types/components/DBEntryManagerPanel/AddOrEditDBEntry/CreatableMultiselect.d.ts +7 -1
- package/dist/esm/types/components/DBEntryManagerPanel/AddOrEditDBEntry/index.d.ts +5 -4
- package/dist/esm/types/components/DBEntryManagerPanel/helpers/generateEndpointPath.d.ts +1 -1
- package/dist/esm/types/components/DBEntryManagerPanel/index.d.ts +13 -2
- package/dist/esm/types/components/DBEntryManagerPanel/types/DBEntry.d.ts +1 -1
- package/dist/esm/types/components/DBEntryManagerPanel/types/DBEntryField.d.ts +1 -1
- package/dist/esm/types/components/Drawer.d.ts +1 -1
- package/dist/esm/types/components/ErrorBox.d.ts +1 -1
- package/dist/esm/types/components/IntelliTable.d.ts +1 -1
- package/dist/esm/types/components/ItemPicker/NestableItemList.d.ts +1 -1
- package/dist/esm/types/components/ItemPicker/index.d.ts +1 -1
- package/dist/esm/types/components/ItemPicker/types/PickableItem.d.ts +1 -1
- package/dist/esm/types/components/LogReviewer.d.ts +1 -1
- package/dist/esm/types/components/Modal.d.ts +1 -1
- package/dist/esm/types/components/PopFailureMark.d.ts +1 -1
- package/dist/esm/types/components/PopPendingMark.d.ts +1 -1
- package/dist/esm/types/components/PopSuccessMark.d.ts +1 -1
- package/dist/esm/types/components/RadioButton.d.ts +1 -1
- package/dist/esm/types/components/SimpleDateChooser.d.ts +1 -1
- package/dist/esm/types/components/TabBox.d.ts +1 -1
- package/dist/esm/types/helpers/abbreviate.test.d.ts +5 -0
- package/dist/esm/types/helpers/addDBEditorEndpoints.d.ts +4 -3
- package/dist/esm/types/helpers/avg.test.d.ts +5 -0
- package/dist/esm/types/helpers/canReviewLogs.d.ts +5 -0
- package/dist/esm/types/helpers/canReviewLogs.test.d.ts +5 -0
- package/dist/esm/types/helpers/ceilToNumDecimals.test.d.ts +5 -0
- package/dist/esm/types/helpers/compareArraysByProp.d.ts +3 -2
- package/dist/esm/types/helpers/compareArraysByProp.test.d.ts +5 -0
- package/dist/esm/types/helpers/extractProp.test.d.ts +5 -0
- package/dist/esm/types/helpers/floorToNumDecimals.test.d.ts +5 -0
- package/dist/esm/types/helpers/forceNumIntoBounds.test.d.ts +5 -0
- package/dist/esm/types/helpers/genCSV.test.d.ts +5 -0
- package/dist/esm/types/helpers/genCommaList.d.ts +12 -0
- package/dist/esm/types/helpers/genCommaList.test.d.ts +1 -0
- package/dist/esm/types/helpers/genRouteHandler.d.ts +7 -7
- package/dist/esm/types/helpers/getHumanReadableDate.d.ts +1 -1
- package/dist/esm/types/helpers/getHumanReadableDate.test.d.ts +5 -0
- package/dist/esm/types/helpers/getLocalTimeInfo.d.ts +1 -1
- package/dist/esm/types/helpers/getLocalTimeInfo.test.d.ts +6 -0
- package/dist/esm/types/helpers/getMonthName.test.d.ts +5 -0
- package/dist/esm/types/helpers/getOrdinal.test.d.ts +5 -0
- package/dist/esm/types/helpers/getPartOfDay.test.d.ts +5 -0
- package/dist/esm/types/helpers/getTimeInfoInET.d.ts +1 -1
- package/dist/esm/types/helpers/getTimeInfoInET.test.d.ts +5 -0
- package/dist/esm/types/helpers/parallelLimit.d.ts +1 -1
- package/dist/esm/types/helpers/validators/shared/constants/ERROR_MESSAGES.d.ts +10 -0
- package/dist/esm/types/helpers/validators/shared/helpers/validateRegex.d.ts +19 -0
- package/dist/esm/types/helpers/validators/shared/types/ValidationResult.d.ts +12 -0
- package/dist/esm/types/helpers/validators/validateEmail.d.ts +11 -0
- package/dist/esm/types/helpers/validators/validateEmail.test.d.ts +1 -0
- package/dist/esm/types/helpers/validators/validatePhoneNumber.d.ts +11 -0
- package/dist/esm/types/helpers/validators/validatePhoneNumber.test.d.ts +1 -0
- package/dist/esm/types/helpers/validators/validateString.d.ts +22 -0
- package/dist/esm/types/helpers/validators/validateString.test.d.ts +1 -0
- package/dist/esm/types/index.d.ts +5 -1
- package/dist/esm/types/server/initServer.d.ts +1 -1
- package/dist/esm/types/types/IntelliTableColumn.d.ts +1 -1
- package/dist/esm/types/types/Log/LogMainInfo.d.ts +1 -1
- package/dist/esm/types/types/Log/LogSourceSpecificInfo.d.ts +1 -1
- package/dist/esm/types/types/Log/LogTypeSpecificInfo.d.ts +1 -1
- package/dist/esm/types/types/Log/index.d.ts +1 -1
- package/dist/esm/types/types/LogFunction.d.ts +1 -1
- package/dist/esm/types/types/LogMetadataContextMap.d.ts +1 -1
- package/dist/esm/types/types/LogMetadataTagMap.d.ts +1 -1
- package/dist/esm/types/types/LogMetadataTargetMap.d.ts +1 -1
- package/dist/esm/types/types/LogMetadataType.d.ts +1 -1
- package/dist/index.d.ts +134 -56
- package/package.json +14 -13
- package/src/components/ItemPicker/index.test.tsx +10 -10
- package/src/helpers/abbreviate.test.ts +26 -0
- package/src/helpers/avg.test.ts +24 -0
- package/src/helpers/canReviewLogs.test.ts +67 -0
- package/src/helpers/canReviewLogs.ts +20 -0
- package/src/helpers/ceilToNumDecimals.test.ts +39 -0
- package/src/helpers/compareArraysByProp.test.ts +102 -0
- package/src/helpers/compareArraysByProp.ts +41 -19
- package/src/helpers/extractProp.test.ts +34 -0
- package/src/helpers/floorToNumDecimals.test.ts +39 -0
- package/src/helpers/forceNumIntoBounds.test.ts +34 -0
- package/src/helpers/genCSV.test.ts +61 -0
- package/src/helpers/genCSV.ts +5 -2
- package/src/helpers/genCommaList.test.ts +57 -0
- package/src/helpers/genCommaList.ts +21 -0
- package/src/helpers/getHumanReadableDate.test.ts +29 -0
- package/src/helpers/getLocalTimeInfo.test.ts +48 -0
- package/src/helpers/getMonthName.test.ts +79 -0
- package/src/helpers/getOrdinal.test.ts +84 -0
- package/src/helpers/{getOrdinal.tsx → getOrdinal.ts} +1 -0
- package/src/helpers/getPartOfDay.test.ts +56 -0
- package/src/helpers/getTimeInfoInET.test.ts +72 -0
- package/src/helpers/validators/shared/constants/ERROR_MESSAGES.ts +18 -0
- package/src/helpers/validators/shared/helpers/validateRegex.ts +47 -0
- package/src/helpers/validators/shared/types/ValidationResult.ts +20 -0
- package/src/helpers/validators/validateEmail.test.ts +110 -0
- package/src/helpers/validators/validateEmail.ts +47 -0
- package/src/helpers/validators/validatePhoneNumber.test.ts +94 -0
- package/src/helpers/validators/validatePhoneNumber.ts +49 -0
- package/src/helpers/validators/validateString.test.ts +175 -0
- package/src/helpers/validators/validateString.ts +171 -0
- package/src/index.ts +8 -0
- package/tsconfig.json +6 -2
- /package/src/helpers/{abbreviate.tsx → abbreviate.ts} +0 -0
- /package/src/helpers/{avg.tsx → avg.ts} +0 -0
- /package/src/helpers/{ceilToNumDecimals.tsx → ceilToNumDecimals.ts} +0 -0
- /package/src/helpers/{floorToNumDecimals.tsx → floorToNumDecimals.ts} +0 -0
- /package/src/helpers/{forceNumIntoBounds.tsx → forceNumIntoBounds.ts} +0 -0
- /package/src/helpers/{getLocalTimeInfo.tsx → getLocalTimeInfo.ts} +0 -0
- /package/src/helpers/{getTimeInfoInET.tsx → getTimeInfoInET.ts} +0 -0
package/.eslintrc.js
CHANGED
package/dist/cjs/index.js
CHANGED
|
@@ -1301,6 +1301,7 @@ const getMonthName = (month) => {
|
|
|
1301
1301
|
return ((_a = monthNames[month - 1]) !== null && _a !== void 0 ? _a : monthNames[0]);
|
|
1302
1302
|
};
|
|
1303
1303
|
|
|
1304
|
+
// Constants
|
|
1304
1305
|
const ORDINALS = ['th', 'st', 'nd', 'rd'];
|
|
1305
1306
|
/**
|
|
1306
1307
|
* Get a number's ordinal
|
|
@@ -2296,12 +2297,13 @@ const roundToNumDecimals = (num, numDecimals) => {
|
|
|
2296
2297
|
* @returns escaped cell text
|
|
2297
2298
|
*/
|
|
2298
2299
|
const escapeCellText = (text) => {
|
|
2299
|
-
if (!String(text).includes(',')
|
|
2300
|
+
if (!String(text).includes(',')
|
|
2301
|
+
&& !String(text).includes('"')) {
|
|
2300
2302
|
// No need to escape
|
|
2301
2303
|
return String(text);
|
|
2302
2304
|
}
|
|
2303
2305
|
// Perform escape
|
|
2304
|
-
return `"${String(text).replace(/"/g, '""')}`;
|
|
2306
|
+
return `"${String(text).replace(/"/g, '""')}"`;
|
|
2305
2307
|
};
|
|
2306
2308
|
/**
|
|
2307
2309
|
* Generate a CSV file
|
|
@@ -39457,7 +39459,12 @@ var CreatableSelect = /*#__PURE__*/React.forwardRef(function (props, ref) {
|
|
|
39457
39459
|
});
|
|
39458
39460
|
var CreatableSelect$1 = CreatableSelect;
|
|
39459
39461
|
|
|
39460
|
-
|
|
39462
|
+
/**
|
|
39463
|
+
* Multiselect component that allows the user to type in values and add them to
|
|
39464
|
+
* the multiselect component
|
|
39465
|
+
* @author Yuen Ler Chow
|
|
39466
|
+
* @author Gabe Abrams
|
|
39467
|
+
*/
|
|
39461
39468
|
/* ------------- Actions ------------ */
|
|
39462
39469
|
// Types of actions
|
|
39463
39470
|
var ActionType$2;
|
|
@@ -39470,6 +39477,7 @@ var ActionType$2;
|
|
|
39470
39477
|
* @author Yuen Ler Chow
|
|
39471
39478
|
* @param state current state
|
|
39472
39479
|
* @param action action to execute
|
|
39480
|
+
* @returns updated state
|
|
39473
39481
|
*/
|
|
39474
39482
|
const reducer$2 = (state, action) => {
|
|
39475
39483
|
switch (action.type) {
|
|
@@ -39503,14 +39511,18 @@ const CreatableMultiselect = (props) => {
|
|
|
39503
39511
|
* Creates an option for the multiselect component
|
|
39504
39512
|
* @author Yuen Ler Chow
|
|
39505
39513
|
* @param label label of the option
|
|
39514
|
+
* @returns the new option
|
|
39506
39515
|
*/
|
|
39507
39516
|
const createOption = (label) => {
|
|
39508
39517
|
// set the value to the label without special characters and spaces, and lowercase
|
|
39509
39518
|
return {
|
|
39510
39519
|
label,
|
|
39511
39520
|
value: (label
|
|
39521
|
+
// Make lowercase
|
|
39512
39522
|
.toLowerCase()
|
|
39523
|
+
// Replace special characters with nothing
|
|
39513
39524
|
.replace(/\W/g, '')
|
|
39525
|
+
// Replace spaces with dashes
|
|
39514
39526
|
.replace(' ', '-')),
|
|
39515
39527
|
};
|
|
39516
39528
|
};
|
|
@@ -39540,6 +39552,7 @@ const CreatableMultiselect = (props) => {
|
|
|
39540
39552
|
return value === numberVal;
|
|
39541
39553
|
});
|
|
39542
39554
|
}));
|
|
39555
|
+
// Notify parent of new values
|
|
39543
39556
|
onChange([...values, ...newValues]);
|
|
39544
39557
|
}
|
|
39545
39558
|
else {
|
|
@@ -39560,9 +39573,10 @@ const CreatableMultiselect = (props) => {
|
|
|
39560
39573
|
return value === val;
|
|
39561
39574
|
});
|
|
39562
39575
|
}));
|
|
39576
|
+
// Notify parent of new values
|
|
39563
39577
|
onChange([...values, ...newValues]);
|
|
39564
39578
|
}
|
|
39565
|
-
//
|
|
39579
|
+
// Reset text field to empty because the values have been added
|
|
39566
39580
|
dispatch({
|
|
39567
39581
|
type: ActionType$2.SetInputValue,
|
|
39568
39582
|
value: '',
|
|
@@ -39621,7 +39635,7 @@ const CreatableMultiselect = (props) => {
|
|
|
39621
39635
|
// Update values based on type
|
|
39622
39636
|
if (type === DBEntryFieldType$1.NumberArray) {
|
|
39623
39637
|
const numberValues = newValues.map((val) => {
|
|
39624
|
-
return Number(val.value);
|
|
39638
|
+
return Number.parseFloat(val.value);
|
|
39625
39639
|
});
|
|
39626
39640
|
onChange(numberValues);
|
|
39627
39641
|
}
|
|
@@ -39643,6 +39657,7 @@ const CreatableMultiselect = (props) => {
|
|
|
39643
39657
|
/**
|
|
39644
39658
|
* Panel for adding a DBEntry to the database
|
|
39645
39659
|
* @author Yuen Ler Chow
|
|
39660
|
+
* @author Gabe Abrams
|
|
39646
39661
|
*/
|
|
39647
39662
|
/*------------------------------------------------------------------------*/
|
|
39648
39663
|
/* -------------------------------- Style ------------------------------- */
|
|
@@ -39666,6 +39681,7 @@ var ActionType$1;
|
|
|
39666
39681
|
* @author Yuen Ler Chow
|
|
39667
39682
|
* @param state current state
|
|
39668
39683
|
* @param action action to execute
|
|
39684
|
+
* @returns updated state
|
|
39669
39685
|
*/
|
|
39670
39686
|
const reducer$1 = (state, action) => {
|
|
39671
39687
|
switch (action.type) {
|
|
@@ -39716,7 +39732,10 @@ const AddOrEditDBEntry = (props) => {
|
|
|
39716
39732
|
entry[field.objectKey] = field.defaultValue;
|
|
39717
39733
|
}
|
|
39718
39734
|
});
|
|
39719
|
-
|
|
39735
|
+
// Modify entry if needed
|
|
39736
|
+
const modifiedEntry = (modifyEntry
|
|
39737
|
+
? yield modifyEntry(entry)
|
|
39738
|
+
: entry);
|
|
39720
39739
|
// add id key to entry so that when we delete the item, the key will always be "id"
|
|
39721
39740
|
modifiedEntry.id = modifiedEntry[idPropName];
|
|
39722
39741
|
// Send to server
|
|
@@ -39753,14 +39772,18 @@ const AddOrEditDBEntry = (props) => {
|
|
|
39753
39772
|
for (let i = 0; i < fields.length; i += 1) {
|
|
39754
39773
|
const field = fields[i];
|
|
39755
39774
|
const value = entry[field.objectKey];
|
|
39756
|
-
// Check if required field is empty. Field is automatically required if
|
|
39775
|
+
// Check if required field is empty. Field is automatically required if
|
|
39776
|
+
// it is the idPropName
|
|
39757
39777
|
if ((field.required || (field.objectKey === idPropName)) && !value) {
|
|
39758
39778
|
validationError = `Please fill in the ${field.label} field`;
|
|
39759
39779
|
return validationError;
|
|
39760
39780
|
}
|
|
39761
39781
|
// Check if unique field is unique
|
|
39762
39782
|
if (field.objectKey === idPropName && !dbEntryToEdit) {
|
|
39763
|
-
|
|
39783
|
+
const notUnique = entries.find((e) => {
|
|
39784
|
+
return e[idPropName] === value;
|
|
39785
|
+
});
|
|
39786
|
+
if (notUnique) {
|
|
39764
39787
|
validationError = `An item with the ${field.label} ${value} already exists. ${field.label} must be unique.`;
|
|
39765
39788
|
return validationError;
|
|
39766
39789
|
}
|
|
@@ -39872,6 +39895,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
39872
39895
|
* @author Yuen Ler Chow
|
|
39873
39896
|
* @param field the entry field to render
|
|
39874
39897
|
* @param disabled true if the field should be disabled
|
|
39898
|
+
* @returns rendered entry field
|
|
39875
39899
|
*/
|
|
39876
39900
|
const renderEntryField = (field, disabled) => {
|
|
39877
39901
|
if (field.type === DBEntryFieldType$1.String) {
|
|
@@ -39993,9 +40017,11 @@ const AddOrEditDBEntry = (props) => {
|
|
|
39993
40017
|
}),
|
|
39994
40018
|
React__default["default"].createElement("div", { className: "text-center mt-2" },
|
|
39995
40019
|
React__default["default"].createElement("button", { type: "button", id: "AddOrEditDBEntry-save-changes-button", className: "btn btn-primary btn-lg me-1", "aria-label": "Save changes", onClick: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40020
|
+
// Show validation errors
|
|
39996
40021
|
if (validationError && validationError.length > 0) {
|
|
39997
40022
|
return alert$1('Please fix the following error', validationError);
|
|
39998
40023
|
}
|
|
40024
|
+
// Run the included validator if it exists
|
|
39999
40025
|
if (validateEntry) {
|
|
40000
40026
|
try {
|
|
40001
40027
|
yield validateEntry(entry);
|
|
@@ -40008,7 +40034,7 @@ const AddOrEditDBEntry = (props) => {
|
|
|
40008
40034
|
}) },
|
|
40009
40035
|
React__default["default"].createElement(reactFontawesome.FontAwesomeIcon, { icon: freeSolidSvgIcons.faSave, className: "me-1" }),
|
|
40010
40036
|
"Save"),
|
|
40011
|
-
React__default["default"].createElement("button", { type: "button", id: "AddOrEditDBEntry-cancel-button", className: "btn btn-secondary btn-lg
|
|
40037
|
+
React__default["default"].createElement("button", { type: "button", id: "AddOrEditDBEntry-cancel-button", className: "btn btn-secondary btn-lg", "aria-label": "save changes", onClick: cancel }, "Cancel"))));
|
|
40012
40038
|
}
|
|
40013
40039
|
/*----------------------------------------*/
|
|
40014
40040
|
/* --------------- Main UI -------------- */
|
|
@@ -40035,6 +40061,7 @@ const generateEndpointPath = (collectionName, adminsOnly) => {
|
|
|
40035
40061
|
/**
|
|
40036
40062
|
* DB Entry Manager Panel
|
|
40037
40063
|
* @author Yuen Ler Chow
|
|
40064
|
+
* @author Gabe Abrams
|
|
40038
40065
|
*/
|
|
40039
40066
|
/* ------------- Actions ------------ */
|
|
40040
40067
|
// Types of actions
|
|
@@ -40058,6 +40085,7 @@ var ActionType;
|
|
|
40058
40085
|
* @author Yuen Ler Chow
|
|
40059
40086
|
* @param state current state
|
|
40060
40087
|
* @param action action to execute
|
|
40088
|
+
* @returns updated state
|
|
40061
40089
|
*/
|
|
40062
40090
|
const reducer = (state, action) => {
|
|
40063
40091
|
switch (action.type) {
|
|
@@ -41687,8 +41715,14 @@ const initLogCollection = (Collection) => {
|
|
|
41687
41715
|
});
|
|
41688
41716
|
};
|
|
41689
41717
|
|
|
41718
|
+
/*------------------------------------------------------------------------*/
|
|
41719
|
+
/* -------------------------------- Cache ------------------------------- */
|
|
41720
|
+
/*------------------------------------------------------------------------*/
|
|
41690
41721
|
// Cache user's ability
|
|
41691
41722
|
let canReview = undefined;
|
|
41723
|
+
/*------------------------------------------------------------------------*/
|
|
41724
|
+
/* -------------------------------- Main -------------------------------- */
|
|
41725
|
+
/*------------------------------------------------------------------------*/
|
|
41692
41726
|
/**
|
|
41693
41727
|
* Check if the current user can review logs
|
|
41694
41728
|
* @author Gabe Abrams
|
|
@@ -41735,29 +41769,42 @@ const extractProp = (arr, prop) => {
|
|
|
41735
41769
|
* @author Gabe Abrams
|
|
41736
41770
|
* @param a the first array
|
|
41737
41771
|
* @param b the second array
|
|
41738
|
-
* @param prop the property to compare with
|
|
41772
|
+
* @param prop the property to compare with, or an array of props to compare
|
|
41773
|
+
* with (if array, all values associated with those props must match)
|
|
41739
41774
|
* @returns true if the arrays contain the same objects as determined by
|
|
41740
41775
|
* the values associated with each object's prop
|
|
41741
41776
|
*/
|
|
41742
41777
|
const compareArraysByProp = (a, b, prop) => {
|
|
41743
|
-
//
|
|
41744
|
-
|
|
41745
|
-
const bVals = new Set(extractProp(b, prop));
|
|
41746
|
-
// Compare sizes first
|
|
41747
|
-
if (aVals.size !== bVals.size) {
|
|
41778
|
+
// Immediately return if size of arrays is different
|
|
41779
|
+
if (a.length !== b.length) {
|
|
41748
41780
|
return false;
|
|
41749
41781
|
}
|
|
41750
|
-
//
|
|
41751
|
-
|
|
41752
|
-
//
|
|
41753
|
-
const
|
|
41754
|
-
|
|
41755
|
-
|
|
41756
|
-
|
|
41757
|
-
|
|
41758
|
-
|
|
41759
|
-
|
|
41760
|
-
|
|
41782
|
+
// Get all props
|
|
41783
|
+
const props = (Array.isArray(prop) ? prop : [prop]);
|
|
41784
|
+
// Clone second array so we can work on it
|
|
41785
|
+
const bCloned = [...b];
|
|
41786
|
+
// Remove elements from b as we find them in a
|
|
41787
|
+
for (let i = 0; i < a.length; i++) {
|
|
41788
|
+
// Find matching element in b
|
|
41789
|
+
const matchingIndex = bCloned.findIndex((bItem) => {
|
|
41790
|
+
// Compare based on all props
|
|
41791
|
+
return props.every((propToCompareBy) => {
|
|
41792
|
+
const aVal = extractProp(a[i], propToCompareBy);
|
|
41793
|
+
const bVal = extractProp(bItem, propToCompareBy);
|
|
41794
|
+
return aVal === bVal;
|
|
41795
|
+
});
|
|
41796
|
+
});
|
|
41797
|
+
// Check if no match
|
|
41798
|
+
const noMatch = (matchingIndex < 0);
|
|
41799
|
+
// If no match, there's no corresponding element in b
|
|
41800
|
+
if (noMatch) {
|
|
41801
|
+
return false;
|
|
41802
|
+
}
|
|
41803
|
+
// Remove the matching element
|
|
41804
|
+
bCloned.splice(matchingIndex, 1);
|
|
41805
|
+
}
|
|
41806
|
+
// If we made it here, all elements in a have a corresponding element in b
|
|
41807
|
+
return true;
|
|
41761
41808
|
};
|
|
41762
41809
|
|
|
41763
41810
|
/**
|
|
@@ -41815,9 +41862,11 @@ const getLocalTimeInfo = (dateOrTimestamp) => {
|
|
|
41815
41862
|
* @param opts.app express app to add routes too
|
|
41816
41863
|
* @param opts.collectionName the name of the collection
|
|
41817
41864
|
* @param opts.adminsOnly true if the endpoint is for admins only
|
|
41865
|
+
* @param opts.collection dce-mango db collection
|
|
41818
41866
|
*/
|
|
41819
41867
|
const addDBEditorEndpoints = (opts) => {
|
|
41820
41868
|
const { app, collectionName, adminsOnly, collection, } = opts;
|
|
41869
|
+
// Generate the endpoint path
|
|
41821
41870
|
const endpointPath = generateEndpointPath(collectionName, adminsOnly);
|
|
41822
41871
|
/**
|
|
41823
41872
|
* List all items in the collection
|
|
@@ -41866,6 +41915,246 @@ const addDBEditorEndpoints = (opts) => {
|
|
|
41866
41915
|
}));
|
|
41867
41916
|
};
|
|
41868
41917
|
|
|
41918
|
+
/**
|
|
41919
|
+
* Given an array of strings, create a single comma-separated string that includes
|
|
41920
|
+
* 'and' as well as an oxford comma.
|
|
41921
|
+
* Ex: ['apples'] => 'apples'
|
|
41922
|
+
* Ex: ['apples', 'bananas'] => 'apples and bananas'
|
|
41923
|
+
* Ex: ['apples', 'bananas', 'grapes'] => 'apples, bananas, and grapes'
|
|
41924
|
+
* @author Austen Money
|
|
41925
|
+
* @param list an array of elements to be made into a single comma-separated string.
|
|
41926
|
+
* @returns a comma-separated string.
|
|
41927
|
+
*/
|
|
41928
|
+
const genCommaList = (list) => {
|
|
41929
|
+
const { length } = list;
|
|
41930
|
+
return (length < 2
|
|
41931
|
+
? list.join('')
|
|
41932
|
+
: `${list.slice(0, length - 1).join(', ')}${length < 3 ? ' and ' : ', and '}${list[length - 1]}`);
|
|
41933
|
+
};
|
|
41934
|
+
|
|
41935
|
+
/*------------------------------------------------------------------------*/
|
|
41936
|
+
/* ------------------------------ Constants ----------------------------- */
|
|
41937
|
+
/*------------------------------------------------------------------------*/
|
|
41938
|
+
const INVALID_REGEX_ERROR = 'input does not follow the requested format';
|
|
41939
|
+
const INVALID_EMAIL_ERROR = 'Please provide a valid email address.';
|
|
41940
|
+
const INVALID_PHONE_ERROR = 'Please provide a valid phone number.';
|
|
41941
|
+
const INVALID_STRING_ERRORS = {
|
|
41942
|
+
MIN_LEN: (minLen) => {
|
|
41943
|
+
return `input must not be under ${minLen} character(s)`;
|
|
41944
|
+
},
|
|
41945
|
+
MAX_LEN: (maxLen) => {
|
|
41946
|
+
return `input must not be over ${maxLen} character(s)`;
|
|
41947
|
+
},
|
|
41948
|
+
LETTERS_ONLY: 'input must only contain letters',
|
|
41949
|
+
NUMBERS_ONLY: 'input must only contain numbers',
|
|
41950
|
+
MESSAGE_INTRO: 'The following error(s) occurred: ',
|
|
41951
|
+
};
|
|
41952
|
+
|
|
41953
|
+
// Import constants
|
|
41954
|
+
/**
|
|
41955
|
+
* Determines whether a given input string is considered valid based on
|
|
41956
|
+
* the provided regex.
|
|
41957
|
+
* @author Austen Money
|
|
41958
|
+
* @param opts object containing all args
|
|
41959
|
+
* @param opts.input user-provided input to validate
|
|
41960
|
+
* @param opts.regex regular expression to check against input
|
|
41961
|
+
* @param [opts.regexDescription] description of what regexString is checking
|
|
41962
|
+
* for, used to customize error message
|
|
41963
|
+
* @returns the unchanged input if valid, or a customized error message if
|
|
41964
|
+
* invalid
|
|
41965
|
+
*/
|
|
41966
|
+
const validateRegex = (opts) => {
|
|
41967
|
+
// customize error message in case of invalid input
|
|
41968
|
+
const errorMessage = `${INVALID_REGEX_ERROR}${opts.regexDescription
|
|
41969
|
+
? ': '
|
|
41970
|
+
: ''}${opts.regexDescription}`;
|
|
41971
|
+
// return error message if test is invalid, or input string if valid
|
|
41972
|
+
return (opts.regex.test(opts.input)
|
|
41973
|
+
? {
|
|
41974
|
+
isValid: true,
|
|
41975
|
+
cleanedValue: opts.input,
|
|
41976
|
+
}
|
|
41977
|
+
: {
|
|
41978
|
+
isValid: false,
|
|
41979
|
+
errorMessage,
|
|
41980
|
+
});
|
|
41981
|
+
};
|
|
41982
|
+
|
|
41983
|
+
// Import helpers
|
|
41984
|
+
/**
|
|
41985
|
+
* Determines whether a given email address is valid.
|
|
41986
|
+
* @author Austen Money
|
|
41987
|
+
* @param email email address to validate
|
|
41988
|
+
* @returns whether email fulfills proper formatting requirements, includes a
|
|
41989
|
+
* cleaned version of the address without leading or trailing
|
|
41990
|
+
* whitespace if valid or an error message if invalid.
|
|
41991
|
+
*/
|
|
41992
|
+
const validateEmail = (email) => {
|
|
41993
|
+
// validation regex, sourced from HTML living standard: http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#e-mail-state-(type=email)
|
|
41994
|
+
// eslint-disable-next-line max-len
|
|
41995
|
+
const emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
41996
|
+
// remove leading and trailing whitespace
|
|
41997
|
+
const cleanedValue = email.replace(/^\s+|\s+$/g, '');
|
|
41998
|
+
// validate email with regex, and return error if not valid
|
|
41999
|
+
return (validateRegex({
|
|
42000
|
+
input: cleanedValue,
|
|
42001
|
+
regex: emailRegex,
|
|
42002
|
+
}).isValid
|
|
42003
|
+
? {
|
|
42004
|
+
isValid: true,
|
|
42005
|
+
cleanedValue,
|
|
42006
|
+
}
|
|
42007
|
+
: {
|
|
42008
|
+
isValid: false,
|
|
42009
|
+
errorMessage: INVALID_EMAIL_ERROR,
|
|
42010
|
+
});
|
|
42011
|
+
};
|
|
42012
|
+
|
|
42013
|
+
// Import helpers
|
|
42014
|
+
/**
|
|
42015
|
+
* Determines whether a given phone number is valid.
|
|
42016
|
+
* @author Austen Money
|
|
42017
|
+
* @param phoneNumber phone number to validate
|
|
42018
|
+
* @returns whether phone number is considered valid - if valid, also returns
|
|
42019
|
+
* a cleaned version of the number without any formatting. If invalid,
|
|
42020
|
+
* returns an error message.
|
|
42021
|
+
*/
|
|
42022
|
+
const validatePhoneNumber = (phoneNumber) => {
|
|
42023
|
+
// regex to validate phone number
|
|
42024
|
+
const validationRegex = /^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$/;
|
|
42025
|
+
// validate phone number with regex
|
|
42026
|
+
const validationResponse = validateRegex({
|
|
42027
|
+
input: phoneNumber,
|
|
42028
|
+
regex: validationRegex,
|
|
42029
|
+
});
|
|
42030
|
+
// remove all non-digits from number
|
|
42031
|
+
const cleanedValue = phoneNumber.replace(/\D/g, '');
|
|
42032
|
+
// return cleaned value if valid, or error message if invalid
|
|
42033
|
+
return (validationResponse.isValid
|
|
42034
|
+
? {
|
|
42035
|
+
isValid: true,
|
|
42036
|
+
cleanedValue,
|
|
42037
|
+
}
|
|
42038
|
+
: {
|
|
42039
|
+
isValid: false,
|
|
42040
|
+
errorMessage: INVALID_PHONE_ERROR,
|
|
42041
|
+
});
|
|
42042
|
+
};
|
|
42043
|
+
|
|
42044
|
+
// Import helpers
|
|
42045
|
+
/*------------------------------------------------------------------------*/
|
|
42046
|
+
/* ------------------------------ Constants ----------------------------- */
|
|
42047
|
+
/*------------------------------------------------------------------------*/
|
|
42048
|
+
// define minimum and maximum range for lowercase ASCII chars
|
|
42049
|
+
const LOWERCASE_MIN = 65;
|
|
42050
|
+
const LOWERCASE_MAX = 90;
|
|
42051
|
+
// define minimum and maximum range for uppercase ASCII chars
|
|
42052
|
+
const UPPERCASE_MIN = 97;
|
|
42053
|
+
const UPPERCASE_MAX = 122;
|
|
42054
|
+
// define minimum and maximum range for ASCII digits
|
|
42055
|
+
const DIGIT_MIN = 48;
|
|
42056
|
+
const DIGIT_MAX = 57;
|
|
42057
|
+
/*------------------------------------------------------------------------*/
|
|
42058
|
+
/* ---------------------------- Main Function --------------------------- */
|
|
42059
|
+
/*------------------------------------------------------------------------*/
|
|
42060
|
+
/**
|
|
42061
|
+
* Determines whether a given input string is considered valid based on
|
|
42062
|
+
* the provided requirements.
|
|
42063
|
+
* @author Austen Money
|
|
42064
|
+
* @param input input string
|
|
42065
|
+
* @param opts options for validation
|
|
42066
|
+
* @returns whether input is considered valid according to reqs - if
|
|
42067
|
+
* valid, returns a cleaned version of input; if invalid, returns
|
|
42068
|
+
* a string containing error messages describing which requirements
|
|
42069
|
+
* were not met.
|
|
42070
|
+
*/
|
|
42071
|
+
const validateString = (input, opts) => {
|
|
42072
|
+
// stores all invalid input errors
|
|
42073
|
+
const errorMessages = [];
|
|
42074
|
+
// contains version of input that will be returned
|
|
42075
|
+
let cleanedValue = input;
|
|
42076
|
+
// remove whitespace if required
|
|
42077
|
+
if (opts.ignoreWhitespace) {
|
|
42078
|
+
cleanedValue = input.replace(/\s+/g, '');
|
|
42079
|
+
}
|
|
42080
|
+
// apply max char requirement
|
|
42081
|
+
if (opts.minLen) {
|
|
42082
|
+
if (cleanedValue.length < opts.minLen) {
|
|
42083
|
+
errorMessages.push(INVALID_STRING_ERRORS.MIN_LEN(opts.minLen));
|
|
42084
|
+
}
|
|
42085
|
+
}
|
|
42086
|
+
// apply max char requirement
|
|
42087
|
+
if (opts.maxLen) {
|
|
42088
|
+
if (cleanedValue.length > opts.maxLen) {
|
|
42089
|
+
errorMessages.push(INVALID_STRING_ERRORS.MAX_LEN(opts.maxLen));
|
|
42090
|
+
}
|
|
42091
|
+
}
|
|
42092
|
+
// apply alphabetical requirement
|
|
42093
|
+
if (opts.lettersOnly) {
|
|
42094
|
+
// remove diacritics
|
|
42095
|
+
cleanedValue = cleanedValue.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
|
42096
|
+
const containsNonLetters = (cleanedValue
|
|
42097
|
+
// split into characters
|
|
42098
|
+
.split('')
|
|
42099
|
+
// convert into character codes
|
|
42100
|
+
.map((curr) => {
|
|
42101
|
+
return curr.charCodeAt(0);
|
|
42102
|
+
})
|
|
42103
|
+
// check for non-letters
|
|
42104
|
+
.some((currCode) => {
|
|
42105
|
+
return (!(currCode >= LOWERCASE_MIN && currCode <= LOWERCASE_MAX)
|
|
42106
|
+
&& !(currCode >= UPPERCASE_MIN && currCode <= UPPERCASE_MAX));
|
|
42107
|
+
}));
|
|
42108
|
+
if (containsNonLetters) {
|
|
42109
|
+
errorMessages.push(INVALID_STRING_ERRORS.LETTERS_ONLY);
|
|
42110
|
+
}
|
|
42111
|
+
}
|
|
42112
|
+
// apply numerical requirement
|
|
42113
|
+
if (opts.numbersOnly) {
|
|
42114
|
+
const containsNonNumbers = (cleanedValue
|
|
42115
|
+
// split into characters
|
|
42116
|
+
.split('')
|
|
42117
|
+
// convert into character codes
|
|
42118
|
+
.map((curr) => {
|
|
42119
|
+
return curr.charCodeAt(0);
|
|
42120
|
+
})
|
|
42121
|
+
// check for non-numbers
|
|
42122
|
+
.some((currCode) => {
|
|
42123
|
+
return (!(currCode >= DIGIT_MIN && currCode <= DIGIT_MAX));
|
|
42124
|
+
}));
|
|
42125
|
+
if (containsNonNumbers) {
|
|
42126
|
+
errorMessages.push(INVALID_STRING_ERRORS.NUMBERS_ONLY);
|
|
42127
|
+
}
|
|
42128
|
+
}
|
|
42129
|
+
// apply regex requirement
|
|
42130
|
+
if (opts.regexTest) {
|
|
42131
|
+
const regex = opts.regexTest;
|
|
42132
|
+
// validate and create customized error message if description is provided
|
|
42133
|
+
const result = validateRegex({
|
|
42134
|
+
input: cleanedValue,
|
|
42135
|
+
regex,
|
|
42136
|
+
regexDescription: opts.regexDescription,
|
|
42137
|
+
});
|
|
42138
|
+
// if string did not pass regex validation, add error message
|
|
42139
|
+
if (result.isValid === false) {
|
|
42140
|
+
errorMessages.push(result.errorMessage);
|
|
42141
|
+
}
|
|
42142
|
+
}
|
|
42143
|
+
// combine all error messages into one string to return
|
|
42144
|
+
const errorMessage = `${INVALID_STRING_ERRORS.MESSAGE_INTRO}${genCommaList(errorMessages)}.`;
|
|
42145
|
+
return (
|
|
42146
|
+
// if no error messages, string is valid; if not, it is invalid
|
|
42147
|
+
errorMessages.length === 0
|
|
42148
|
+
? {
|
|
42149
|
+
isValid: true,
|
|
42150
|
+
cleanedValue,
|
|
42151
|
+
}
|
|
42152
|
+
: {
|
|
42153
|
+
isValid: false,
|
|
42154
|
+
errorMessage,
|
|
42155
|
+
});
|
|
42156
|
+
};
|
|
42157
|
+
|
|
41869
42158
|
/**
|
|
41870
42159
|
* Days of the week
|
|
41871
42160
|
* @author Gabe Abrams
|
|
@@ -41930,6 +42219,7 @@ exports.extractProp = extractProp;
|
|
|
41930
42219
|
exports.floorToNumDecimals = floorToNumDecimals;
|
|
41931
42220
|
exports.forceNumIntoBounds = forceNumIntoBounds;
|
|
41932
42221
|
exports.genCSV = genCSV;
|
|
42222
|
+
exports.genCommaList = genCommaList;
|
|
41933
42223
|
exports.genRouteHandler = genRouteHandler;
|
|
41934
42224
|
exports.getHumanReadableDate = getHumanReadableDate;
|
|
41935
42225
|
exports.getLocalTimeInfo = getLocalTimeInfo;
|
|
@@ -41954,6 +42244,9 @@ exports.startMinWait = startMinWait;
|
|
|
41954
42244
|
exports.stringsToHumanReadableList = stringsToHumanReadableList;
|
|
41955
42245
|
exports.stubServerEndpoint = stubServerEndpoint;
|
|
41956
42246
|
exports.sum = sum;
|
|
42247
|
+
exports.validateEmail = validateEmail;
|
|
42248
|
+
exports.validatePhoneNumber = validatePhoneNumber;
|
|
42249
|
+
exports.validateString = validateString;
|
|
41957
42250
|
exports.visitServerEndpoint = visitServerEndpoint;
|
|
41958
42251
|
exports.waitMs = waitMs;
|
|
41959
42252
|
//# sourceMappingURL=index.js.map
|