@oneuptime/common 8.0.5289 → 8.0.5299

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.
@@ -0,0 +1,535 @@
1
+ /** @jest-environment jsdom */
2
+ /*
3
+ * Ensure deterministic timezone for Date#getHours() etc.
4
+ * This must be set before importing the component under test.
5
+ */
6
+ // eslint-disable-next-line no-undef
7
+ process.env.TZ = "UTC";
8
+ import React from "react";
9
+ import { render, screen, within } from "@testing-library/react";
10
+ import userEvent from "@testing-library/user-event";
11
+ import "@testing-library/jest-dom";
12
+ import TimePicker from "../../../../UI/Components/TimePicker/TimePicker";
13
+ import DateUtilities from "../../../../Types/Date";
14
+
15
+ type DateModule = typeof import("../../../../Types/Date");
16
+ type DateLib = DateModule["default"];
17
+ type MockedDateLib = jest.Mocked<DateLib>;
18
+ type UserEventInstance = ReturnType<typeof userEvent.setup>;
19
+ type ChangeHandler = jest.Mock<void, [string | undefined]>;
20
+ type VoidHandler = jest.Mock<void, []>;
21
+ type DialogElement = HTMLElement;
22
+ type ButtonElement = HTMLButtonElement;
23
+ type InputElement = HTMLInputElement;
24
+ type HourMinuteMock = {
25
+ getHours: () => number;
26
+ getMinutes: () => number;
27
+ };
28
+
29
+ // Mock OneUptimeDate utilities used by the component
30
+ jest.mock("../../../../Types/Date", () => {
31
+ const real: DateModule = jest.requireActual("../../../../Types/Date");
32
+ // Helper to create a minimal date-like object with getHours/getMinutes
33
+ const makeHM: (h: number, m: number) => HourMinuteMock = (
34
+ h: number,
35
+ m: number,
36
+ ): HourMinuteMock => {
37
+ return {
38
+ getHours: () => {
39
+ return h;
40
+ },
41
+ getMinutes: () => {
42
+ return m;
43
+ },
44
+ };
45
+ };
46
+ return {
47
+ __esModule: true,
48
+ default: {
49
+ ...real.default,
50
+ getUserPrefers12HourFormat: jest.fn(() => {
51
+ return false;
52
+ }), // default to 24h; tests can override per test
53
+ getCurrentDate: jest.fn(() => {
54
+ return makeHM(13, 45) as unknown as Date;
55
+ }),
56
+ fromString: jest.fn((v: string | Date) => {
57
+ if (!v) {
58
+ return undefined as unknown as Date;
59
+ }
60
+ if (typeof v === "string") {
61
+ const match: RegExpMatchArray | null = v.match(/T(\d{2}):(\d{2})/);
62
+ const hh: number = match ? parseInt(match[1] as string, 10) : 0;
63
+ const mm: number = match ? parseInt(match[2] as string, 10) : 0;
64
+ return makeHM(hh, mm) as unknown as Date;
65
+ }
66
+ // If a Date instance is provided, prefer UTC to avoid env timezone
67
+ const d: Date = v;
68
+ const hasUtcHours: (() => number) | undefined = (
69
+ d as { getUTCHours?: () => number }
70
+ ).getUTCHours;
71
+ const hasUtcMinutes: (() => number) | undefined = (
72
+ d as { getUTCMinutes?: () => number }
73
+ ).getUTCMinutes;
74
+ const hh: number = hasUtcHours ? hasUtcHours.call(d) : d.getHours();
75
+ const mm: number = hasUtcMinutes
76
+ ? hasUtcMinutes.call(d)
77
+ : d.getMinutes();
78
+ return makeHM(hh, mm) as unknown as Date;
79
+ }),
80
+ toString: jest.fn((d: Date) => {
81
+ return d.toISOString();
82
+ }),
83
+ getDateWithCustomTime: jest.fn(
84
+ ({
85
+ hours,
86
+ minutes,
87
+ }: {
88
+ hours: number;
89
+ minutes: number;
90
+ seconds?: number;
91
+ }) => {
92
+ const base: Date = new Date("2024-05-15T00:00:00.000Z");
93
+ base.setUTCHours(hours, minutes, 0, 0);
94
+ return base;
95
+ },
96
+ ),
97
+ getCurrentTimezoneString: jest.fn(() => {
98
+ return "UTC";
99
+ }),
100
+ getCurrentTimezone: jest.fn(() => {
101
+ return "Etc/UTC";
102
+ }),
103
+ },
104
+ };
105
+ });
106
+
107
+ // Mock Icon to avoid SVG complexity
108
+ jest.mock("../../../../UI/Components/Icon/Icon", () => {
109
+ return {
110
+ __esModule: true,
111
+ default: ({ className }: { className?: string }) => {
112
+ return <i data-testid="icon" className={className} />;
113
+ },
114
+ };
115
+ });
116
+
117
+ // Mock Modal to render children immediately and expose submit/close
118
+ jest.mock("../../../../UI/Components/Modal/Modal", () => {
119
+ return {
120
+ __esModule: true,
121
+ default: ({
122
+ title,
123
+ description,
124
+ onClose,
125
+ onSubmit,
126
+ children,
127
+ submitButtonText,
128
+ }: any) => {
129
+ return (
130
+ <div role="dialog" aria-label={title}>
131
+ <div>{description}</div>
132
+ <div>{children}</div>
133
+ <button onClick={onSubmit}>{submitButtonText ?? "Apply"}</button>
134
+ <button onClick={onClose}>Close</button>
135
+ </div>
136
+ );
137
+ },
138
+ ModalWidth: { Medium: "Medium" },
139
+ };
140
+ });
141
+
142
+ const getDateLib: () => MockedDateLib = () => {
143
+ return DateUtilities as MockedDateLib;
144
+ };
145
+
146
+ describe("TimePicker", () => {
147
+ beforeEach(() => {
148
+ // Do not reset implementations provided by jest.mock factory; only clear call history
149
+ jest.clearAllMocks();
150
+ });
151
+
152
+ it("renders in 24h by default and shows current time", () => {
153
+ const onChange: ChangeHandler = jest.fn();
154
+ render(<TimePicker value="2024-05-15T08:05:00.000Z" onChange={onChange} />);
155
+
156
+ // Should display HH:mm based on value prop
157
+ expect(screen.getByLabelText("Hours")).toHaveValue("08");
158
+ expect(screen.getByLabelText("Minutes")).toHaveValue("05");
159
+
160
+ // AM/PM buttons are not shown in 24h
161
+ expect(
162
+ screen.queryByRole("button", { name: "AM" }),
163
+ ).not.toBeInTheDocument();
164
+ expect(
165
+ screen.queryByRole("button", { name: "PM" }),
166
+ ).not.toBeInTheDocument();
167
+ });
168
+
169
+ it("opens modal on click when enabled", async () => {
170
+ const user: UserEventInstance = userEvent.setup();
171
+ render(<TimePicker value="2024-05-15T10:20:00.000Z" />);
172
+
173
+ // Click the field container by clicking on hours input
174
+ await user.click(screen.getByLabelText("Hours"));
175
+
176
+ // Modal should appear
177
+ expect(
178
+ screen.getByRole("dialog", { name: "Select time" }),
179
+ ).toBeInTheDocument();
180
+ expect(screen.getByText(/your UTC/i)).toBeInTheDocument();
181
+ });
182
+
183
+ it("does not open modal when readOnly or disabled", async () => {
184
+ const user: UserEventInstance = userEvent.setup();
185
+ const { rerender } = render(
186
+ <TimePicker value="2024-05-15T10:20:00.000Z" readOnly />,
187
+ );
188
+
189
+ await user.click(screen.getByLabelText("Hours"));
190
+ expect(
191
+ screen.queryByRole("dialog", { name: "Select time" }),
192
+ ).not.toBeInTheDocument();
193
+
194
+ rerender(<TimePicker value="2024-05-15T10:20:00.000Z" disabled />);
195
+ await user.click(screen.getByLabelText("Minutes"));
196
+ expect(
197
+ screen.queryByRole("dialog", { name: "Select time" }),
198
+ ).not.toBeInTheDocument();
199
+ });
200
+
201
+ it("applies changes from modal and emits ISO via onChange (24h)", async () => {
202
+ const user: UserEventInstance = userEvent.setup();
203
+ const onChange: ChangeHandler = jest.fn();
204
+ render(<TimePicker value="2024-05-15T08:05:00.000Z" onChange={onChange} />);
205
+
206
+ // Open modal
207
+ await user.click(screen.getByLabelText("Hours"));
208
+ const dialog: DialogElement = screen.getByRole("dialog", {
209
+ name: "Select time",
210
+ });
211
+
212
+ // Increase hours and minutes using the chevrons
213
+ const incHour: ButtonElement = within(dialog).getByLabelText(
214
+ "Increase hours",
215
+ ) as HTMLButtonElement;
216
+ const incMin: ButtonElement = within(dialog).getByLabelText(
217
+ "Increase minutes",
218
+ ) as HTMLButtonElement;
219
+
220
+ await user.click(incHour); // 08 -> 09
221
+ await user.click(incMin); // 05 -> 06
222
+
223
+ // Apply
224
+ await user.click(
225
+ within(dialog).getByRole("button", {
226
+ name: "Apply",
227
+ }),
228
+ );
229
+
230
+ // onChange should be called with ISO string
231
+ expect(onChange).toHaveBeenCalledTimes(1);
232
+ const emittedCall: [string | undefined] | undefined =
233
+ onChange.mock.calls[0];
234
+ expect(emittedCall).toBeDefined();
235
+ const emitted: string = (emittedCall as [string])[0];
236
+ expect(typeof emitted).toBe("string");
237
+
238
+ const lib: MockedDateLib = getDateLib();
239
+ // getDateWithCustomTime uses UTC hours in our mock; 9:06 maps to 09:06:00Z on the chosen date
240
+ expect(lib.getDateWithCustomTime).toHaveBeenCalledWith({
241
+ hours: 9,
242
+ minutes: 6,
243
+ seconds: 0,
244
+ });
245
+ });
246
+
247
+ it("supports decrement wrapping for hours and minutes (24h)", async () => {
248
+ const user: UserEventInstance = userEvent.setup();
249
+ const onChange: ChangeHandler = jest.fn();
250
+ render(<TimePicker value="2024-05-15T00:00:00.000Z" onChange={onChange} />);
251
+
252
+ await user.click(screen.getByLabelText("Hours"));
253
+ const dialog: DialogElement = screen.getByRole("dialog", {
254
+ name: "Select time",
255
+ });
256
+
257
+ const decHour: ButtonElement = within(dialog).getByLabelText(
258
+ "Decrease hours",
259
+ ) as HTMLButtonElement;
260
+ const decMin: ButtonElement = within(dialog).getByLabelText(
261
+ "Decrease minutes",
262
+ ) as HTMLButtonElement;
263
+
264
+ // Minutes 00 -> 59 and hours 00 -> 23 when decreasing
265
+ await user.click(decMin);
266
+ await user.click(decHour);
267
+
268
+ await user.click(
269
+ within(dialog).getByRole("button", {
270
+ name: "Apply",
271
+ }),
272
+ );
273
+
274
+ const lib: MockedDateLib = getDateLib();
275
+ // dec minute first -> 00 -> 59, hours 0->23, then dec hour -> 22
276
+ expect(lib.getDateWithCustomTime).toHaveBeenCalledWith({
277
+ hours: 22,
278
+ minutes: 59,
279
+ seconds: 0,
280
+ });
281
+ });
282
+
283
+ it("renders and operates in 12h mode with AM/PM toggles", async () => {
284
+ const user: UserEventInstance = userEvent.setup();
285
+ const lib: MockedDateLib = getDateLib();
286
+ lib.getUserPrefers12HourFormat.mockReturnValue(true);
287
+
288
+ const onChange: ChangeHandler = jest.fn();
289
+ render(<TimePicker value="2024-05-15T13:45:00.000Z" onChange={onChange} />);
290
+
291
+ // Displays 01:45 PM
292
+ expect(screen.getByLabelText("Hours")).toHaveValue("01");
293
+ const apButtons: HTMLElement[] = screen.getAllByRole("button", {
294
+ name: "Open time selector for AM/PM",
295
+ });
296
+ expect(apButtons).toHaveLength(2);
297
+
298
+ await user.click(screen.getByLabelText("Hours"));
299
+ const dialog: DialogElement = screen.getByRole("dialog", {
300
+ name: "Select time",
301
+ });
302
+
303
+ // Modal description should reflect 12h mode
304
+ expect(
305
+ within(dialog).getByText(/choose hours, minutes, and AM\/PM/i),
306
+ ).toBeInTheDocument();
307
+
308
+ // Toggle to AM and change hour input to 12 to map to 00
309
+ await user.click(
310
+ within(dialog).getByRole("button", { name: /^AM$/ }) as HTMLButtonElement,
311
+ );
312
+ const hourInput: InputElement = within(dialog).getByLabelText(
313
+ "Hours",
314
+ ) as InputElement;
315
+ // Change to 12
316
+ await user.clear(hourInput);
317
+ await user.type(hourInput, "12");
318
+
319
+ await user.click(
320
+ within(dialog).getByRole("button", {
321
+ name: "Apply",
322
+ }),
323
+ );
324
+
325
+ // Should map to hours 0 in 24h
326
+ expect(lib.getDateWithCustomTime).toHaveBeenCalledWith({
327
+ hours: 0,
328
+ minutes: 45,
329
+ seconds: 0,
330
+ });
331
+ });
332
+
333
+ it("AM/PM button mapping inside modal", async () => {
334
+ const user: UserEventInstance = userEvent.setup();
335
+ const lib: MockedDateLib = getDateLib();
336
+ lib.getUserPrefers12HourFormat.mockReturnValue(true);
337
+
338
+ render(<TimePicker value="2024-05-15T01:10:00.000Z" />);
339
+
340
+ await user.click(screen.getByLabelText("Hours"));
341
+ const dialog: DialogElement = screen.getByRole("dialog", {
342
+ name: "Select time",
343
+ });
344
+ // Click PM, should add 12 hours (1 -> 13)
345
+ await user.click(
346
+ within(dialog).getByRole("button", { name: /^PM$/ }) as HTMLButtonElement,
347
+ );
348
+
349
+ // Increase minutes to 11 to ensure state changed
350
+ await user.click(
351
+ within(dialog).getByLabelText("Increase minutes") as HTMLButtonElement,
352
+ );
353
+
354
+ await user.click(
355
+ within(dialog).getByRole("button", {
356
+ name: "Apply",
357
+ }),
358
+ );
359
+
360
+ expect(lib.getDateWithCustomTime).toHaveBeenCalledWith({
361
+ hours: 13,
362
+ minutes: 11,
363
+ seconds: 0,
364
+ });
365
+ });
366
+
367
+ it("quick minutes buttons set minutes", async () => {
368
+ const user: UserEventInstance = userEvent.setup();
369
+ const onChange: ChangeHandler = jest.fn();
370
+ render(<TimePicker value="2024-05-15T08:05:00.000Z" onChange={onChange} />);
371
+
372
+ await user.click(screen.getByLabelText("Hours"));
373
+ const dialog: DialogElement = screen.getByRole("dialog", {
374
+ name: "Select time",
375
+ });
376
+
377
+ await user.click(
378
+ within(dialog).getByRole("button", { name: "05" }) as HTMLButtonElement,
379
+ );
380
+ await user.click(
381
+ within(dialog).getByRole("button", {
382
+ name: "Apply",
383
+ }) as HTMLButtonElement,
384
+ );
385
+
386
+ const lib: MockedDateLib = getDateLib();
387
+ expect(lib.getDateWithCustomTime).toHaveBeenCalledWith({
388
+ hours: 8,
389
+ minutes: 5,
390
+ seconds: 0,
391
+ });
392
+ });
393
+
394
+ it("respects placeholder in 24h and 12h modes", () => {
395
+ const lib: MockedDateLib = getDateLib();
396
+ lib.getUserPrefers12HourFormat.mockReturnValue(false);
397
+ const { unmount } = render(<TimePicker placeholder="HH" />);
398
+ expect(screen.getByLabelText("Hours")).toHaveAttribute("placeholder", "HH");
399
+
400
+ lib.getUserPrefers12HourFormat.mockReturnValue(true);
401
+ unmount();
402
+ render(<TimePicker />);
403
+ expect(screen.getByLabelText("Hours")).toHaveAttribute("placeholder", "hh");
404
+ });
405
+
406
+ it("shows error icon and message when error prop is set", () => {
407
+ render(<TimePicker error="Required" />);
408
+
409
+ expect(screen.getByTestId("error-message")).toHaveTextContent("Required");
410
+ // Error icon rendered
411
+ expect(
412
+ screen.getAllByTestId("icon").some((iconEl: HTMLElement) => {
413
+ return iconEl.className?.includes("text-red-500");
414
+ }),
415
+ ).toBeTruthy();
416
+ });
417
+
418
+ it("calls onFocus and onBlur from the hours input", async () => {
419
+ const user: UserEventInstance = userEvent.setup();
420
+ const onFocus: VoidHandler = jest.fn();
421
+ const onBlur: VoidHandler = jest.fn();
422
+
423
+ render(<TimePicker onFocus={onFocus} onBlur={onBlur} />);
424
+
425
+ const hours: InputElement = screen.getByLabelText("Hours") as InputElement;
426
+ await user.click(hours);
427
+ expect(onFocus).toHaveBeenCalled();
428
+
429
+ hours.blur();
430
+ expect(onBlur).toHaveBeenCalled();
431
+ });
432
+
433
+ it("updates when value prop changes", () => {
434
+ // Force 24h mode for this test to avoid bleed from prior tests
435
+ const lib: MockedDateLib = getDateLib();
436
+ lib.getUserPrefers12HourFormat.mockReturnValue(false);
437
+
438
+ const { rerender } = render(
439
+ <TimePicker value="2024-05-15T02:03:00.000Z" />,
440
+ );
441
+ expect(screen.getByLabelText("Hours")).toHaveValue("02");
442
+ expect(screen.getByLabelText("Minutes")).toHaveValue("03");
443
+
444
+ rerender(<TimePicker value="2024-05-15T21:59:00.000Z" />);
445
+ expect(screen.getByLabelText("Hours")).toHaveValue("21");
446
+ expect(screen.getByLabelText("Minutes")).toHaveValue("59");
447
+ });
448
+
449
+ it("clamps and maps hour text edits inside modal for 12h", async () => {
450
+ const user: UserEventInstance = userEvent.setup();
451
+ const lib: MockedDateLib = getDateLib();
452
+ lib.getUserPrefers12HourFormat.mockReturnValue(true);
453
+
454
+ render(<TimePicker value="2024-05-15T12:00:00.000Z" />);
455
+
456
+ await user.click(screen.getByLabelText("Hours"));
457
+ const dialog: DialogElement = screen.getByRole("dialog", {
458
+ name: "Select time",
459
+ });
460
+
461
+ const hourInput: InputElement = within(dialog).getByLabelText(
462
+ "Hours",
463
+ ) as InputElement;
464
+ await user.clear(hourInput);
465
+ await user.type(hourInput, "99"); // should clamp to 12 in 12h mode
466
+
467
+ await user.click(
468
+ within(dialog).getByRole("button", {
469
+ name: "Apply",
470
+ }),
471
+ );
472
+
473
+ // 12 PM stays 12 (i.e., 12 in 24h), with minutes from initial value 00
474
+ expect(lib.getDateWithCustomTime).toHaveBeenCalledWith({
475
+ hours: 12,
476
+ minutes: 0,
477
+ seconds: 0,
478
+ });
479
+ });
480
+
481
+ it("minute text edits clamp to 0-59", async () => {
482
+ const user: UserEventInstance = userEvent.setup();
483
+ render(<TimePicker value="2024-05-15T10:10:00.000Z" />);
484
+
485
+ await user.click(screen.getByLabelText("Hours"));
486
+ const dialog: DialogElement = screen.getByRole("dialog", {
487
+ name: "Select time",
488
+ });
489
+
490
+ const minInput: InputElement = within(dialog).getByLabelText(
491
+ "Minutes",
492
+ ) as InputElement;
493
+ await user.clear(minInput);
494
+ await user.type(minInput, "99");
495
+
496
+ await user.click(
497
+ within(dialog).getByRole("button", {
498
+ name: "Apply",
499
+ }),
500
+ );
501
+
502
+ const lib: MockedDateLib = getDateLib();
503
+ expect(lib.getDateWithCustomTime).toHaveBeenCalledWith({
504
+ hours: 10,
505
+ minutes: 59,
506
+ seconds: 0,
507
+ });
508
+ });
509
+
510
+ it("modal Close does not emit change or update main display", async () => {
511
+ const user: UserEventInstance = userEvent.setup();
512
+ const onChange: ChangeHandler = jest.fn();
513
+ render(<TimePicker value="2024-05-15T08:05:00.000Z" onChange={onChange} />);
514
+
515
+ // Open modal, change something, then close
516
+ await user.click(screen.getByLabelText("Hours"));
517
+ const dialog: DialogElement = screen.getByRole("dialog", {
518
+ name: "Select time",
519
+ });
520
+ await user.click(
521
+ within(dialog).getByLabelText("Increase hours") as HTMLButtonElement,
522
+ );
523
+ await user.click(
524
+ within(dialog).getByRole("button", {
525
+ name: "Close",
526
+ }) as HTMLButtonElement,
527
+ );
528
+
529
+ // No onChange called
530
+ expect(onChange).not.toHaveBeenCalled();
531
+
532
+ // Still shows original value
533
+ expect(screen.getByLabelText("Hours")).toHaveValue("08");
534
+ });
535
+ });
@@ -17,7 +17,7 @@ import Select from "../../../Types/BaseDatabase/Select";
17
17
  export interface ComponentProps<TBaseModel extends BaseModel> {
18
18
  modelType: { new (): TBaseModel };
19
19
  modelId: ObjectID;
20
- onDuplicateSuccess?: (item: TBaseModel) => void | undefined;
20
+ onDuplicateSuccess?: (item: TBaseModel) => Promise<void> | void;
21
21
  fieldsToDuplicate: Select<TBaseModel>;
22
22
  fieldsToChange: Array<ModelField<TBaseModel>>;
23
23
  navigateToOnSuccess?: Route | undefined;
@@ -78,7 +78,9 @@ const DuplicateModel: <TBaseModel extends BaseModel>(
78
78
  throw new Error(`Could not create ${model.singularName}`);
79
79
  }
80
80
 
81
- props.onDuplicateSuccess?.(newItem.data);
81
+ if (props.onDuplicateSuccess) {
82
+ await props.onDuplicateSuccess(newItem.data);
83
+ }
82
84
 
83
85
  if (props.navigateToOnSuccess) {
84
86
  Navigation.navigate(
@@ -9,6 +9,7 @@ import DictionaryForm from "../../Dictionary/Dictionary";
9
9
  import Dropdown, { DropdownValue } from "../../Dropdown/Dropdown";
10
10
  import FilePicker from "../../FilePicker/FilePicker";
11
11
  import Input, { InputType } from "../../Input/Input";
12
+ import TimePicker from "../../TimePicker/Index";
12
13
  import Link from "../../Link/Link";
13
14
  import Modal from "../../Modal/Modal";
14
15
  import IDGenerator from "../../ObjectID/IDGenerator";
@@ -280,6 +281,31 @@ const FormField: <T extends GenericObject>(
280
281
  )}
281
282
 
282
283
  <div className="mt-2">
284
+ {/* Time Picker */}
285
+ {props.field.fieldType === FormFieldSchemaType.Time && (
286
+ <TimePicker
287
+ autoFocus={!props.disableAutofocus && index === 1}
288
+ tabIndex={index}
289
+ disabled={props.isDisabled || props.field.disabled}
290
+ error={props.touched && props.error ? props.error : undefined}
291
+ dataTestId={props.field.dataTestId}
292
+ onChange={async (value: string) => {
293
+ onChange(value);
294
+ props.setFieldValue(props.fieldName, value);
295
+ }}
296
+ onBlur={async () => {
297
+ props.setFieldTouched(props.fieldName, true);
298
+ }}
299
+ value={
300
+ (props.currentValues &&
301
+ (props.currentValues as any)[props.fieldName]) ||
302
+ (props.field.defaultValue as any) ||
303
+ undefined
304
+ }
305
+ placeholder={props.field.placeholder || undefined}
306
+ />
307
+ )}
308
+
283
309
  {props.field.fieldType === FormFieldSchemaType.Color && (
284
310
  <ColorPicker
285
311
  error={props.touched && props.error ? props.error : undefined}
@@ -70,17 +70,13 @@ const Input: FunctionComponent<ComponentProps> = (
70
70
  useEffect(() => {
71
71
  if (
72
72
  props.type === InputType.DATE ||
73
- props.type === InputType.DATETIME_LOCAL ||
74
- props.type === InputType.TIME
73
+ props.type === InputType.DATETIME_LOCAL
75
74
  ) {
76
75
  if (value && (value as unknown) instanceof Date) {
77
76
  let dateString: string = "";
78
77
  try {
79
78
  if (props.type === InputType.DATETIME_LOCAL) {
80
79
  dateString = OneUptimeDate.toDateTimeLocalString(value as any);
81
- } else if (props.type === InputType.TIME) {
82
- // get time from date
83
- dateString = OneUptimeDate.toTimeString(value as any);
84
80
  } else {
85
81
  dateString = OneUptimeDate.asDateForDatabaseQuery(value);
86
82
  }
@@ -99,9 +95,6 @@ const Input: FunctionComponent<ComponentProps> = (
99
95
  try {
100
96
  if (props.type === InputType.DATETIME_LOCAL) {
101
97
  dateString = OneUptimeDate.toDateTimeLocalString(date);
102
- } else if (props.type === InputType.TIME) {
103
- // get time from date
104
- dateString = OneUptimeDate.toTimeString(value as any);
105
98
  } else {
106
99
  dateString = OneUptimeDate.asDateForDatabaseQuery(date);
107
100
  }
@@ -161,25 +154,15 @@ const Input: FunctionComponent<ComponentProps> = (
161
154
  onFocus={props.onFocus}
162
155
  onClick={props.onClick}
163
156
  data-testid={props.dataTestId}
164
- spellCheck={!props.disableSpellCheck && props.type === InputType.TEXT}
157
+ spellCheck={!props.disableSpellCheck}
165
158
  onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
166
- let value: string | Date = e.target.value;
159
+ const value: string | Date = e.target.value;
167
160
 
168
161
  if (
169
162
  (props.type === InputType.DATE ||
170
- props.type === InputType.DATETIME_LOCAL ||
171
- props.type === InputType.TIME) &&
163
+ props.type === InputType.DATETIME_LOCAL) &&
172
164
  value
173
165
  ) {
174
- if (props.type === InputType.TIME) {
175
- // conver value like "16:00" to date with local timezone
176
- value = OneUptimeDate.getDateWithCustomTime({
177
- hours: parseInt(value.split(":")[0]?.toString() || "0"),
178
- minutes: parseInt(value.split(":")[1]?.toString() || "0"),
179
- seconds: 0,
180
- });
181
- }
182
-
183
166
  const date: Date = OneUptimeDate.fromString(value);
184
167
  const dateString: string = OneUptimeDate.toString(date);
185
168
  setValue(dateString);
@@ -0,0 +1,3 @@
1
+ import TimePicker from "./TimePicker";
2
+
3
+ export default TimePicker;