dce-reactkit 4.0.0 → 4.0.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 +174 -53
- 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 +174 -54
- 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 +62 -26
- 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/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ declare enum Variant {
|
|
|
23
23
|
* @author Gabe Abrams
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
-
type Props$
|
|
26
|
+
type Props$m = {
|
|
27
27
|
children: React$1.ReactNode;
|
|
28
28
|
};
|
|
29
29
|
/**
|
|
@@ -106,7 +106,7 @@ declare const showFatalError: (error: any, errorTitle?: string) => Promise<void>
|
|
|
106
106
|
* @author Gabe Abrams
|
|
107
107
|
*/
|
|
108
108
|
declare const addFatalErrorHandler: (handler: () => void) => void;
|
|
109
|
-
declare const AppWrapper: React$1.FC<Props$
|
|
109
|
+
declare const AppWrapper: React$1.FC<Props$m>;
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
112
|
* Loading spinner/indicator
|
|
@@ -120,14 +120,14 @@ declare const LoadingSpinner: () => React$1.JSX.Element;
|
|
|
120
120
|
* @author Gabe Abrams
|
|
121
121
|
*/
|
|
122
122
|
|
|
123
|
-
type Props$
|
|
123
|
+
type Props$l = {
|
|
124
124
|
error: any;
|
|
125
125
|
title?: string;
|
|
126
126
|
onClose?: () => void;
|
|
127
127
|
variant?: Variant;
|
|
128
128
|
icon?: IconProp;
|
|
129
129
|
};
|
|
130
|
-
declare const ErrorBox: React$1.FC<Props$
|
|
130
|
+
declare const ErrorBox: React$1.FC<Props$l>;
|
|
131
131
|
|
|
132
132
|
/**
|
|
133
133
|
* Types of buttons in the modal
|
|
@@ -226,21 +226,21 @@ declare const Modal: React$1.FC<ModalProps>;
|
|
|
226
226
|
* @author Gabe Abrams
|
|
227
227
|
*/
|
|
228
228
|
|
|
229
|
-
type Props$
|
|
229
|
+
type Props$k = {
|
|
230
230
|
title: React$1.ReactNode;
|
|
231
231
|
children: React$1.ReactNode;
|
|
232
232
|
topRightChildren?: React$1.ReactNode;
|
|
233
233
|
noBottomMargin?: boolean;
|
|
234
234
|
noBottomPadding?: boolean;
|
|
235
235
|
};
|
|
236
|
-
declare const TabBox: React$1.FC<Props$
|
|
236
|
+
declare const TabBox: React$1.FC<Props$k>;
|
|
237
237
|
|
|
238
238
|
/**
|
|
239
239
|
* A radio selection button
|
|
240
240
|
* @author Gabe Abrams
|
|
241
241
|
*/
|
|
242
242
|
|
|
243
|
-
type Props$
|
|
243
|
+
type Props$j = {
|
|
244
244
|
text: React$1.ReactNode;
|
|
245
245
|
onSelected: () => void;
|
|
246
246
|
ariaLabel: string;
|
|
@@ -254,14 +254,14 @@ type Props$i = {
|
|
|
254
254
|
small?: boolean;
|
|
255
255
|
useComplexFormatting?: boolean;
|
|
256
256
|
};
|
|
257
|
-
declare const RadioButton: React$1.FC<Props$
|
|
257
|
+
declare const RadioButton: React$1.FC<Props$j>;
|
|
258
258
|
|
|
259
259
|
/**
|
|
260
260
|
* A checkbox button
|
|
261
261
|
* @author Gabe Abrams
|
|
262
262
|
*/
|
|
263
263
|
|
|
264
|
-
type Props$
|
|
264
|
+
type Props$i = {
|
|
265
265
|
text: React$1.ReactNode;
|
|
266
266
|
onChanged: (checked: boolean) => void;
|
|
267
267
|
ariaLabel: string;
|
|
@@ -276,14 +276,14 @@ type Props$h = {
|
|
|
276
276
|
dashed?: boolean;
|
|
277
277
|
useComplexFormatting?: boolean;
|
|
278
278
|
};
|
|
279
|
-
declare const CheckboxButton: React$1.FC<Props$
|
|
279
|
+
declare const CheckboxButton: React$1.FC<Props$i>;
|
|
280
280
|
|
|
281
281
|
/**
|
|
282
282
|
* Input group with a title and space for buttons
|
|
283
283
|
* @author Gabe Abrams
|
|
284
284
|
*/
|
|
285
285
|
|
|
286
|
-
type Props$
|
|
286
|
+
type Props$h = {
|
|
287
287
|
label: React$1.ReactNode;
|
|
288
288
|
minLabelWidth?: string;
|
|
289
289
|
children: React$1.ReactNode;
|
|
@@ -292,14 +292,15 @@ type Props$g = {
|
|
|
292
292
|
isAdminFeature?: boolean;
|
|
293
293
|
noMarginOnBottom?: boolean;
|
|
294
294
|
};
|
|
295
|
-
declare const ButtonInputGroup: React$1.FC<Props$
|
|
295
|
+
declare const ButtonInputGroup: React$1.FC<Props$h>;
|
|
296
296
|
|
|
297
297
|
/**
|
|
298
298
|
* A very simple, lightweight date chooser
|
|
299
299
|
* @author Gabe Abrams
|
|
300
|
+
* @author Gardenia Liu
|
|
300
301
|
*/
|
|
301
302
|
|
|
302
|
-
type Props$
|
|
303
|
+
type Props$g = {
|
|
303
304
|
ariaLabel: string;
|
|
304
305
|
name: string;
|
|
305
306
|
month: number;
|
|
@@ -313,9 +314,30 @@ type Props$f = {
|
|
|
313
314
|
*/
|
|
314
315
|
onChange: (month: number, day: number, year: number) => void;
|
|
315
316
|
numMonthsToShow?: number;
|
|
316
|
-
|
|
317
|
+
dontAllowPast?: boolean;
|
|
318
|
+
dontAllowFuture?: boolean;
|
|
319
|
+
};
|
|
320
|
+
declare const SimpleDateChooser: React$1.FC<Props$g>;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* A very simple, lightweight time chooser
|
|
324
|
+
* @author Gardenia Liu
|
|
325
|
+
*/
|
|
326
|
+
|
|
327
|
+
type Props$f = {
|
|
328
|
+
ariaLabel: string;
|
|
329
|
+
name: string;
|
|
330
|
+
hour: number;
|
|
331
|
+
minute: number;
|
|
332
|
+
/**
|
|
333
|
+
* Handler for when time changes
|
|
334
|
+
* @param hour new 24hr hour number
|
|
335
|
+
* @param minute new minute number
|
|
336
|
+
*/
|
|
337
|
+
onChange: (hour: number, minute: number) => void;
|
|
338
|
+
intervalMin?: number;
|
|
317
339
|
};
|
|
318
|
-
declare const
|
|
340
|
+
declare const SimpleTimeChooser: React$1.FC<Props$f>;
|
|
319
341
|
|
|
320
342
|
/**
|
|
321
343
|
* Drawer container
|
|
@@ -1550,7 +1572,9 @@ declare enum ReactKitErrorCode {
|
|
|
1550
1572
|
NoResponse = "DRK1",
|
|
1551
1573
|
NoCode = "DRK2",
|
|
1552
1574
|
SessionExpired = "DRK3",
|
|
1553
|
-
NoCACCLSendRequestFunction = "DRK7"
|
|
1575
|
+
NoCACCLSendRequestFunction = "DRK7",
|
|
1576
|
+
SimpleDateChooserInvalidDateRange = "DRK35",
|
|
1577
|
+
SimpleDateChooserInvalidNumMonths = "DRK36"
|
|
1554
1578
|
}
|
|
1555
1579
|
|
|
1556
|
-
export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntry, DBEntryField, DBEntryFieldType, DBEntryManagerPanel, DayOfWeek, Drawer, Dropdown, DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, IntelliTableColumn, ItemPicker, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_REVIEW_STATUS_ROUTE, LOG_ROUTE_PATH, LoadingSpinner, Log, LogAction, LogBuiltInMetadata, LogFunction, LogLevel, LogMainInfo, LogMetadataType, LogReviewer, LogSource, LogSourceSpecificInfo, LogType, LogTypeSpecificInfo, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, MultiSwitch, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, TabBox, ToggleSwitch, Tooltip, 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 };
|
|
1580
|
+
export { AppWrapper, AutoscrollToBottomContainer, ButtonInputGroup, CSVDownloadButton, CheckboxButton, CopiableBox, DAY_IN_MS, DBEntry, DBEntryField, DBEntryFieldType, DBEntryManagerPanel, DayOfWeek, Drawer, Dropdown, DropdownItemType, DynamicWord, ErrorBox, ErrorWithCode, HOUR_IN_MS, IntelliTable, IntelliTableColumn, ItemPicker, LOG_REVIEW_ROUTE_PATH_PREFIX, LOG_REVIEW_STATUS_ROUTE, LOG_ROUTE_PATH, LoadingSpinner, Log, LogAction, LogBuiltInMetadata, LogFunction, LogLevel, LogMainInfo, LogMetadataType, LogReviewer, LogSource, LogSourceSpecificInfo, LogType, LogTypeSpecificInfo, MINUTE_IN_MS, Modal, ModalButtonType, ModalSize, ModalType, MultiSwitch, ParamType, PickableItem, PopFailureMark, PopPendingMark, PopSuccessMark, RadioButton, ReactKitErrorCode, SimpleDateChooser, SimpleTimeChooser, TabBox, ToggleSwitch, Tooltip, 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 };
|
package/package.json
CHANGED
|
@@ -1182,7 +1182,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1182
1182
|
year={dateFilterState.startDate.year}
|
|
1183
1183
|
month={dateFilterState.startDate.month}
|
|
1184
1184
|
day={dateFilterState.startDate.day}
|
|
1185
|
-
|
|
1185
|
+
dontAllowFuture
|
|
1186
1186
|
numMonthsToShow={36}
|
|
1187
1187
|
onChange={(month, day, year) => {
|
|
1188
1188
|
dateFilterState.startDate = { month, day, year };
|
|
@@ -1198,7 +1198,7 @@ const LogReviewer: React.FC<Props> = (props) => {
|
|
|
1198
1198
|
year={dateFilterState.endDate.year}
|
|
1199
1199
|
month={dateFilterState.endDate.month}
|
|
1200
1200
|
day={dateFilterState.endDate.day}
|
|
1201
|
-
|
|
1201
|
+
dontAllowFuture
|
|
1202
1202
|
numMonthsToShow={12}
|
|
1203
1203
|
onChange={(month, day, year) => {
|
|
1204
1204
|
if (
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A very simple, lightweight date chooser
|
|
3
3
|
* @author Gabe Abrams
|
|
4
|
+
* @author Gardenia Liu
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
// Import React
|
|
7
8
|
import React from 'react';
|
|
8
|
-
import getMonthName from '../helpers/getMonthName';
|
|
9
9
|
|
|
10
10
|
// Import helpers
|
|
11
11
|
import getOrdinal from '../helpers/getOrdinal';
|
|
12
|
+
import getMonthName from '../helpers/getMonthName';
|
|
12
13
|
import getTimeInfoInET from '../helpers/getTimeInfoInET';
|
|
13
14
|
|
|
15
|
+
// Import classes
|
|
16
|
+
import ErrorWithCode from '../errors/ErrorWithCode';
|
|
17
|
+
|
|
18
|
+
// Import types
|
|
19
|
+
import ReactKitErrorCode from '../types/ReactKitErrorCode';
|
|
20
|
+
|
|
14
21
|
/*------------------------------------------------------------------------*/
|
|
15
22
|
/* -------------------------------- Types ------------------------------- */
|
|
16
23
|
/*------------------------------------------------------------------------*/
|
|
@@ -33,12 +40,14 @@ type Props = {
|
|
|
33
40
|
* @param year new full year number
|
|
34
41
|
*/
|
|
35
42
|
onChange: (month: number, day: number, year: number) => void,
|
|
36
|
-
// Number of months to allow the user to choose from
|
|
37
|
-
//
|
|
43
|
+
// Number of months in either the past or future to allow the user to choose from
|
|
44
|
+
// If we aren't allowing the past or the future, we will throw an error
|
|
45
|
+
// (max is 12, default is 6 in the past and 6 in the future)
|
|
38
46
|
numMonthsToShow?: number,
|
|
39
|
-
// If true,
|
|
40
|
-
|
|
41
|
-
|
|
47
|
+
// If true, the user isn't allowed to select dates in the past
|
|
48
|
+
dontAllowPast?: boolean,
|
|
49
|
+
// If true, the user isn't allowed to select dates in the future
|
|
50
|
+
dontAllowFuture?: boolean,
|
|
42
51
|
};
|
|
43
52
|
|
|
44
53
|
/*------------------------------------------------------------------------*/
|
|
@@ -56,8 +65,9 @@ const SimpleDateChooser: React.FC<Props> = (props) => {
|
|
|
56
65
|
ariaLabel,
|
|
57
66
|
name,
|
|
58
67
|
onChange,
|
|
59
|
-
chooseFromPast,
|
|
60
68
|
numMonthsToShow = 6,
|
|
69
|
+
dontAllowFuture,
|
|
70
|
+
dontAllowPast,
|
|
61
71
|
} = props;
|
|
62
72
|
|
|
63
73
|
/*------------------------------------------------------------------------*/
|
|
@@ -76,16 +86,41 @@ const SimpleDateChooser: React.FC<Props> = (props) => {
|
|
|
76
86
|
days: number[],
|
|
77
87
|
year: number,
|
|
78
88
|
}[] = [];
|
|
89
|
+
|
|
79
90
|
let startYear = today.year;
|
|
80
91
|
let startMonth = today.month;
|
|
81
|
-
|
|
92
|
+
|
|
93
|
+
// Don't allow past or future dates
|
|
94
|
+
if (dontAllowPast && dontAllowFuture) {
|
|
95
|
+
throw new ErrorWithCode(
|
|
96
|
+
'No past or future dates allowed',
|
|
97
|
+
ReactKitErrorCode.SimpleDateChooserInvalidDateRange,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Require numMonthsToShow to be positive
|
|
102
|
+
if (numMonthsToShow <= 0) {
|
|
103
|
+
throw new ErrorWithCode(
|
|
104
|
+
'numMonthsToShow must be positive',
|
|
105
|
+
ReactKitErrorCode.SimpleDateChooserInvalidNumMonths,
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Recalculate startMonth and startYear when allowing past dates
|
|
110
|
+
if (!dontAllowPast) {
|
|
82
111
|
startMonth -= Math.max(0, numMonthsToShow - 1);
|
|
83
112
|
while (startMonth <= 0) {
|
|
84
113
|
startMonth += 12;
|
|
85
114
|
startYear -= 1;
|
|
86
115
|
}
|
|
87
116
|
}
|
|
88
|
-
|
|
117
|
+
// Calculate total number of months to show
|
|
118
|
+
let totalMonthsToShow = numMonthsToShow;
|
|
119
|
+
if (!dontAllowPast && !dontAllowFuture) {
|
|
120
|
+
totalMonthsToShow = totalMonthsToShow * 2 - 1;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (let i = 0; i < totalMonthsToShow; i++) {
|
|
89
124
|
// Get month and year info
|
|
90
125
|
const unmoddedMonth = (startMonth + i);
|
|
91
126
|
let month = unmoddedMonth;
|
|
@@ -105,24 +140,25 @@ const SimpleDateChooser: React.FC<Props> = (props) => {
|
|
|
105
140
|
// Figure out which days are allowed
|
|
106
141
|
const days = [];
|
|
107
142
|
const numDaysInMonth = (new Date(year, month, 0)).getDate();
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
days.push(day);
|
|
143
|
+
|
|
144
|
+
// Current month
|
|
145
|
+
if (month === today.month && year === today.year) {
|
|
146
|
+
// Past selection: add all previous days of the month
|
|
147
|
+
if (!dontAllowPast) {
|
|
148
|
+
for (let day = 1; day < today.day; day++) {
|
|
149
|
+
days.push(day);
|
|
150
|
+
}
|
|
117
151
|
}
|
|
118
|
-
|
|
152
|
+
days.push(today.day); // Add current day
|
|
119
153
|
// Future selection: add all remaining days of the month
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
154
|
+
if (!dontAllowFuture) {
|
|
155
|
+
for (let day = today.day + 1; day <= numDaysInMonth; day++) {
|
|
156
|
+
days.push(day);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} else { // Past or future month
|
|
160
|
+
// Include all days in the month
|
|
161
|
+
for (let day = 1; day <= numDaysInMonth; day++) {
|
|
126
162
|
days.push(day);
|
|
127
163
|
}
|
|
128
164
|
}
|
|
@@ -158,8 +194,8 @@ const SimpleDateChooser: React.FC<Props> = (props) => {
|
|
|
158
194
|
</option>,
|
|
159
195
|
);
|
|
160
196
|
|
|
197
|
+
// This is the currently selected month
|
|
161
198
|
if (month === choice.month) {
|
|
162
|
-
// This is the currently selected month
|
|
163
199
|
// Create day options
|
|
164
200
|
choice.days.forEach((dayChoice) => {
|
|
165
201
|
const ordinal = getOrdinal(dayChoice);
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A very simple, lightweight time chooser
|
|
3
|
+
* @author Gardenia Liu
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Import React
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
// Import helpers
|
|
10
|
+
import padZerosLeft from '../helpers/padZerosLeft';
|
|
11
|
+
|
|
12
|
+
/*------------------------------------------------------------------------*/
|
|
13
|
+
/* -------------------------------- Types ------------------------------- */
|
|
14
|
+
/*------------------------------------------------------------------------*/
|
|
15
|
+
|
|
16
|
+
type Props = {
|
|
17
|
+
// Aria label
|
|
18
|
+
ariaLabel: string,
|
|
19
|
+
// Name of the chooser (machine-readable, hyphenated)
|
|
20
|
+
name: string,
|
|
21
|
+
// Currently selected hour of the day (24hr)
|
|
22
|
+
hour: number,
|
|
23
|
+
// Currently selected minute within the hour
|
|
24
|
+
minute: number,
|
|
25
|
+
/**
|
|
26
|
+
* Handler for when time changes
|
|
27
|
+
* @param hour new 24hr hour number
|
|
28
|
+
* @param minute new minute number
|
|
29
|
+
*/
|
|
30
|
+
onChange: (hour: number, minute: number) => void,
|
|
31
|
+
// Interval in minutes between each choice
|
|
32
|
+
// Allowed options: 15, 30, 60, defaults to 15
|
|
33
|
+
// If an unsupported interval is passed in, it will default to 15
|
|
34
|
+
intervalMin?: number,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/*------------------------------------------------------------------------*/
|
|
38
|
+
/* ------------------------------ Constants ----------------------------- */
|
|
39
|
+
/*------------------------------------------------------------------------*/
|
|
40
|
+
|
|
41
|
+
// Allowed intervals between options
|
|
42
|
+
const ALLOWED_INTERVALS = [15, 30, 60]; // min
|
|
43
|
+
|
|
44
|
+
// Default interval to use if an unsupported interval is passed in
|
|
45
|
+
const DEFAULT_INTERVAL = ALLOWED_INTERVALS[0]; // min
|
|
46
|
+
|
|
47
|
+
/*------------------------------------------------------------------------*/
|
|
48
|
+
/* ------------------------------ Component ----------------------------- */
|
|
49
|
+
/*------------------------------------------------------------------------*/
|
|
50
|
+
|
|
51
|
+
const SimpleTimeChooser: React.FC<Props> = (props) => {
|
|
52
|
+
/*------------------------------------------------------------------------*/
|
|
53
|
+
/* -------------------------------- Setup ------------------------------- */
|
|
54
|
+
/*------------------------------------------------------------------------*/
|
|
55
|
+
|
|
56
|
+
/* -------------- Props ------------- */
|
|
57
|
+
|
|
58
|
+
const {
|
|
59
|
+
ariaLabel,
|
|
60
|
+
name,
|
|
61
|
+
hour,
|
|
62
|
+
minute,
|
|
63
|
+
onChange,
|
|
64
|
+
} = props;
|
|
65
|
+
let {
|
|
66
|
+
intervalMin = DEFAULT_INTERVAL,
|
|
67
|
+
} = props;
|
|
68
|
+
|
|
69
|
+
// Use default interval if not supported
|
|
70
|
+
if (!ALLOWED_INTERVALS.includes(intervalMin)) {
|
|
71
|
+
intervalMin = DEFAULT_INTERVAL;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/*------------------------------------------------------------------------*/
|
|
75
|
+
/* ------------------------- Component Functions ------------------------ */
|
|
76
|
+
/*------------------------------------------------------------------------*/
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Convert number of minutes since midnight into 24hour and minute format
|
|
80
|
+
* @author Gabe Abrams
|
|
81
|
+
* @param minSinceMidnight total minutes since midnight
|
|
82
|
+
* @returns hours (24) and minutes
|
|
83
|
+
*/
|
|
84
|
+
const convertMinSinceMidnightToHoursAndMin = (minSinceMidnight: number): {
|
|
85
|
+
hours: number,
|
|
86
|
+
minutes: number,
|
|
87
|
+
} => {
|
|
88
|
+
return {
|
|
89
|
+
hours: Math.floor(minSinceMidnight / 60),
|
|
90
|
+
minutes: minSinceMidnight % 60,
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Convert time in minutes into HH:MM format
|
|
96
|
+
* @author Gardenia Liu
|
|
97
|
+
* @param totalMinutes total minutes since midnight
|
|
98
|
+
* @returns formatted time string
|
|
99
|
+
*/
|
|
100
|
+
const formatTime = (totalMinutes: number): string => {
|
|
101
|
+
// Handle special cases
|
|
102
|
+
if (totalMinutes === 0) {
|
|
103
|
+
return '12:00 Midnight';
|
|
104
|
+
}
|
|
105
|
+
if (totalMinutes === 12 * 60) {
|
|
106
|
+
return '12:00 Noon';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// All normal cases:
|
|
110
|
+
const timeInfo = convertMinSinceMidnightToHoursAndMin(totalMinutes);
|
|
111
|
+
let { hours } = timeInfo;
|
|
112
|
+
const { minutes } = timeInfo;
|
|
113
|
+
|
|
114
|
+
// Process 24hr -> 12hr
|
|
115
|
+
const isAM = (hours < 12);
|
|
116
|
+
if (hours === 0) {
|
|
117
|
+
hours = 12;
|
|
118
|
+
} else if (hours > 12) {
|
|
119
|
+
hours %= 12;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Pad with zeros
|
|
123
|
+
const paddedMinutes = padZerosLeft(minutes, 2);
|
|
124
|
+
|
|
125
|
+
// Assemble time string
|
|
126
|
+
return `${hours}:${paddedMinutes} ${isAM ? 'AM' : 'PM'}`;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/*------------------------------------------------------------------------*/
|
|
130
|
+
/* ------------------------------- Render ------------------------------- */
|
|
131
|
+
/*------------------------------------------------------------------------*/
|
|
132
|
+
|
|
133
|
+
/*----------------------------------------*/
|
|
134
|
+
/* --------------- Main UI -------------- */
|
|
135
|
+
/*----------------------------------------*/
|
|
136
|
+
|
|
137
|
+
// Generate list of time options
|
|
138
|
+
const times: string[] = [];
|
|
139
|
+
for (let time = 0; time < 24 * 60; time += intervalMin) {
|
|
140
|
+
times.push(formatTime(time));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Currently selected time in minutes since midnight
|
|
144
|
+
const selectedTimeMin = hour * 60 + minute;
|
|
145
|
+
|
|
146
|
+
// Create choice options
|
|
147
|
+
const timeOptions: React.ReactNode[] = times.map((timeString, timeIndex) => {
|
|
148
|
+
const numMinutesForChoice = timeIndex * intervalMin;
|
|
149
|
+
|
|
150
|
+
// Render the option
|
|
151
|
+
return (
|
|
152
|
+
<option
|
|
153
|
+
key={numMinutesForChoice}
|
|
154
|
+
value={numMinutesForChoice}
|
|
155
|
+
aria-label={`choose ${timeString}`}
|
|
156
|
+
>
|
|
157
|
+
{timeString}
|
|
158
|
+
</option>
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<div
|
|
164
|
+
className="SimpleTimeChooser-container"
|
|
165
|
+
aria-label={`time chooser with selected time: ${formatTime(selectedTimeMin)}`}
|
|
166
|
+
>
|
|
167
|
+
{/* Time Chooser */}
|
|
168
|
+
<select
|
|
169
|
+
aria-label={`time for ${ariaLabel}`}
|
|
170
|
+
className="custom-select d-inline-block"
|
|
171
|
+
style={{ width: 'auto' }}
|
|
172
|
+
id={`SimpleTimeChooser-${name}-time`}
|
|
173
|
+
value={selectedTimeMin}
|
|
174
|
+
onChange={(e) => {
|
|
175
|
+
// Parse selector value (string)
|
|
176
|
+
const newTime = Number.parseInt(e.target.value, 10);
|
|
177
|
+
|
|
178
|
+
// Convert minutes since midnight to hour and minute
|
|
179
|
+
const timeInfo = convertMinSinceMidnightToHoursAndMin(newTime);
|
|
180
|
+
|
|
181
|
+
// Notify parent
|
|
182
|
+
onChange(timeInfo.hours, timeInfo.minutes);
|
|
183
|
+
}}
|
|
184
|
+
>
|
|
185
|
+
{timeOptions}
|
|
186
|
+
</select>
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
/*------------------------------------------------------------------------*/
|
|
192
|
+
/* ------------------------------- Wrap Up ------------------------------ */
|
|
193
|
+
/*------------------------------------------------------------------------*/
|
|
194
|
+
|
|
195
|
+
// Export component
|
|
196
|
+
export default SimpleTimeChooser;
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import RadioButton from './components/RadioButton';
|
|
|
15
15
|
import CheckboxButton from './components/CheckboxButton';
|
|
16
16
|
import ButtonInputGroup from './components/ButtonInputGroup';
|
|
17
17
|
import SimpleDateChooser from './components/SimpleDateChooser';
|
|
18
|
+
import SimpleTimeChooser from './components/SimpleTimeChooser';
|
|
18
19
|
import Drawer from './components/Drawer';
|
|
19
20
|
import PopSuccessMark from './components/PopSuccessMark';
|
|
20
21
|
import PopFailureMark from './components/PopFailureMark';
|
|
@@ -133,6 +134,7 @@ export {
|
|
|
133
134
|
CheckboxButton,
|
|
134
135
|
ButtonInputGroup,
|
|
135
136
|
SimpleDateChooser,
|
|
137
|
+
SimpleTimeChooser,
|
|
136
138
|
Drawer,
|
|
137
139
|
PopSuccessMark,
|
|
138
140
|
PopFailureMark,
|
package/src/types/LogSource.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Highest error code =
|
|
1
|
+
// Highest error code = DRK36
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* List of error codes built into the react kit
|
|
@@ -9,6 +9,8 @@ enum ReactKitErrorCode {
|
|
|
9
9
|
NoCode = 'DRK2',
|
|
10
10
|
SessionExpired = 'DRK3',
|
|
11
11
|
NoCACCLSendRequestFunction = 'DRK7',
|
|
12
|
+
SimpleDateChooserInvalidDateRange = 'DRK35',
|
|
13
|
+
SimpleDateChooserInvalidNumMonths = 'DRK36',
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export default ReactKitErrorCode;
|