From e9a94189360ba2e019052a6e0eb6a0ecac171e95 Mon Sep 17 00:00:00 2001 From: Alexander Polyankin <alexander.polyankin@metabase.com> Date: Tue, 18 Oct 2022 16:08:49 +0300 Subject: [PATCH] Extract date picker filter utilities (#25964) --- .../lib/queries/utils/date-filters.ts | 36 +++++++++++++++++++ .../pickers/DatePicker/RangeDatePicker.tsx | 34 +++++++++--------- .../pickers/DatePicker/SingleDatePicker.tsx | 16 +++++---- 3 files changed, 62 insertions(+), 24 deletions(-) diff --git a/frontend/src/metabase-lib/lib/queries/utils/date-filters.ts b/frontend/src/metabase-lib/lib/queries/utils/date-filters.ts index ad5c7aa5af8..88472ec411a 100644 --- a/frontend/src/metabase-lib/lib/queries/utils/date-filters.ts +++ b/frontend/src/metabase-lib/lib/queries/utils/date-filters.ts @@ -392,3 +392,39 @@ export const isDayOfWeekDateFilter = testTemporalUnit("day-of-week"); export const isMonthOfYearDateFilter = testTemporalUnit("month-of-year"); export const isQuarterofYearDateFilter = testTemporalUnit("quarter-of-year"); export const isHourOfDayDateFilter = testTemporalUnit("hour-of-day"); + +export function getDateFilterValue(mbql: any[]) { + const [_op, _field, value] = mbql; + return value; +} + +export function setDateFilterValue(mbql: any[], newValue: string | null) { + const [op, field] = mbql; + return [op, field, newValue]; +} + +export function clearDateFilterTime(mbql: any[]) { + return setDateFilterValue(mbql, setTimeComponent(getDateFilterValue(mbql))); +} + +export function getDateRangeFilterValue(mbql: any[]) { + const [_op, _field, startValue, endValue] = mbql; + return [startValue, endValue]; +} + +export function setDateRangeFilterValue( + mbql: any[], + [startValue, endValue]: [string | null, string | null], +) { + const [op, field] = mbql; + return [op, field, startValue, endValue]; +} + +export function clearDateRangeFilterTime(mbql: any[]) { + const [startValue, endValue] = getDateRangeFilterValue(mbql); + + return setDateRangeFilterValue(mbql, [ + setTimeComponent(startValue), + setTimeComponent(endValue), + ]); +} diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker/RangeDatePicker.tsx b/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker/RangeDatePicker.tsx index 7d446939dd8..830ab8b4ce5 100644 --- a/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker/RangeDatePicker.tsx +++ b/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker/RangeDatePicker.tsx @@ -1,8 +1,12 @@ import React, { useCallback, useState } from "react"; import moment, { Moment } from "moment-timezone"; import Calendar from "metabase/components/Calendar"; -import { setTimeComponent } from "metabase-lib/lib/queries/utils/query-time"; import Filter from "metabase-lib/lib/queries/structured/Filter"; +import { + clearDateRangeFilterTime, + getDateRangeFilterValue, + setDateRangeFilterValue, +} from "metabase-lib/lib/queries/utils/date-filters"; import SingleDatePicker, { SingleDatePickerProps } from "./SingleDatePicker"; import SpecificDatePicker from "./SpecificDatePicker"; import { DateContainer, DateDivider } from "./RangeDatePicker.styled"; @@ -17,11 +21,12 @@ export interface BetweenPickerProps { export const BetweenPicker = ({ className, - filter: [op, field, startValue, endValue], + filter, primaryColor, hideTimeSelectors, onFilterChange, }: BetweenPickerProps) => { + const [startValue, endValue] = getDateRangeFilterValue(filter); const [isStartDateActive, setIsStartDateActive] = useState(true); const handleStartDateFocus = useCallback(() => { @@ -35,41 +40,36 @@ export const BetweenPicker = ({ const handleDateClick = useCallback( (newValue: string, newDate: Moment) => { if (isStartDateActive) { - onFilterChange([op, field, newValue, null]); + onFilterChange(setDateRangeFilterValue(filter, [newValue, null])); } else if (newDate.isBefore(startValue)) { - onFilterChange([op, field, newValue, startValue]); + onFilterChange(setDateRangeFilterValue(filter, [newValue, startValue])); } else { - onFilterChange([op, field, startValue, newValue]); + onFilterChange(setDateRangeFilterValue(filter, [startValue, newValue])); } setIsStartDateActive(isActive => !isActive); }, - [op, field, startValue, isStartDateActive, onFilterChange], + [filter, startValue, isStartDateActive, onFilterChange], ); const handleStartDateChange = useCallback( (newValue: string | null) => { - onFilterChange([op, field, newValue, endValue]); + onFilterChange(setDateRangeFilterValue(filter, [newValue, endValue])); setIsStartDateActive(isActive => !isActive); }, - [op, field, endValue, onFilterChange], + [filter, endValue, onFilterChange], ); const handleEndDateChange = useCallback( (newValue: string | null) => { - onFilterChange([op, field, startValue, newValue]); + onFilterChange(setDateRangeFilterValue(filter, [startValue, newValue])); setIsStartDateActive(isActive => !isActive); }, - [op, field, startValue, onFilterChange], + [filter, startValue, onFilterChange], ); const handleEndDateClear = useCallback(() => { - onFilterChange([ - op, - field, - setTimeComponent(startValue), - setTimeComponent(endValue), - ]); - }, [op, field, startValue, endValue, onFilterChange]); + onFilterChange(clearDateRangeFilterTime(filter)); + }, [filter, onFilterChange]); return ( <div className={className} data-testid="between-date-picker"> diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker/SingleDatePicker.tsx b/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker/SingleDatePicker.tsx index 8bae4a03155..1ba385a8ee8 100644 --- a/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker/SingleDatePicker.tsx +++ b/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker/SingleDatePicker.tsx @@ -1,9 +1,11 @@ -/* eslint-disable react/prop-types */ import React from "react"; - import { SelectAll } from "metabase/components/Calendar"; -import { setTimeComponent } from "metabase-lib/lib/queries/utils/query-time"; import Filter from "metabase-lib/lib/queries/structured/Filter"; +import { + clearDateFilterTime, + getDateFilterValue, + setDateFilterValue, +} from "metabase-lib/lib/queries/utils/date-filters"; import SpecificDatePicker from "./SpecificDatePicker"; export type SingleDatePickerProps = { @@ -17,7 +19,7 @@ export type SingleDatePickerProps = { const SingleDatePicker = ({ className, - filter: [op, field, value], + filter, onFilterChange, hideTimeSelectors, selectAll, @@ -25,11 +27,11 @@ const SingleDatePicker = ({ }: SingleDatePickerProps) => ( <SpecificDatePicker className={className} - value={value} + value={getDateFilterValue(filter)} primaryColor={primaryColor} selectAll={selectAll} - onChange={value => onFilterChange([op, field, value])} - onClear={() => onFilterChange([op, field, setTimeComponent(value)])} + onChange={value => onFilterChange(setDateFilterValue(filter, value))} + onClear={() => onFilterChange(clearDateFilterTime(filter))} autoFocus hasCalendar hideTimeSelectors={hideTimeSelectors} -- GitLab