diff --git a/frontend/src/metabase/components/Calendar.tsx b/frontend/src/metabase/components/Calendar.tsx index da9015013b49a129c63122f18a364e164da3beee..7f8e5ded4f29e460033a993627c4a562e5053860 100644 --- a/frontend/src/metabase/components/Calendar.tsx +++ b/frontend/src/metabase/components/Calendar.tsx @@ -1,4 +1,3 @@ -/* eslint-disable react/prop-types */ import React, { Component } from "react"; import cx from "classnames"; import moment, { Moment } from "moment-timezone"; @@ -13,7 +12,7 @@ import { CalendarDay } from "./Calendar.styled"; export type SelectAll = "after" | "before"; -type Props = { +export type CalendarProps = { initial?: Moment; selected?: Moment; selectedEnd?: Moment; @@ -33,8 +32,8 @@ type State = { current?: Moment; }; -export default class Calendar extends Component<Props, State> { - constructor(props: Props) { +export default class Calendar extends Component<CalendarProps, State> { + constructor(props: CalendarProps) { super(props); this.state = { current: moment(props.initial || undefined), @@ -45,7 +44,7 @@ export default class Calendar extends Component<Props, State> { isRangePicker: true, }; - UNSAFE_componentWillReceiveProps(nextProps: Props) { + UNSAFE_componentWillReceiveProps(nextProps: CalendarProps) { if ( // `selected` became null or not null (nextProps.selected == null) !== (this.props.selected == null) || @@ -158,6 +157,11 @@ export default class Calendar extends Component<Props, State> { const firstDayOfWeek = getFirstDayOfWeekIndex(); const date = moment(current).startOf("month").isoWeekday(firstDayOfWeek); + // if set week doesn't start with 1st day of month, then add the previous week + if (date.date() > 1) { + date.add(-1, "w"); + } + let done = false; let monthIndex = date.month(); let count = 0; diff --git a/frontend/src/metabase/components/Calendar.unit.spec.tsx b/frontend/src/metabase/components/Calendar.unit.spec.tsx index e27a53ea4f2b87b1086b253cfe0e26624c90265e..28aef2c25016958b5ff1ec0e5d597f96d9860555 100644 --- a/frontend/src/metabase/components/Calendar.unit.spec.tsx +++ b/frontend/src/metabase/components/Calendar.unit.spec.tsx @@ -1,10 +1,48 @@ import React from "react"; +import moment from "moment-timezone"; +import mockDate from "mockdate"; +import userEvent from "@testing-library/user-event"; import { render, screen } from "__support__/ui"; + import MetabaseSettings from "metabase/lib/settings"; import { updateMomentStartOfWeek } from "metabase/lib/i18n"; -import Calendar from "./Calendar"; +import Calendar, { CalendarProps } from "./Calendar"; describe("Calendar", () => { + afterEach(() => { + mockDate.reset(); + }); + + it("should switch months correctly", () => { + mockDate.set("2018-01-12T12:00:00Z", 0); + setup({ selected: moment("2018-01-01") }); + + const PREVIOUS = screen.getByRole("img", { name: /chevronleft icon/i }); + const NEXT = screen.getByRole("img", { name: /chevronright icon/i }); + + expect(screen.getByText("January 2018")).toBeInTheDocument(); + + userEvent.click(PREVIOUS); + expect(screen.getByText("December 2017")).toBeInTheDocument(); + + userEvent.click(NEXT); + userEvent.click(NEXT); + expect(screen.getByText("February 2018")).toBeInTheDocument(); + }); + + it("should render all days of current month by default", () => { + mockDate.set("2023-03-31T12:00:00Z", 0); + setup(); + + // check that listed dates are correct + expect(screen.getByTestId("calendar-weeks")).toHaveTextContent( + [ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + ].join(""), // days in March 2023 + ); + }); + it("should render weekday short names", () => { setup(); @@ -51,6 +89,6 @@ describe("Calendar", () => { }); }); -function setup() { - return render(<Calendar />); +function setup(props?: Partial<CalendarProps>) { + return render(<Calendar {...props} />); } diff --git a/frontend/test/metabase/components/Calendar.unit.spec.js b/frontend/test/metabase/components/Calendar.unit.spec.js deleted file mode 100644 index 8151b26d8a1ad7e409e38d3922004f7617ddee2b..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/components/Calendar.unit.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; -import moment from "moment-timezone"; -import mockDate from "mockdate"; - -import { render, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; - -import Calendar from "metabase/components/Calendar"; - -describe("Calendar", () => { - afterEach(() => { - mockDate.reset(); - }); - - it("should switch months correctly", () => { - mockDate.set("2018-01-12T12:00:00Z", 0); - render(<Calendar selected={moment("2018-01-01")} onChange={() => {}} />); - - const PREVIOUS = screen.getByRole("img", { name: /chevronleft icon/i }); - const NEXT = screen.getByRole("img", { name: /chevronright icon/i }); - - expect(screen.getByText("January 2018")).toBeInTheDocument(); - - userEvent.click(PREVIOUS); - expect(screen.getByText("December 2017")).toBeInTheDocument(); - - userEvent.click(NEXT); - userEvent.click(NEXT); - expect(screen.getByText("February 2018")).toBeInTheDocument(); - }); -});