-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #18 from Jaspersoft/date-time-ic
DateTime Input Control
- Loading branch information
Showing
10 changed files
with
449 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
packages/jv-input-controls/src/controls/DateTimePickerInputControl.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import { DateTimePicker as JVDateTimePicker } from "@jaspersoft/jv-ui-components/material-ui/DateTime/DateTimePicker"; | ||
import { | ||
BaseInputControlProps, | ||
ICDateValidationRule, | ||
} from "./BaseInputControl"; | ||
import { useControlClasses } from "./hooks/useControlClasses"; | ||
import { useLiveDateFormattedState } from "./hooks/useLiveDateFormattedState"; | ||
|
||
export type DateTimeICType = "datetime"; | ||
|
||
export interface DateTimeICProps extends BaseInputControlProps { | ||
value?: string; | ||
className?: string; | ||
views?: Array<"year" | "month" | "day" | "hours" | "minutes" | "seconds">; | ||
disabled?: boolean; | ||
} | ||
|
||
const removeSingleQuotes = (str: string) => str.replace(/'/g, ""); | ||
const formatToDayJS = (str: string) => { | ||
const separator = str.includes("T") ? "T" : " "; | ||
const [date, time] = str.split(separator); | ||
return `${date.toUpperCase()}${separator}${time}`; | ||
}; | ||
|
||
export const DateTimePickerInputControl = (props: DateTimeICProps) => { | ||
let dateFormat, | ||
views: string[] = []; | ||
if (props.validationRules !== undefined) { | ||
const [rule] = props.validationRules as ICDateValidationRule[]; | ||
dateFormat = removeSingleQuotes(rule.dateTimeFormatValidationRule.format); | ||
dateFormat = formatToDayJS(dateFormat); | ||
} | ||
views = props.views | ||
? props.views | ||
: ["year", "month", "day", "hours", "minutes", "seconds"]; | ||
const liveState = useLiveDateFormattedState({ | ||
initialValue: props.state?.value || props.value || "", | ||
format: dateFormat, | ||
}); | ||
const controlClasses = useControlClasses([], props); | ||
return ( | ||
<JVDateTimePicker | ||
{...props} | ||
onChange={liveState.onChange} | ||
value={liveState.value} | ||
views={views} | ||
className={`${controlClasses.join(" ")} ${props.className || ""}`} | ||
timeSteps={{ hours: 1, minutes: 1, seconds: 1 }} | ||
/> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
packages/jv-input-controls/test/DateTimePickerInputControl.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { DatePickerProvider as JVDatePickerProvider } from "@jaspersoft/jv-ui-components/material-ui/Date/DatePickerProvider"; | ||
import { fireEvent, render, screen } from "@testing-library/react"; | ||
import "@testing-library/jest-dom"; | ||
import * as React from "react"; | ||
import { DateTimePickerInputControl } from "../src/controls/DateTimePickerInputControl"; | ||
|
||
const requiredProps = { | ||
id: "column_timestamp_1", | ||
label: "column_timestamp", | ||
mandatory: false, | ||
readOnly: false, | ||
visible: true, | ||
type: "singleValueDatetime", | ||
}; | ||
|
||
const getDateTimePickerIC = (options?: any): React.JSX.Element => { | ||
const mergedProps = { ...requiredProps, ...options }; | ||
return ( | ||
<JVDatePickerProvider> | ||
<DateTimePickerInputControl {...mergedProps} /> | ||
</JVDatePickerProvider> | ||
); | ||
}; | ||
|
||
describe("DateTimePickerInputControl tests", () => { | ||
test("DateTimePickerInputControl is rendered correctly", () => { | ||
render(getDateTimePickerIC({ value: "2014-09-12T15:46:18" })); | ||
const datePickerElement = screen.getByRole("textbox"); | ||
expect(datePickerElement).toBeInTheDocument(); | ||
}); | ||
|
||
test("displays the label when provided", () => { | ||
const testLabel = "Test Label"; | ||
render(getDateTimePickerIC({ label: testLabel })); | ||
const labelElement = screen.queryByLabelText(testLabel); | ||
expect(labelElement).toBeInTheDocument(); | ||
}); | ||
|
||
test("value is converted to AM/PM format", () => { | ||
render(getDateTimePickerIC({ value: "2014-09-14T15:46:18" })); | ||
const inputElement = screen.getByRole("textbox") as HTMLInputElement; | ||
expect(inputElement.value).toBe("09/14/2014 03:46:18 PM"); | ||
}); | ||
|
||
test("check the component is read-only", () => { | ||
// Render the component | ||
const { rerender } = render(getDateTimePickerIC({ readOnly: true })); | ||
let inputElement = screen.getByRole("textbox") as HTMLInputElement; | ||
|
||
// Assert that the element is found and has the expected attribute | ||
expect(inputElement).toBeInTheDocument(); | ||
expect(inputElement).toHaveAttribute("readonly"); | ||
|
||
rerender(getDateTimePickerIC({})); | ||
inputElement = screen.getByRole("textbox") as HTMLInputElement; | ||
expect(inputElement).not.toHaveAttribute("readonly"); | ||
}); | ||
|
||
test("check the component is visible or not", () => { | ||
const HIDDEN_CLASS_NAME = "jv-uVisibility-hide"; | ||
// Render the component | ||
const { container } = render(getDateTimePickerIC({ visible: false })); | ||
// Use querySelector to get the first div with the class "jv-mInputLarge" | ||
const divElement = container.querySelector(`div.${HIDDEN_CLASS_NAME}`); | ||
|
||
// Assert that the element is found and has the expected class | ||
expect(divElement).toBeInTheDocument(); | ||
expect(divElement).toHaveClass(HIDDEN_CLASS_NAME); | ||
}); | ||
|
||
test("check the component is disabled", () => { | ||
// Render the component | ||
const { rerender } = render(getDateTimePickerIC({ disabled: true })); | ||
let inputElement = screen.getByRole("textbox") as HTMLInputElement; | ||
|
||
// Assert that the element is found and has the expected attribute | ||
expect(inputElement).toBeInTheDocument(); | ||
expect(inputElement).toHaveAttribute("disabled"); | ||
|
||
rerender(getDateTimePickerIC({})); | ||
inputElement = screen.getByRole("textbox") as HTMLInputElement; | ||
expect(inputElement).not.toHaveAttribute("disabled"); | ||
}); | ||
}); |
50 changes: 50 additions & 0 deletions
50
packages/jv-input-controls/test/hooks/useLiveDateFormattedState.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
* Copyright © 2005-2024. Cloud Software Group, Inc. All rights reserved. Confidential & Proprietary. | ||
* Licensed pursuant to commercial Cloud Software Group, Inc End User License Agreement. | ||
*/ | ||
|
||
import { useLiveDateFormattedState } from "../../src/controls/hooks/useLiveDateFormattedState"; | ||
import { renderHook } from "@testing-library/react"; | ||
|
||
describe("useLiveState hook tests", () => { | ||
const initialValue = "2024-07-08"; | ||
|
||
it("should store initial value", () => { | ||
const { result } = renderHook(() => | ||
useLiveDateFormattedState({ initialValue }), | ||
); | ||
expect(result.current.value).toBe(initialValue); | ||
}); | ||
it("should return 2 fields", () => { | ||
const { result } = renderHook(() => | ||
useLiveDateFormattedState({ initialValue }), | ||
); | ||
expect(Object.keys(result.current).length).toBe(2); | ||
}); | ||
it("should return expected fields: value, onChange", () => { | ||
const { result } = renderHook(() => | ||
useLiveDateFormattedState({ initialValue }), | ||
); | ||
expect(result.current.value).toBeDefined(); | ||
expect(result.current.onChange).toBeDefined(); | ||
expect(result.current.onChange instanceof Function).toBeTruthy(); | ||
}); | ||
it("should return same date even though a datetime format is provided", () => { | ||
const dateTimeFormat = "YYYY-MM-DDTHH:mm:ss"; | ||
const { result } = renderHook(() => | ||
useLiveDateFormattedState({ format: dateTimeFormat, initialValue }), | ||
); | ||
expect(result.current.value).toBe(initialValue); | ||
}); | ||
it("should return a datetime value", () => { | ||
const dateTimeFormat = "YYYY-MM-DDTHH:mm:ss", | ||
dateTimeValue = "2014-09-12T15:46:18"; | ||
const { result } = renderHook(() => | ||
useLiveDateFormattedState({ | ||
format: dateTimeFormat, | ||
initialValue: dateTimeValue, | ||
}), | ||
); | ||
expect(result.current.value).toBe(dateTimeValue); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* Copyright © 2005-2024. Cloud Software Group, Inc. All rights reserved. Confidential & Proprietary. | ||
* Licensed pursuant to commercial Cloud Software Group, Inc End User License Agreement. | ||
*/ | ||
|
||
import dayjs from "dayjs"; | ||
|
||
const castValueIfNeeded = (theValue: dayjs.Dayjs): dayjs.Dayjs => { | ||
return theValue instanceof dayjs ? theValue : dayjs(theValue); | ||
}; | ||
|
||
export default castValueIfNeeded; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
packages/jv-ui-components/material-ui/DateTime/DateTimePicker.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { DateTimePicker as MuiDateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; | ||
import { forwardRef } from "react"; | ||
import castValueIfNeeded from "../Date/Date.Utils"; | ||
|
||
export const DateTimePicker = forwardRef((props: any, ref) => { | ||
const { value, ...remainingProps } = props; | ||
|
||
let otherProps = {}; | ||
if (value) { | ||
otherProps = { value: castValueIfNeeded(value) }; | ||
} | ||
return <MuiDateTimePicker {...{ ...remainingProps, ...otherProps }} />; | ||
}); |
Oops, something went wrong.