dce-reactkit 4.0.0 → 4.0.2-beta-simple-date-chooser.1
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/dist/cjs/index.js +355 -91
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/SimpleDateChooser.d.ts +3 -1
- package/dist/cjs/types/components/SimpleTimeChooser.d.ts +20 -0
- package/dist/cjs/types/index.d.ts +2 -1
- package/dist/cjs/types/types/ReactKitErrorCode.d.ts +3 -1
- package/dist/esm/index.js +355 -92
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/SimpleDateChooser.d.ts +3 -1
- package/dist/esm/types/components/SimpleTimeChooser.d.ts +20 -0
- package/dist/esm/types/index.d.ts +2 -1
- package/dist/esm/types/types/ReactKitErrorCode.d.ts +3 -1
- package/dist/index.d.ts +41 -17
- package/package.json +1 -1
- package/src/components/LogReviewer.tsx +2 -2
- package/src/components/SimpleDateChooser.tsx +397 -119
- package/src/components/SimpleTimeChooser.tsx +196 -0
- package/src/index.ts +2 -0
- package/src/types/LogSource.ts +1 -1
- package/src/types/ReactKitErrorCode.tsx +3 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A very simple, lightweight date chooser
|
|
3
3
|
* @author Gabe Abrams
|
|
4
|
+
* @author Gardenia Liu
|
|
4
5
|
*/
|
|
5
6
|
import React from 'react';
|
|
6
7
|
type Props = {
|
|
@@ -17,7 +18,8 @@ type Props = {
|
|
|
17
18
|
*/
|
|
18
19
|
onChange: (month: number, day: number, year: number) => void;
|
|
19
20
|
numMonthsToShow?: number;
|
|
20
|
-
|
|
21
|
+
dontAllowPast?: boolean;
|
|
22
|
+
dontAllowFuture?: boolean;
|
|
21
23
|
};
|
|
22
24
|
declare const SimpleDateChooser: React.FC<Props>;
|
|
23
25
|
export default SimpleDateChooser;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A very simple, lightweight time chooser
|
|
3
|
+
* @author Gardenia Liu
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
type Props = {
|
|
7
|
+
ariaLabel: string;
|
|
8
|
+
name: string;
|
|
9
|
+
hour: number;
|
|
10
|
+
minute: number;
|
|
11
|
+
/**
|
|
12
|
+
* Handler for when time changes
|
|
13
|
+
* @param hour new 24hr hour number
|
|
14
|
+
* @param minute new minute number
|
|
15
|
+
*/
|
|
16
|
+
onChange: (hour: number, minute: number) => void;
|
|
17
|
+
intervalMin?: number;
|
|
18
|
+
};
|
|
19
|
+
declare const SimpleTimeChooser: React.FC<Props>;
|
|
20
|
+
export default SimpleTimeChooser;
|
|
@@ -7,6 +7,7 @@ import RadioButton from './components/RadioButton';
|
|
|
7
7
|
import CheckboxButton from './components/CheckboxButton';
|
|
8
8
|
import ButtonInputGroup from './components/ButtonInputGroup';
|
|
9
9
|
import SimpleDateChooser from './components/SimpleDateChooser';
|
|
10
|
+
import SimpleTimeChooser from './components/SimpleTimeChooser';
|
|
10
11
|
import Drawer from './components/Drawer';
|
|
11
12
|
import PopSuccessMark from './components/PopSuccessMark';
|
|
12
13
|
import PopFailureMark from './components/PopFailureMark';
|
|
@@ -100,4 +101,4 @@ import PickableItem from './components/ItemPicker/types/PickableItem';
|
|
|
100
101
|
import DBEntry from './components/DBEntryManagerPanel/types/DBEntry';
|
|
101
102
|
import DBEntryField from './components/DBEntryManagerPanel/types/DBEntryField';
|
|
102
103
|
import DBEntryFieldType from './components/DBEntryManagerPanel/types/DBEntryFieldType';
|
|
103
|
-
export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, MultiSwitch, Dropdown, alert, prompt, confirm, showFatalError, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_ROUTE_PATH, LOG_REVIEW_STATUS_ROUTE, DynamicWord, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, stubServerEndpoint, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, canReviewLogs, isMobileOrTablet, extractProp, compareArraysByProp, genCommaList, validateEmail, validatePhoneNumber, validateString, getLocalTimeInfo, idify, makeLinksClickable, prefixWithAOrAn, everyAsync, filterAsync, forEachAsync, mapAsync, someAsync, capitalize, shuffleArray, getWordCount, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, leaveToURL, combineClassNames, useForceRender, setClientEventMetadataPopulator, ParamType, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, LogFunction, LogTypeSpecificInfo, LogMainInfo, LogSourceSpecificInfo, LogLevel, IntelliTableColumn, DropdownItemType, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, };
|
|
104
|
+
export { AppWrapper, LoadingSpinner, ErrorBox, Modal, TabBox, RadioButton, CheckboxButton, ButtonInputGroup, SimpleDateChooser, SimpleTimeChooser, Drawer, PopSuccessMark, PopFailureMark, PopPendingMark, CopiableBox, ItemPicker, LogReviewer, IntelliTable, CSVDownloadButton, DBEntryManagerPanel, Tooltip, ToggleSwitch, AutoscrollToBottomContainer, MultiSwitch, Dropdown, alert, prompt, confirm, showFatalError, ErrorWithCode, MINUTE_IN_MS, HOUR_IN_MS, DAY_IN_MS, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_ROUTE_PATH, LOG_REVIEW_STATUS_ROUTE, DynamicWord, abbreviate, avg, ceilToNumDecimals, floorToNumDecimals, forceNumIntoBounds, padDecimalZeros, padZerosLeft, roundToNumDecimals, sum, waitMs, getOrdinal, getTimeInfoInET, stubServerEndpoint, startMinWait, getHumanReadableDate, getPartOfDay, stringsToHumanReadableList, onlyKeepLetters, parallelLimit, getMonthName, genCSV, canReviewLogs, isMobileOrTablet, extractProp, compareArraysByProp, genCommaList, validateEmail, validatePhoneNumber, validateString, getLocalTimeInfo, idify, makeLinksClickable, prefixWithAOrAn, everyAsync, filterAsync, forEachAsync, mapAsync, someAsync, capitalize, shuffleArray, getWordCount, initClient, visitServerEndpoint, logClientEvent, addFatalErrorHandler, leaveToURL, combineClassNames, useForceRender, setClientEventMetadataPopulator, ParamType, ModalButtonType, ModalSize, ModalType, ReactKitErrorCode, Variant, DayOfWeek, Log, LogType, LogSource, LogAction, LogBuiltInMetadata, LogMetadataType, LogFunction, LogTypeSpecificInfo, LogMainInfo, LogSourceSpecificInfo, LogLevel, IntelliTableColumn, DropdownItemType, PickableItem, DBEntry, DBEntryField, DBEntryFieldType, };
|
|
@@ -6,6 +6,8 @@ declare enum ReactKitErrorCode {
|
|
|
6
6
|
NoResponse = "DRK1",
|
|
7
7
|
NoCode = "DRK2",
|
|
8
8
|
SessionExpired = "DRK3",
|
|
9
|
-
NoCACCLSendRequestFunction = "DRK7"
|
|
9
|
+
NoCACCLSendRequestFunction = "DRK7",
|
|
10
|
+
SimpleDateChooserInvalidDateRange = "DRK35",
|
|
11
|
+
SimpleDateChooserInvalidNumMonths = "DRK36"
|
|
10
12
|
}
|
|
11
13
|
export default ReactKitErrorCode;
|
package/dist/esm/index.js
CHANGED
|
@@ -29,7 +29,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
// Highest error code =
|
|
32
|
+
// Highest error code = DRK36
|
|
33
33
|
/**
|
|
34
34
|
* List of error codes built into the react kit
|
|
35
35
|
* @author Gabe Abrams
|
|
@@ -40,6 +40,8 @@ var ReactKitErrorCode;
|
|
|
40
40
|
ReactKitErrorCode["NoCode"] = "DRK2";
|
|
41
41
|
ReactKitErrorCode["SessionExpired"] = "DRK3";
|
|
42
42
|
ReactKitErrorCode["NoCACCLSendRequestFunction"] = "DRK7";
|
|
43
|
+
ReactKitErrorCode["SimpleDateChooserInvalidDateRange"] = "DRK35";
|
|
44
|
+
ReactKitErrorCode["SimpleDateChooserInvalidNumMonths"] = "DRK36";
|
|
43
45
|
})(ReactKitErrorCode || (ReactKitErrorCode = {}));
|
|
44
46
|
var ReactKitErrorCode$1 = ReactKitErrorCode;
|
|
45
47
|
|
|
@@ -2521,6 +2523,19 @@ const ButtonInputGroup = (props) => {
|
|
|
2521
2523
|
: children))));
|
|
2522
2524
|
};
|
|
2523
2525
|
|
|
2526
|
+
// Constants
|
|
2527
|
+
const ORDINALS = ['th', 'st', 'nd', 'rd'];
|
|
2528
|
+
/**
|
|
2529
|
+
* Get a number's ordinal
|
|
2530
|
+
* @author Gabe Abrams
|
|
2531
|
+
* @param num the number being analyzed
|
|
2532
|
+
* @returns ordinal
|
|
2533
|
+
*/
|
|
2534
|
+
const getOrdinal = (num) => {
|
|
2535
|
+
var _a, _b;
|
|
2536
|
+
return ((_b = (_a = ORDINALS[(num - 20) % 10]) !== null && _a !== void 0 ? _a : ORDINALS[num]) !== null && _b !== void 0 ? _b : ORDINALS[0]);
|
|
2537
|
+
};
|
|
2538
|
+
|
|
2524
2539
|
const monthNames = [
|
|
2525
2540
|
{ short: 'Jan', full: 'January' },
|
|
2526
2541
|
{ short: 'Feb', full: 'February' },
|
|
@@ -2549,19 +2564,6 @@ const getMonthName = (month) => {
|
|
|
2549
2564
|
return ((_a = monthNames[month - 1]) !== null && _a !== void 0 ? _a : monthNames[0]);
|
|
2550
2565
|
};
|
|
2551
2566
|
|
|
2552
|
-
// Constants
|
|
2553
|
-
const ORDINALS = ['th', 'st', 'nd', 'rd'];
|
|
2554
|
-
/**
|
|
2555
|
-
* Get a number's ordinal
|
|
2556
|
-
* @author Gabe Abrams
|
|
2557
|
-
* @param num the number being analyzed
|
|
2558
|
-
* @returns ordinal
|
|
2559
|
-
*/
|
|
2560
|
-
const getOrdinal = (num) => {
|
|
2561
|
-
var _a, _b;
|
|
2562
|
-
return ((_b = (_a = ORDINALS[(num - 20) % 10]) !== null && _a !== void 0 ? _a : ORDINALS[num]) !== null && _b !== void 0 ? _b : ORDINALS[0]);
|
|
2563
|
-
};
|
|
2564
|
-
|
|
2565
2567
|
/**
|
|
2566
2568
|
* Get current time info in US Boston Eastern Time, independent of machine
|
|
2567
2569
|
* timezone
|
|
@@ -2625,35 +2627,86 @@ const getTimeInfoInET = (dateOrTimestamp) => {
|
|
|
2625
2627
|
/**
|
|
2626
2628
|
* A very simple, lightweight date chooser
|
|
2627
2629
|
* @author Gabe Abrams
|
|
2630
|
+
* @author Gardenia Liu
|
|
2628
2631
|
*/
|
|
2629
2632
|
/*------------------------------------------------------------------------*/
|
|
2630
|
-
/*
|
|
2633
|
+
/* -------------------------------- State ------------------------------- */
|
|
2631
2634
|
/*------------------------------------------------------------------------*/
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2635
|
+
/* -------------- Views ------------- */
|
|
2636
|
+
var View;
|
|
2637
|
+
(function (View) {
|
|
2638
|
+
// Date chooser
|
|
2639
|
+
View["DateChooser"] = "DateChooser";
|
|
2640
|
+
// Invalid date
|
|
2641
|
+
View["InvalidDate"] = "InvalidDate";
|
|
2642
|
+
})(View || (View = {}));
|
|
2643
|
+
/* ------------- Actions ------------ */
|
|
2644
|
+
// Types of actions
|
|
2645
|
+
var ActionType$a;
|
|
2646
|
+
(function (ActionType) {
|
|
2647
|
+
// Fix invalid date so it is now in range
|
|
2648
|
+
ActionType["FixInvalidDate"] = "FixInvalidDate";
|
|
2649
|
+
})(ActionType$a || (ActionType$a = {}));
|
|
2650
|
+
/**
|
|
2651
|
+
* Reducer that executes actions
|
|
2652
|
+
* @author Gardenia Liu
|
|
2653
|
+
* @param state current state
|
|
2654
|
+
* @param action action to execute
|
|
2655
|
+
* @returns updated state
|
|
2656
|
+
*/
|
|
2657
|
+
const reducer$b = (state, action) => {
|
|
2658
|
+
switch (action.type) {
|
|
2659
|
+
case ActionType$a.FixInvalidDate: {
|
|
2660
|
+
return Object.assign(Object.assign({}, state), { view: View.DateChooser });
|
|
2661
|
+
}
|
|
2662
|
+
default: {
|
|
2663
|
+
return state;
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
};
|
|
2667
|
+
/*------------------------------------------------------------------------*/
|
|
2668
|
+
/* --------------------------- Static Helpers --------------------------- */
|
|
2669
|
+
/*------------------------------------------------------------------------*/
|
|
2670
|
+
/**
|
|
2671
|
+
* Get the list of choices in the date chooser given props
|
|
2672
|
+
* @author Gardenia Liu
|
|
2673
|
+
* @author Gabe Abrams
|
|
2674
|
+
* @param opts object containing all arguments
|
|
2675
|
+
* @param opts.numMonthsToShow number of months to show
|
|
2676
|
+
* @param opts.dontAllowPast if true, the user isn't allowed to select dates in the past
|
|
2677
|
+
* @param opts.dontAllowFuture if true, the user isn't allowed to select dates in the future
|
|
2678
|
+
* @returns choices
|
|
2679
|
+
*/
|
|
2680
|
+
const getChoices = (opts) => {
|
|
2681
|
+
// Destructure props
|
|
2682
|
+
const { dontAllowFuture, dontAllowPast, numMonthsToShow = 6, } = opts;
|
|
2644
2683
|
// Determine the set of choices allowed
|
|
2645
2684
|
const today = getTimeInfoInET();
|
|
2646
2685
|
const choices = [];
|
|
2647
2686
|
let startYear = today.year;
|
|
2648
2687
|
let startMonth = today.month;
|
|
2649
|
-
|
|
2688
|
+
// Don't allow past or future dates
|
|
2689
|
+
if (dontAllowPast && dontAllowFuture) {
|
|
2690
|
+
throw new ErrorWithCode('No past or future dates allowed', ReactKitErrorCode$1.SimpleDateChooserInvalidDateRange);
|
|
2691
|
+
}
|
|
2692
|
+
// Require numMonthsToShow to be positive
|
|
2693
|
+
if (numMonthsToShow <= 0) {
|
|
2694
|
+
throw new ErrorWithCode('numMonthsToShow must be positive', ReactKitErrorCode$1.SimpleDateChooserInvalidNumMonths);
|
|
2695
|
+
}
|
|
2696
|
+
// Recalculate startMonth and startYear when allowing past dates
|
|
2697
|
+
if (!dontAllowPast) {
|
|
2650
2698
|
startMonth -= Math.max(0, numMonthsToShow - 1);
|
|
2651
2699
|
while (startMonth <= 0) {
|
|
2652
2700
|
startMonth += 12;
|
|
2653
2701
|
startYear -= 1;
|
|
2654
2702
|
}
|
|
2655
2703
|
}
|
|
2656
|
-
|
|
2704
|
+
// Calculate total number of months to show
|
|
2705
|
+
let totalMonthsToShow = numMonthsToShow;
|
|
2706
|
+
if (!dontAllowPast && !dontAllowFuture) {
|
|
2707
|
+
totalMonthsToShow = totalMonthsToShow * 2 - 1;
|
|
2708
|
+
}
|
|
2709
|
+
for (let i = 0; i < totalMonthsToShow; i++) {
|
|
2657
2710
|
// Get month and year info
|
|
2658
2711
|
const unmoddedMonth = (startMonth + i);
|
|
2659
2712
|
let month = unmoddedMonth;
|
|
@@ -2672,23 +2725,25 @@ const SimpleDateChooser = (props) => {
|
|
|
2672
2725
|
// Figure out which days are allowed
|
|
2673
2726
|
const days = [];
|
|
2674
2727
|
const numDaysInMonth = (new Date(year, month, 0)).getDate();
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
days.push(day);
|
|
2728
|
+
// Current month
|
|
2729
|
+
if (month === today.month && year === today.year) {
|
|
2730
|
+
// Past selection: add all previous days of the month
|
|
2731
|
+
if (!dontAllowPast) {
|
|
2732
|
+
for (let day = 1; day < today.day; day++) {
|
|
2733
|
+
days.push(day);
|
|
2734
|
+
}
|
|
2683
2735
|
}
|
|
2684
|
-
|
|
2685
|
-
else {
|
|
2736
|
+
days.push(today.day); // Add current day
|
|
2686
2737
|
// Future selection: add all remaining days of the month
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2738
|
+
if (!dontAllowFuture) {
|
|
2739
|
+
for (let day = today.day + 1; day <= numDaysInMonth; day++) {
|
|
2740
|
+
days.push(day);
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
else { // Past or future month
|
|
2745
|
+
// Include all days in the month
|
|
2746
|
+
for (let day = 1; day <= numDaysInMonth; day++) {
|
|
2692
2747
|
days.push(day);
|
|
2693
2748
|
}
|
|
2694
2749
|
}
|
|
@@ -2699,36 +2754,262 @@ const SimpleDateChooser = (props) => {
|
|
|
2699
2754
|
days,
|
|
2700
2755
|
});
|
|
2701
2756
|
}
|
|
2702
|
-
//
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2757
|
+
// Return choices
|
|
2758
|
+
return choices;
|
|
2759
|
+
};
|
|
2760
|
+
/**
|
|
2761
|
+
* Checks whether a given date is outside the valid range of allowed choices
|
|
2762
|
+
* @author Gardenia Liu
|
|
2763
|
+
* @param opts object containing all arguments
|
|
2764
|
+
* @param opts.month 1-indexed month
|
|
2765
|
+
* @param opts.day day of the month
|
|
2766
|
+
* @param opts.year full year
|
|
2767
|
+
* @param opts.choices valid date choices
|
|
2768
|
+
* @returns true if date is out of range
|
|
2769
|
+
*/
|
|
2770
|
+
const isDateOutOfRange = (opts) => {
|
|
2771
|
+
const { month, day, year, choices, } = opts;
|
|
2772
|
+
return !choices.some((choice) => {
|
|
2773
|
+
return (choice.month === month
|
|
2774
|
+
&& choice.year === year
|
|
2775
|
+
&& choice.days.includes(day));
|
|
2776
|
+
});
|
|
2777
|
+
};
|
|
2778
|
+
/*------------------------------------------------------------------------*/
|
|
2779
|
+
/* ------------------------------ Component ----------------------------- */
|
|
2780
|
+
/*------------------------------------------------------------------------*/
|
|
2781
|
+
const SimpleDateChooser = (props) => {
|
|
2782
|
+
/*------------------------------------------------------------------------*/
|
|
2783
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
2784
|
+
/*------------------------------------------------------------------------*/
|
|
2785
|
+
/* -------------- Props ------------- */
|
|
2786
|
+
const { ariaLabel, name, dontAllowPast, dontAllowFuture, numMonthsToShow, onChange, month, day, year, } = props;
|
|
2787
|
+
// Get choices
|
|
2788
|
+
const choices = getChoices({
|
|
2789
|
+
numMonthsToShow,
|
|
2790
|
+
dontAllowPast,
|
|
2791
|
+
dontAllowFuture,
|
|
2792
|
+
});
|
|
2793
|
+
/* -------------- State ------------- */
|
|
2794
|
+
// Check if the currently selected date is out of range
|
|
2795
|
+
const currentSelectedDateOutOfRange = isDateOutOfRange({
|
|
2796
|
+
month,
|
|
2797
|
+
day,
|
|
2798
|
+
year,
|
|
2799
|
+
choices,
|
|
2800
|
+
});
|
|
2801
|
+
// Initial state
|
|
2802
|
+
const initialState = {
|
|
2803
|
+
view: (currentSelectedDateOutOfRange
|
|
2804
|
+
? View.InvalidDate
|
|
2805
|
+
: View.DateChooser),
|
|
2806
|
+
};
|
|
2807
|
+
// Initialize state
|
|
2808
|
+
const [state, dispatch] = useReducer(reducer$b, initialState);
|
|
2809
|
+
// Destructure common state
|
|
2810
|
+
const { view, } = state;
|
|
2811
|
+
/*------------------------------------------------------------------------*/
|
|
2812
|
+
/* ------------------------- Component Functions ------------------------ */
|
|
2813
|
+
/*------------------------------------------------------------------------*/
|
|
2814
|
+
/**
|
|
2815
|
+
* Ask the user if they want to edit an invalid date
|
|
2816
|
+
* @author Gardenia Liu
|
|
2817
|
+
* @author Gabe Abrams
|
|
2818
|
+
*/
|
|
2819
|
+
const askToEditInvalidDate = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
2820
|
+
// Ask the user if they want to edit the date
|
|
2821
|
+
const confirmed = yield confirm('Are you sure?', 'The current date is outside the normal range. If you edit it, you\'ll need to choose a new date in the normal range.', {
|
|
2822
|
+
confirmButtonText: 'Edit Date',
|
|
2823
|
+
});
|
|
2824
|
+
// Check if user confirmed
|
|
2825
|
+
if (confirmed) {
|
|
2826
|
+
// Update the date to today
|
|
2827
|
+
const today = getTimeInfoInET();
|
|
2828
|
+
onChange(today.month, today.day, today.year);
|
|
2829
|
+
// Update state
|
|
2830
|
+
dispatch({
|
|
2831
|
+
type: ActionType$a.FixInvalidDate,
|
|
2719
2832
|
});
|
|
2720
2833
|
}
|
|
2721
2834
|
});
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2835
|
+
/*------------------------------------------------------------------------*/
|
|
2836
|
+
/* ------------------------------- Render ------------------------------- */
|
|
2837
|
+
/*------------------------------------------------------------------------*/
|
|
2838
|
+
/*----------------------------------------*/
|
|
2839
|
+
/* ---------------- Views --------------- */
|
|
2840
|
+
/*----------------------------------------*/
|
|
2841
|
+
// Body that will be filled with the current view
|
|
2842
|
+
let body;
|
|
2843
|
+
/* ---------- DateChooser ---------- */
|
|
2844
|
+
if (view === View.DateChooser) {
|
|
2845
|
+
// Create lists of options
|
|
2846
|
+
const monthOptions = [];
|
|
2847
|
+
const dayOptions = [];
|
|
2848
|
+
// Render each option and add it to the list
|
|
2849
|
+
choices.forEach((choice) => {
|
|
2850
|
+
// Create month option
|
|
2851
|
+
monthOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}`, value: `${choice.month}-${choice.year}`, "aria-label": `choose ${choice.choiceName}`, onSelect: () => {
|
|
2852
|
+
onChange(choice.month, choice.days[0], choice.year);
|
|
2853
|
+
} }, choice.choiceName));
|
|
2854
|
+
// This is the currently selected month
|
|
2855
|
+
if (month === choice.month) {
|
|
2856
|
+
// Create day options
|
|
2857
|
+
choice.days.forEach((dayChoice) => {
|
|
2858
|
+
const ordinal = getOrdinal(dayChoice);
|
|
2859
|
+
dayOptions.push(React__default.createElement("option", { key: `${choice.year}-${choice.month}-${dayChoice}`, value: dayChoice, "aria-label": `choose date ${dayChoice}` },
|
|
2860
|
+
dayChoice,
|
|
2861
|
+
ordinal));
|
|
2862
|
+
});
|
|
2863
|
+
}
|
|
2864
|
+
});
|
|
2865
|
+
// Create body
|
|
2866
|
+
body = (React__default.createElement("div", { className: "SimpleDateChooser-inner-container d-inline-block", "aria-label": `date chooser with selected date: ${month}/${day}/${year}` },
|
|
2867
|
+
React__default.createElement("select", { "aria-label": `month for ${ariaLabel}`, className: "custom-select d-inline-block mr-1", style: { width: 'auto' }, id: `SimpleDateChooser-${name}-month`, value: `${month}-${year}`, onChange: (e) => {
|
|
2868
|
+
const choice = choices[e.target.selectedIndex];
|
|
2869
|
+
// Change day, month, and year
|
|
2870
|
+
onChange(choice.month, choice.days[0], choice.year);
|
|
2871
|
+
} }, monthOptions),
|
|
2872
|
+
React__default.createElement("select", { "aria-label": `day for ${ariaLabel}`, className: "custom-select d-inline-block", style: { width: 'auto' }, id: `SimpleDateChooser-${name}-day`, value: day, onChange: (e) => {
|
|
2873
|
+
// Only change the day
|
|
2874
|
+
onChange(month, Number.parseInt(e.target.value, 10), year);
|
|
2875
|
+
} }, dayOptions)));
|
|
2876
|
+
}
|
|
2877
|
+
/* --------- DateOutOfRange --------- */
|
|
2878
|
+
if (view === View.InvalidDate) {
|
|
2879
|
+
body = (React__default.createElement("div", { className: "SimpleDateChooser-inner-container d-inline-block" },
|
|
2880
|
+
React__default.createElement("button", { type: "button", className: "btn btn-light", onClick: askToEditInvalidDate, "aria-label": `edit date for ${ariaLabel}` },
|
|
2881
|
+
getMonthName(month).full,
|
|
2882
|
+
' ',
|
|
2883
|
+
day,
|
|
2884
|
+
getOrdinal(day),
|
|
2885
|
+
",",
|
|
2886
|
+
' ',
|
|
2887
|
+
year),
|
|
2888
|
+
React__default.createElement("button", { type: "button", className: "btn btn-secondary", onClick: askToEditInvalidDate, "aria-label": `edit date for ${ariaLabel}` }, "Edit")));
|
|
2889
|
+
}
|
|
2890
|
+
/*----------------------------------------*/
|
|
2891
|
+
/* --------------- Main UI -------------- */
|
|
2892
|
+
/*----------------------------------------*/
|
|
2893
|
+
return (React__default.createElement("span", { className: "SimpleDateChooser-outer-container" }, body));
|
|
2894
|
+
};
|
|
2895
|
+
|
|
2896
|
+
/**
|
|
2897
|
+
* Pad a number with zeros on the left (e.g. 5 becomes 05 with 2 digit padding)
|
|
2898
|
+
* @author Gabe Abrams
|
|
2899
|
+
* @param num the number to pad
|
|
2900
|
+
* @param numDigits the minimum number of digits before the decimal
|
|
2901
|
+
* @returns padded number
|
|
2902
|
+
*/
|
|
2903
|
+
const padZerosLeft = (num, numDigits) => {
|
|
2904
|
+
// Convert to string
|
|
2905
|
+
let out = String(num);
|
|
2906
|
+
// Add zeros
|
|
2907
|
+
while (out.split('.')[0].length < numDigits) {
|
|
2908
|
+
out = `0${out}`;
|
|
2909
|
+
}
|
|
2910
|
+
// Return
|
|
2911
|
+
return out;
|
|
2912
|
+
};
|
|
2913
|
+
|
|
2914
|
+
/**
|
|
2915
|
+
* A very simple, lightweight time chooser
|
|
2916
|
+
* @author Gardenia Liu
|
|
2917
|
+
*/
|
|
2918
|
+
/*------------------------------------------------------------------------*/
|
|
2919
|
+
/* ------------------------------ Constants ----------------------------- */
|
|
2920
|
+
/*------------------------------------------------------------------------*/
|
|
2921
|
+
// Allowed intervals between options
|
|
2922
|
+
const ALLOWED_INTERVALS = [15, 30, 60]; // min
|
|
2923
|
+
// Default interval to use if an unsupported interval is passed in
|
|
2924
|
+
const DEFAULT_INTERVAL = ALLOWED_INTERVALS[0]; // min
|
|
2925
|
+
/*------------------------------------------------------------------------*/
|
|
2926
|
+
/* ------------------------------ Component ----------------------------- */
|
|
2927
|
+
/*------------------------------------------------------------------------*/
|
|
2928
|
+
const SimpleTimeChooser = (props) => {
|
|
2929
|
+
/*------------------------------------------------------------------------*/
|
|
2930
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
2931
|
+
/*------------------------------------------------------------------------*/
|
|
2932
|
+
/* -------------- Props ------------- */
|
|
2933
|
+
const { ariaLabel, name, hour, minute, onChange, } = props;
|
|
2934
|
+
let { intervalMin = DEFAULT_INTERVAL, } = props;
|
|
2935
|
+
// Use default interval if not supported
|
|
2936
|
+
if (!ALLOWED_INTERVALS.includes(intervalMin)) {
|
|
2937
|
+
intervalMin = DEFAULT_INTERVAL;
|
|
2938
|
+
}
|
|
2939
|
+
/*------------------------------------------------------------------------*/
|
|
2940
|
+
/* ------------------------- Component Functions ------------------------ */
|
|
2941
|
+
/*------------------------------------------------------------------------*/
|
|
2942
|
+
/**
|
|
2943
|
+
* Convert number of minutes since midnight into 24hour and minute format
|
|
2944
|
+
* @author Gabe Abrams
|
|
2945
|
+
* @param minSinceMidnight total minutes since midnight
|
|
2946
|
+
* @returns hours (24) and minutes
|
|
2947
|
+
*/
|
|
2948
|
+
const convertMinSinceMidnightToHoursAndMin = (minSinceMidnight) => {
|
|
2949
|
+
return {
|
|
2950
|
+
hours: Math.floor(minSinceMidnight / 60),
|
|
2951
|
+
minutes: minSinceMidnight % 60,
|
|
2952
|
+
};
|
|
2953
|
+
};
|
|
2954
|
+
/**
|
|
2955
|
+
* Convert time in minutes into HH:MM format
|
|
2956
|
+
* @author Gardenia Liu
|
|
2957
|
+
* @param totalMinutes total minutes since midnight
|
|
2958
|
+
* @returns formatted time string
|
|
2959
|
+
*/
|
|
2960
|
+
const formatTime = (totalMinutes) => {
|
|
2961
|
+
// Handle special cases
|
|
2962
|
+
if (totalMinutes === 0) {
|
|
2963
|
+
return '12:00 Midnight';
|
|
2964
|
+
}
|
|
2965
|
+
if (totalMinutes === 12 * 60) {
|
|
2966
|
+
return '12:00 Noon';
|
|
2967
|
+
}
|
|
2968
|
+
// All normal cases:
|
|
2969
|
+
const timeInfo = convertMinSinceMidnightToHoursAndMin(totalMinutes);
|
|
2970
|
+
let { hours } = timeInfo;
|
|
2971
|
+
const { minutes } = timeInfo;
|
|
2972
|
+
// Process 24hr -> 12hr
|
|
2973
|
+
const isAM = (hours < 12);
|
|
2974
|
+
if (hours === 0) {
|
|
2975
|
+
hours = 12;
|
|
2976
|
+
}
|
|
2977
|
+
else if (hours > 12) {
|
|
2978
|
+
hours %= 12;
|
|
2979
|
+
}
|
|
2980
|
+
// Pad with zeros
|
|
2981
|
+
const paddedMinutes = padZerosLeft(minutes, 2);
|
|
2982
|
+
// Assemble time string
|
|
2983
|
+
return `${hours}:${paddedMinutes} ${isAM ? 'AM' : 'PM'}`;
|
|
2984
|
+
};
|
|
2985
|
+
/*------------------------------------------------------------------------*/
|
|
2986
|
+
/* ------------------------------- Render ------------------------------- */
|
|
2987
|
+
/*------------------------------------------------------------------------*/
|
|
2988
|
+
/*----------------------------------------*/
|
|
2989
|
+
/* --------------- Main UI -------------- */
|
|
2990
|
+
/*----------------------------------------*/
|
|
2991
|
+
// Generate list of time options
|
|
2992
|
+
const times = [];
|
|
2993
|
+
for (let time = 0; time < 24 * 60; time += intervalMin) {
|
|
2994
|
+
times.push(formatTime(time));
|
|
2995
|
+
}
|
|
2996
|
+
// Currently selected time in minutes since midnight
|
|
2997
|
+
const selectedTimeMin = hour * 60 + minute;
|
|
2998
|
+
// Create choice options
|
|
2999
|
+
const timeOptions = times.map((timeString, timeIndex) => {
|
|
3000
|
+
const numMinutesForChoice = timeIndex * intervalMin;
|
|
3001
|
+
// Render the option
|
|
3002
|
+
return (React__default.createElement("option", { key: numMinutesForChoice, value: numMinutesForChoice, "aria-label": `choose ${timeString}` }, timeString));
|
|
3003
|
+
});
|
|
3004
|
+
return (React__default.createElement("div", { className: "SimpleTimeChooser-container", "aria-label": `time chooser with selected time: ${formatTime(selectedTimeMin)}` },
|
|
3005
|
+
React__default.createElement("select", { "aria-label": `time for ${ariaLabel}`, className: "custom-select d-inline-block", style: { width: 'auto' }, id: `SimpleTimeChooser-${name}-time`, value: selectedTimeMin, onChange: (e) => {
|
|
3006
|
+
// Parse selector value (string)
|
|
3007
|
+
const newTime = Number.parseInt(e.target.value, 10);
|
|
3008
|
+
// Convert minutes since midnight to hour and minute
|
|
3009
|
+
const timeInfo = convertMinSinceMidnightToHoursAndMin(newTime);
|
|
3010
|
+
// Notify parent
|
|
3011
|
+
onChange(timeInfo.hours, timeInfo.minutes);
|
|
3012
|
+
} }, timeOptions)));
|
|
2732
3013
|
};
|
|
2733
3014
|
|
|
2734
3015
|
/**
|
|
@@ -4825,14 +5106,14 @@ const LogReviewer = (props) => {
|
|
|
4825
5106
|
if (expandedFilterDrawer) {
|
|
4826
5107
|
if (expandedFilterDrawer === FilterDrawer.Date) {
|
|
4827
5108
|
filterDrawer = (React__default.createElement(TabBox, { title: "Date" },
|
|
4828
|
-
React__default.createElement(SimpleDateChooser, { ariaLabel: "filter start date", name: "filter-start-date", year: dateFilterState.startDate.year, month: dateFilterState.startDate.month, day: dateFilterState.startDate.day,
|
|
5109
|
+
React__default.createElement(SimpleDateChooser, { ariaLabel: "filter start date", name: "filter-start-date", year: dateFilterState.startDate.year, month: dateFilterState.startDate.month, day: dateFilterState.startDate.day, dontAllowFuture: true, numMonthsToShow: 36, onChange: (month, day, year) => {
|
|
4829
5110
|
dateFilterState.startDate = { month, day, year };
|
|
4830
5111
|
handleDateRangeUpdated(dateFilterState);
|
|
4831
5112
|
} }),
|
|
4832
5113
|
' ',
|
|
4833
5114
|
"to",
|
|
4834
5115
|
' ',
|
|
4835
|
-
React__default.createElement(SimpleDateChooser, { ariaLabel: "filter end date", name: "filter-end-date", year: dateFilterState.endDate.year, month: dateFilterState.endDate.month, day: dateFilterState.endDate.day,
|
|
5116
|
+
React__default.createElement(SimpleDateChooser, { ariaLabel: "filter end date", name: "filter-end-date", year: dateFilterState.endDate.year, month: dateFilterState.endDate.month, day: dateFilterState.endDate.day, dontAllowFuture: true, numMonthsToShow: 12, onChange: (month, day, year) => {
|
|
4836
5117
|
if (year < dateFilterState.startDate.year
|
|
4837
5118
|
|| (year === dateFilterState.startDate.year
|
|
4838
5119
|
&& month < dateFilterState.startDate.month)
|
|
@@ -15312,24 +15593,6 @@ const padDecimalZeros = (num, numDigits) => {
|
|
|
15312
15593
|
return out;
|
|
15313
15594
|
};
|
|
15314
15595
|
|
|
15315
|
-
/**
|
|
15316
|
-
* Pad a number with zeros on the left (e.g. 5 becomes 05 with 2 digit padding)
|
|
15317
|
-
* @author Gabe Abrams
|
|
15318
|
-
* @param num the number to pad
|
|
15319
|
-
* @param numDigits the minimum number of digits before the decimal
|
|
15320
|
-
* @returns padded number
|
|
15321
|
-
*/
|
|
15322
|
-
const padZerosLeft = (num, numDigits) => {
|
|
15323
|
-
// Convert to string
|
|
15324
|
-
let out = String(num);
|
|
15325
|
-
// Add zeros
|
|
15326
|
-
while (out.split('.')[0].length < numDigits) {
|
|
15327
|
-
out = `0${out}`;
|
|
15328
|
-
}
|
|
15329
|
-
// Return
|
|
15330
|
-
return out;
|
|
15331
|
-
};
|
|
15332
|
-
|
|
15333
15596
|
/**
|
|
15334
15597
|
* Stub a server endpoint response
|
|
15335
15598
|
* @author Gabe Abrams
|
|
@@ -16200,5 +16463,5 @@ var DayOfWeek;
|
|
|
16200
16463
|
})(DayOfWeek || (DayOfWeek = {}));
|
|
16201
16464
|
var DayOfWeek$1 = DayOfWeek;
|
|
16202
16465
|
|
|
16203
|
-
export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntryFieldType$1 as DBEntryFieldType, DBEntryManagerPanel, DayOfWeek$1 as DayOfWeek, Drawer, Dropdown, DropdownItemType$1 as DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, ItemPicker, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_REVIEW_STATUS_ROUTE, LOG_ROUTE_PATH, LoadingSpinner, LogAction$1 as LogAction, LogBuiltInMetadata, LogLevel$1 as LogLevel, LogReviewer, LogSource$1 as LogSource, LogType$1 as LogType, MINUTE_IN_MS, Modal, ModalButtonType$1 as ModalButtonType, ModalSize$1 as ModalSize, ModalType$1 as ModalType, MultiSwitch, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, getWordCount, idify, initClient, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, prompt, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
|
|
16466
|
+
export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntryFieldType$1 as DBEntryFieldType, DBEntryManagerPanel, DayOfWeek$1 as DayOfWeek, Drawer, Dropdown, DropdownItemType$1 as DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, ItemPicker, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_REVIEW_STATUS_ROUTE, LOG_ROUTE_PATH, LoadingSpinner, LogAction$1 as LogAction, LogBuiltInMetadata, LogLevel$1 as LogLevel, LogReviewer, LogSource$1 as LogSource, LogType$1 as LogType, MINUTE_IN_MS, Modal, ModalButtonType$1 as ModalButtonType, ModalSize$1 as ModalSize, ModalType$1 as ModalType, MultiSwitch, ParamType$1 as ParamType, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode$1 as ReactKitErrorCode, SimpleDateChooser, SimpleTimeChooser, TabBox, ToggleSwitch, Tooltip, Variant$1 as Variant, abbreviate, addFatalErrorHandler, alert, avg, canReviewLogs, capitalize, ceilToNumDecimals, combineClassNames, compareArraysByProp, confirm, everyAsync, extractProp, filterAsync, floorToNumDecimals, forEachAsync, forceNumIntoBounds, genCSV, genCommaList, getHumanReadableDate, getLocalTimeInfo, getMonthName, getOrdinal, getPartOfDay, getTimeInfoInET, getWordCount, idify, initClient, isMobileOrTablet, leaveToURL, logClientEvent, makeLinksClickable, mapAsync, onlyKeepLetters, padDecimalZeros, padZerosLeft, parallelLimit, prefixWithAOrAn, prompt, roundToNumDecimals, setClientEventMetadataPopulator, showFatalError, shuffleArray, someAsync, startMinWait, stringsToHumanReadableList, stubServerEndpoint, sum, useForceRender, validateEmail, validatePhoneNumber, validateString, visitServerEndpoint, waitMs };
|
|
16204
16467
|
//# sourceMappingURL=index.js.map
|