From 445868102daaf7c3530f0e61f15519dde1b53618 Mon Sep 17 00:00:00 2001
From: Ariya Hidayat <ariya@metabase.com>
Date: Thu, 17 Feb 2022 07:23:13 -0800
Subject: [PATCH] Make time-series filter work with expression dimension
 (#20510)

The widget to filter time-series dimension should not assume that the
dimension is from a field, as it can be also an expression, i.e. when
the breakout is originated from a custom column. Hence, generalize the
case to avoid any crashing.
---
 .../components/TimeseriesFilterWidget.jsx     | 26 +++++++++++--------
 .../modes/TimeseriesFilterWidget.unit.spec.js |  2 +-
 2 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/frontend/src/metabase/modes/components/TimeseriesFilterWidget.jsx b/frontend/src/metabase/modes/components/TimeseriesFilterWidget.jsx
index fdd088458a4..c24a85d6e3b 100644
--- a/frontend/src/metabase/modes/components/TimeseriesFilterWidget.jsx
+++ b/frontend/src/metabase/modes/components/TimeseriesFilterWidget.jsx
@@ -10,10 +10,8 @@ import * as Query from "metabase/lib/query/query";
 import * as Filter from "metabase/lib/query/filter";
 import * as Card from "metabase/meta/Card";
 
-import {
-  parseFieldTarget,
-  generateTimeFilterValuesDescriptions,
-} from "metabase/lib/query_time";
+import { FieldDimension } from "metabase-lib/lib/Dimension";
+import { generateTimeFilterValuesDescriptions } from "metabase/lib/query_time";
 
 import cx from "classnames";
 import _ from "underscore";
@@ -30,25 +28,31 @@ export default class TimeseriesFilterWidget extends Component {
   }
 
   UNSAFE_componentWillReceiveProps(nextProps) {
-    const query = Card.getQuery(nextProps.card);
-    if (query) {
-      const breakouts = Query.getBreakouts(query);
-      const filters = Query.getFilters(query);
+    const { query } = nextProps;
+    const breakouts = query.breakouts();
+    if (breakouts && breakouts.length > 0) {
+      const filters = query.filters();
 
-      const timeField = parseFieldTarget(breakouts[0]);
+      const dimensions = breakouts.map(b => b.dimension());
+      const dimension = dimensions[0];
+
+      const timeseriesDimension =
+        dimension instanceof FieldDimension
+          ? dimension.withoutTemporalBucketing()
+          : dimension;
 
       const filterIndex = _.findIndex(
         filters,
         filter =>
           Filter.isFieldFilter(filter) &&
-          _.isEqual(filter[1], timeField.mbql()),
+          _.isEqual(filter[1], timeseriesDimension.mbql()),
       );
 
       let filter, currentFilter;
       if (filterIndex >= 0) {
         filter = currentFilter = filters[filterIndex];
       } else {
-        filter = ["time-interval", timeField.mbql(), -30, "day"];
+        filter = ["time-interval", timeseriesDimension.mbql(), -30, "day"];
       }
 
       this.setState({ filter, filterIndex, currentFilter });
diff --git a/frontend/test/metabase/modes/TimeseriesFilterWidget.unit.spec.js b/frontend/test/metabase/modes/TimeseriesFilterWidget.unit.spec.js
index 502d42727c6..a82b6bf9813 100644
--- a/frontend/test/metabase/modes/TimeseriesFilterWidget.unit.spec.js
+++ b/frontend/test/metabase/modes/TimeseriesFilterWidget.unit.spec.js
@@ -12,7 +12,7 @@ import {
 const getTimeseriesFilterWidget = question => (
   <TimeseriesFilterWidget
     card={question.card()}
-    datasetQuery={question.query().datasetQuery()}
+    query={question.query()}
     setDatasetQuery={() => {}}
   />
 );
-- 
GitLab