From cb69cc44602f2254087789e9ea80e2207fa488a3 Mon Sep 17 00:00:00 2001 From: Ariya Hidayat <ariya@metabase.com> Date: Wed, 11 May 2022 09:40:07 -0700 Subject: [PATCH] Improve YearPicker component (#22603) * migrate to TypeScript, add type annotations * include props definition * support Storybook * add a basic unit test --- .../YearPicker/YearPicker.stories.tsx | 24 +++++++++++++++++ .../components/YearPicker/YearPicker.tsx | 26 +++++++++++++++++++ .../YearPicker/YearPicker.unit.spec.tsx | 11 ++++++++ .../metabase/components/YearPicker/index.tsx | 1 + .../widgets/DateMonthYearWidget.jsx | 5 ++-- .../widgets/DateQuarterYearWidget.jsx | 5 ++-- .../components/widgets/YearPicker.jsx | 20 -------------- 7 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 frontend/src/metabase/components/YearPicker/YearPicker.stories.tsx create mode 100644 frontend/src/metabase/components/YearPicker/YearPicker.tsx create mode 100644 frontend/src/metabase/components/YearPicker/YearPicker.unit.spec.tsx create mode 100644 frontend/src/metabase/components/YearPicker/index.tsx delete mode 100644 frontend/src/metabase/parameters/components/widgets/YearPicker.jsx diff --git a/frontend/src/metabase/components/YearPicker/YearPicker.stories.tsx b/frontend/src/metabase/components/YearPicker/YearPicker.stories.tsx new file mode 100644 index 00000000000..77824720b5b --- /dev/null +++ b/frontend/src/metabase/components/YearPicker/YearPicker.stories.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import { ComponentStory } from "@storybook/react"; +import { useArgs } from "@storybook/client-api"; +import YearPicker from "./YearPicker"; + +export default { + title: "Parameters/YearPicker", + component: YearPicker, +}; + +const Template: ComponentStory<typeof YearPicker> = args => { + const [{ value }, updateArgs] = useArgs(); + + const handleChange = (year: number) => { + updateArgs({ value: year }); + }; + + return <YearPicker {...args} value={value} onChange={handleChange} />; +}; + +export const Default = Template.bind({}); +Default.args = { + value: 2022, +}; diff --git a/frontend/src/metabase/components/YearPicker/YearPicker.tsx b/frontend/src/metabase/components/YearPicker/YearPicker.tsx new file mode 100644 index 00000000000..42f502b8ffe --- /dev/null +++ b/frontend/src/metabase/components/YearPicker/YearPicker.tsx @@ -0,0 +1,26 @@ +import React, { ChangeEvent } from "react"; + +import Select from "metabase/core/components/Select"; +import _ from "underscore"; + +const YEARS = _.range(new Date().getFullYear(), 1900, -1); + +export interface YearPickerProps { + value: number; + onChange: (v: number) => void; +} + +const YearPicker = ({ value, onChange }: YearPickerProps) => ( + <Select + className="borderless" + value={value} + options={YEARS} + optionNameFn={(option: any) => option} + optionValueFn={(option: any) => option} + onChange={({ target: { value } }: ChangeEvent<HTMLInputElement>) => + onChange(parseInt(value as string, 10)) + } + /> +); + +export default YearPicker; diff --git a/frontend/src/metabase/components/YearPicker/YearPicker.unit.spec.tsx b/frontend/src/metabase/components/YearPicker/YearPicker.unit.spec.tsx new file mode 100644 index 00000000000..343b066e1e5 --- /dev/null +++ b/frontend/src/metabase/components/YearPicker/YearPicker.unit.spec.tsx @@ -0,0 +1,11 @@ +import React from "react"; +import { render, screen } from "@testing-library/react"; + +import YearPicker from "./YearPicker"; + +describe("YearPicker", () => { + it("should render correctly", () => { + render(<YearPicker value={2022} onChange={jest.fn()}></YearPicker>); + expect(screen.getByRole("button")).toHaveTextContent("2022"); + }); +}); diff --git a/frontend/src/metabase/components/YearPicker/index.tsx b/frontend/src/metabase/components/YearPicker/index.tsx new file mode 100644 index 00000000000..89d4b7ad30a --- /dev/null +++ b/frontend/src/metabase/components/YearPicker/index.tsx @@ -0,0 +1 @@ +export { default } from "./YearPicker"; diff --git a/frontend/src/metabase/parameters/components/widgets/DateMonthYearWidget.jsx b/frontend/src/metabase/parameters/components/widgets/DateMonthYearWidget.jsx index 528b3e858b5..1fbbe4d01e0 100644 --- a/frontend/src/metabase/parameters/components/widgets/DateMonthYearWidget.jsx +++ b/frontend/src/metabase/parameters/components/widgets/DateMonthYearWidget.jsx @@ -1,10 +1,11 @@ /* eslint-disable react/prop-types */ import React from "react"; -import YearPicker from "./YearPicker"; - import moment from "moment"; import _ from "underscore"; import cx from "classnames"; + +import YearPicker from "metabase/components/YearPicker"; + import { MonthContainer, MonthList } from "./DateMonthYearWidget.styled"; export default class DateMonthYearWidget extends React.Component { diff --git a/frontend/src/metabase/parameters/components/widgets/DateQuarterYearWidget.jsx b/frontend/src/metabase/parameters/components/widgets/DateQuarterYearWidget.jsx index 54a10f0e750..1af4d83d881 100644 --- a/frontend/src/metabase/parameters/components/widgets/DateQuarterYearWidget.jsx +++ b/frontend/src/metabase/parameters/components/widgets/DateQuarterYearWidget.jsx @@ -1,13 +1,12 @@ /* eslint-disable react/prop-types */ import React, { Component } from "react"; - -import YearPicker from "./YearPicker"; - import moment from "moment"; import _ from "underscore"; import cx from "classnames"; import { t } from "ttag"; +import YearPicker from "metabase/components/YearPicker"; + // translator: this is a "moment" format string (https://momentjs.com/docs/#/displaying/format/) It should include "Q" for the quarter number, and raw text can be escaped by brackets. For eample "[Quarter] Q" will be rendered as "Quarter 1" etc const QUARTER_FORMAT_STRING = t`[Q]Q`; diff --git a/frontend/src/metabase/parameters/components/widgets/YearPicker.jsx b/frontend/src/metabase/parameters/components/widgets/YearPicker.jsx deleted file mode 100644 index d23a976d4eb..00000000000 --- a/frontend/src/metabase/parameters/components/widgets/YearPicker.jsx +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-disable react/prop-types */ -import React from "react"; - -import Select from "metabase/core/components/Select"; -import _ from "underscore"; - -const YEARS = _.range(new Date().getFullYear(), 1900, -1); - -const YearPicker = ({ value, onChange }) => ( - <Select - className="borderless" - value={value} - options={YEARS} - optionNameFn={option => option} - optionValueFn={option => option} - onChange={({ target: { value } }) => onChange(value)} - /> -); - -export default YearPicker; -- GitLab