From 275e6112d84ec7a65358c8e1fc5572ad0f130693 Mon Sep 17 00:00:00 2001
From: Dalton <daltojohnso@users.noreply.github.com>
Date: Wed, 27 Oct 2021 09:57:47 -0700
Subject: [PATCH] move parameter ui utils to separate file (#18690)

* move parameter ui utils to separate file

* move utils for building parameters from cards to own utils file (#18691)
---
 frontend/src/metabase-lib/lib/Question.js     |  6 +-
 .../components/ParametersPopover.jsx          |  2 +-
 frontend/src/metabase/meta/Card.js            | 68 ++------------
 frontend/src/metabase/meta/Parameter.js       | 74 ---------------
 .../components/ParameterValueWidget.jsx       |  2 +-
 .../parameters/components/ParametersList.jsx  |  2 +-
 .../src/metabase/parameters/utils/cards.js    | 89 +++++++++++++++++++
 .../parameters/utils/cards.unit.spec.js}      | 57 +-----------
 frontend/src/metabase/parameters/utils/ui.js  | 33 +++++++
 .../metabase/parameters/utils/ui.unit.spec.js | 67 ++++++++++++++
 .../public/containers/PublicQuestion.jsx      |  4 +-
 .../src/metabase/query_builder/actions.js     |  8 +-
 .../containers/QuestionEmbedWidget.jsx        |  2 +-
 .../src/metabase/query_builder/selectors.js   |  2 +-
 src/metabase/api/embed.clj                    |  2 +-
 15 files changed, 210 insertions(+), 208 deletions(-)
 delete mode 100644 frontend/src/metabase/meta/Parameter.js
 create mode 100644 frontend/src/metabase/parameters/utils/cards.js
 rename frontend/{test/metabase/meta/Parameter.unit.spec.js => src/metabase/parameters/utils/cards.unit.spec.js} (75%)
 create mode 100644 frontend/src/metabase/parameters/utils/ui.js
 create mode 100644 frontend/src/metabase/parameters/utils/ui.unit.spec.js

diff --git a/frontend/src/metabase-lib/lib/Question.js b/frontend/src/metabase-lib/lib/Question.js
index 4759faed28a..14bf1ae6848 100644
--- a/frontend/src/metabase-lib/lib/Question.js
+++ b/frontend/src/metabase-lib/lib/Question.js
@@ -34,10 +34,8 @@ import {
   findColumnSettingIndexForColumn,
   syncTableColumnsToQuery,
 } from "metabase/lib/dataset";
-import {
-  getValueAndFieldIdPopulatedParametersFromCard,
-  isTransientId,
-} from "metabase/meta/Card";
+import { isTransientId } from "metabase/meta/Card";
+import { getValueAndFieldIdPopulatedParametersFromCard } from "metabase/parameters/utils/cards";
 import { parameterToMBQLFilter } from "metabase/parameters/utils/mbql";
 import { normalizeParameterValue } from "metabase/parameters/utils/parameter-values";
 import {
diff --git a/frontend/src/metabase/dashboard/components/ParametersPopover.jsx b/frontend/src/metabase/dashboard/components/ParametersPopover.jsx
index d4a0fbe6bcc..50da002e0bb 100644
--- a/frontend/src/metabase/dashboard/components/ParametersPopover.jsx
+++ b/frontend/src/metabase/dashboard/components/ParametersPopover.jsx
@@ -2,7 +2,7 @@ import React, { Component } from "react";
 import { t } from "ttag";
 import { getDashboardParameterSections } from "metabase/parameters/utils/dashboard-options";
 import Icon from "metabase/components/Icon";
-import { getParameterIconName } from "metabase/meta/Parameter";
+import { getParameterIconName } from "metabase/parameters/utils/ui";
 import styled from "styled-components";
 
 import type {
diff --git a/frontend/src/metabase/meta/Card.js b/frontend/src/metabase/meta/Card.js
index 49e4a0a41c0..2900230f148 100644
--- a/frontend/src/metabase/meta/Card.js
+++ b/frontend/src/metabase/meta/Card.js
@@ -1,21 +1,16 @@
-import { getTemplateTagParameters } from "metabase/meta/Parameter";
+import _ from "underscore";
+import { assoc, updateIn } from "icepick";
+
+import { getParametersFromCard } from "metabase/parameters/utils/cards";
 import { parameterToMBQLFilter } from "metabase/parameters/utils/mbql";
-import { getParameterTargetField } from "metabase/parameters/utils/targets";
-import {
-  normalizeParameterValue,
-  getValuePopulatedParameters,
-} from "metabase/parameters/utils/parameter-values";
+import { normalizeParameterValue } from "metabase/parameters/utils/parameter-values";
 
 import * as Query from "metabase/lib/query/query";
 import * as Q_DEPRECATED from "metabase/lib/query"; // legacy
 import Utils from "metabase/lib/utils";
 import * as Urls from "metabase/lib/urls";
-import Question from "metabase-lib/lib/Question";
-
-import _ from "underscore";
-import { assoc, updateIn } from "icepick";
 
-import type { StructuredQuery, TemplateTag } from "metabase-types/types/Query";
+import type { StructuredQuery } from "metabase-types/types/Query";
 import type {
   Card,
   DatasetQuery,
@@ -30,10 +25,6 @@ import type {
 import type Metadata from "metabase-lib/lib/metadata/Metadata";
 import type Table from "metabase-lib/lib/metadata/Table";
 
-declare class Object {
-  static values<T>(object: { [key: string]: T }): Array<T>;
-}
-
 // TODO Atte Keinänen 6/5/17 Should these be moved to corresponding metabase-lib classes?
 // Is there any reason behind keeping them in a central place?
 
@@ -113,53 +104,6 @@ export function getTableMetadata(card: Card, metadata: Metadata): ?Table {
   return null;
 }
 
-export function getTemplateTagsForParameters(card: ?Card): Array<TemplateTag> {
-  const templateTags =
-    card &&
-    card.dataset_query &&
-    card.dataset_query.type === "native" &&
-    card.dataset_query.native["template-tags"]
-      ? Object.values(card.dataset_query.native["template-tags"])
-      : [];
-  return templateTags.filter(
-    // this should only return template tags that define a parameter of the card
-    tag => tag.type !== "card" && tag.type !== "snippet",
-  );
-}
-
-export function getParametersFromCard(card: ?Card): Parameter[] {
-  if (card && card.parameters) {
-    return card.parameters;
-  }
-
-  const tags: TemplateTag[] = getTemplateTagsForParameters(card);
-  return getTemplateTagParameters(tags);
-}
-
-export function getValueAndFieldIdPopulatedParametersFromCard(
-  card: Card,
-  metadata,
-  parameterValues?: ParameterValues,
-): Parameter[] {
-  const parameters = getParametersFromCard(card);
-  const valuePopulatedParameters = getValuePopulatedParameters(
-    parameters,
-    parameterValues,
-  );
-  const question = new Question(card, metadata);
-
-  return valuePopulatedParameters.map(parameter => {
-    // if we have a field id for this parameter, set "field_id"
-    const field = getParameterTargetField(parameter.target, metadata, question);
-    if (field != null) {
-      parameter = assoc(parameter, "fields", [field]);
-      parameter = assoc(parameter, "field_id", field.id);
-    }
-    parameter = assoc(parameter, "hasOnlyFieldTargets", field != null);
-    return parameter;
-  });
-}
-
 // NOTE Atte Keinänen 7/5/17: Still used in dashboards and public questions.
 // Query builder uses `Question.getResults` which contains similar logic.
 export function applyParameters(
diff --git a/frontend/src/metabase/meta/Parameter.js b/frontend/src/metabase/meta/Parameter.js
deleted file mode 100644
index a862dae0c9a..00000000000
--- a/frontend/src/metabase/meta/Parameter.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import MetabaseSettings from "metabase/lib/settings";
-import type { TemplateTag } from "metabase-types/types/Query";
-import type { Parameter } from "metabase-types/types/Parameter";
-import _ from "underscore";
-import { getParameterType } from "metabase/parameters/utils/parameter-type";
-
-const areFieldFilterOperatorsEnabled = () =>
-  MetabaseSettings.get("field-filter-operators-enabled?");
-
-// NOTE: this should mirror `template-tag-parameters` in src/metabase/api/embed.clj
-export function getTemplateTagParameters(tags: TemplateTag[]): Parameter[] {
-  function getTemplateTagType(tag) {
-    const { type } = tag;
-    if (type === "date") {
-      return "date/single";
-    } else if (areFieldFilterOperatorsEnabled() && type === "string") {
-      return "string/=";
-    } else if (areFieldFilterOperatorsEnabled() && type === "number") {
-      return "number/=";
-    } else {
-      return "category";
-    }
-  }
-
-  return tags
-    .filter(
-      tag =>
-        tag.type != null && (tag["widget-type"] || tag.type !== "dimension"),
-    )
-    .map(tag => {
-      return {
-        id: tag.id,
-        type: tag["widget-type"] || getTemplateTagType(tag),
-        target:
-          tag.type === "dimension"
-            ? ["dimension", ["template-tag", tag.name]]
-            : ["variable", ["template-tag", tag.name]],
-        name: tag["display-name"],
-        slug: tag.name,
-        default: tag.default,
-      };
-    });
-}
-
-export function getParameterIconName(parameter: ?Parameter) {
-  const type = getParameterType(parameter);
-  switch (type) {
-    case "date":
-      return "calendar";
-    case "location":
-      return "location";
-    case "category":
-      return "string";
-    case "number":
-      return "number";
-    case "id":
-    default:
-      return "label";
-  }
-}
-
-export function buildHiddenParametersSlugSet(hiddenParameterSlugs) {
-  return _.isString(hiddenParameterSlugs)
-    ? new Set(hiddenParameterSlugs.split(","))
-    : new Set();
-}
-
-export function getVisibleParameters(parameters, hiddenParameterSlugs) {
-  const hiddenParametersSlugSet = buildHiddenParametersSlugSet(
-    hiddenParameterSlugs,
-  );
-
-  return parameters.filter(p => !hiddenParametersSlugSet.has(p.slug));
-}
diff --git a/frontend/src/metabase/parameters/components/ParameterValueWidget.jsx b/frontend/src/metabase/parameters/components/ParameterValueWidget.jsx
index a20d2210777..27420d5fac0 100644
--- a/frontend/src/metabase/parameters/components/ParameterValueWidget.jsx
+++ b/frontend/src/metabase/parameters/components/ParameterValueWidget.jsx
@@ -23,7 +23,7 @@ import {
   makeGetMergedParameterFieldValues,
 } from "metabase/selectors/metadata";
 
-import { getParameterIconName } from "metabase/meta/Parameter";
+import { getParameterIconName } from "metabase/parameters/utils/ui";
 import { deriveFieldOperatorFromParameter } from "metabase/parameters/utils/operators";
 import { isDashboardParameterWithoutMapping } from "metabase/meta/Dashboard";
 
diff --git a/frontend/src/metabase/parameters/components/ParametersList.jsx b/frontend/src/metabase/parameters/components/ParametersList.jsx
index a4879c224a0..01e81b76547 100644
--- a/frontend/src/metabase/parameters/components/ParametersList.jsx
+++ b/frontend/src/metabase/parameters/components/ParametersList.jsx
@@ -9,7 +9,7 @@ import {
   SortableElement,
   SortableHandle,
 } from "metabase/components/sortable";
-import { getVisibleParameters } from "metabase/meta/Parameter";
+import { getVisibleParameters } from "metabase/parameters/utils/ui";
 import { getValuePopulatedParameters } from "metabase/parameters/utils/parameter-values";
 
 import type {
diff --git a/frontend/src/metabase/parameters/utils/cards.js b/frontend/src/metabase/parameters/utils/cards.js
new file mode 100644
index 00000000000..9bfbbd104de
--- /dev/null
+++ b/frontend/src/metabase/parameters/utils/cards.js
@@ -0,0 +1,89 @@
+import { assoc } from "icepick";
+
+import Question from "metabase-lib/lib/Question";
+
+import { areFieldFilterOperatorsEnabled } from "./feature-flag";
+import { getParameterTargetField } from "metabase/parameters/utils/targets";
+import { getValuePopulatedParameters } from "metabase/parameters/utils/parameter-values";
+
+// NOTE: this should mirror `template-tag-parameters` in src/metabase/api/embed.clj
+export function getTemplateTagParameters(tags) {
+  function getTemplateTagType(tag) {
+    const { type } = tag;
+    if (type === "date") {
+      return "date/single";
+    } else if (areFieldFilterOperatorsEnabled() && type === "string") {
+      return "string/=";
+    } else if (areFieldFilterOperatorsEnabled() && type === "number") {
+      return "number/=";
+    } else {
+      return "category";
+    }
+  }
+
+  return tags
+    .filter(
+      tag =>
+        tag.type != null && (tag["widget-type"] || tag.type !== "dimension"),
+    )
+    .map(tag => {
+      return {
+        id: tag.id,
+        type: tag["widget-type"] || getTemplateTagType(tag),
+        target:
+          tag.type === "dimension"
+            ? ["dimension", ["template-tag", tag.name]]
+            : ["variable", ["template-tag", tag.name]],
+        name: tag["display-name"],
+        slug: tag.name,
+        default: tag.default,
+      };
+    });
+}
+
+export function getTemplateTagsForParameters(card) {
+  const templateTags =
+    card &&
+    card.dataset_query &&
+    card.dataset_query.type === "native" &&
+    card.dataset_query.native["template-tags"]
+      ? Object.values(card.dataset_query.native["template-tags"])
+      : [];
+  return templateTags.filter(
+    // this should only return template tags that define a parameter of the card
+    tag => tag.type !== "card" && tag.type !== "snippet",
+  );
+}
+
+export function getParametersFromCard(card) {
+  if (card && card.parameters) {
+    return card.parameters;
+  }
+
+  const tags = getTemplateTagsForParameters(card);
+  return getTemplateTagParameters(tags);
+}
+
+export function getValueAndFieldIdPopulatedParametersFromCard(
+  card,
+  metadata,
+  parameterValues,
+) {
+  const parameters = getParametersFromCard(card);
+  const valuePopulatedParameters = getValuePopulatedParameters(
+    parameters,
+    parameterValues,
+  );
+  const question = new Question(card, metadata);
+
+  return valuePopulatedParameters.map(parameter => {
+    // if we have a field id for this parameter, set "field_id"
+    const field = getParameterTargetField(parameter.target, metadata, question);
+    if (field != null) {
+      parameter = assoc(parameter, "fields", [field]);
+      parameter = assoc(parameter, "field_id", field.id);
+    }
+    parameter = assoc(parameter, "hasOnlyFieldTargets", field != null);
+    return parameter;
+  });
+}
diff --git a/frontend/test/metabase/meta/Parameter.unit.spec.js b/frontend/src/metabase/parameters/utils/cards.unit.spec.js
similarity index 75%
rename from frontend/test/metabase/meta/Parameter.unit.spec.js
rename to frontend/src/metabase/parameters/utils/cards.unit.spec.js
index b2946e76a70..3da8383cbc8 100644
--- a/frontend/test/metabase/meta/Parameter.unit.spec.js
+++ b/frontend/src/metabase/parameters/utils/cards.unit.spec.js
@@ -1,9 +1,5 @@
 import MetabaseSettings from "metabase/lib/settings";
-import {
-  getTemplateTagParameters,
-  buildHiddenParametersSlugSet,
-  getVisibleParameters,
-} from "metabase/meta/Parameter";
+import { getTemplateTagParameters } from "./cards";
 
 MetabaseSettings.get = jest.fn();
 
@@ -15,7 +11,7 @@ function mockFieldFilterOperatorsFlag(value) {
   });
 }
 
-describe("metabase/meta/Parameter", () => {
+describe("parameters/utils/cards", () => {
   beforeEach(() => {
     jest.clearAllMocks();
     MetabaseSettings.get.mockReturnValue(false);
@@ -174,53 +170,4 @@ describe("metabase/meta/Parameter", () => {
       });
     });
   });
-
-  describe("buildHiddenParametersSlugSet", () => {
-    it("should turn the given string of slugs separated by commas into a set of slug strings", () => {
-      expect(buildHiddenParametersSlugSet("a,b,c")).toEqual(
-        new Set(["a", "b", "c"]),
-      );
-    });
-
-    it("should return an empty set for any input that is not a string", () => {
-      expect(buildHiddenParametersSlugSet(undefined)).toEqual(new Set());
-      expect(buildHiddenParametersSlugSet(111111)).toEqual(new Set());
-    });
-  });
-
-  describe("getVisibleParameters", () => {
-    const parameters = [
-      {
-        id: 1,
-        slug: "foo",
-      },
-      {
-        id: 2,
-        slug: "bar",
-      },
-      {
-        id: 3,
-        slug: "baz",
-      },
-      {
-        id: 4,
-        slug: "qux",
-      },
-    ];
-
-    const hiddenParameterSlugs = "bar,baz";
-
-    it("should return the parameters that are not hidden", () => {
-      expect(getVisibleParameters(parameters, hiddenParameterSlugs)).toEqual([
-        {
-          id: 1,
-          slug: "foo",
-        },
-        {
-          id: 4,
-          slug: "qux",
-        },
-      ]);
-    });
-  });
 });
diff --git a/frontend/src/metabase/parameters/utils/ui.js b/frontend/src/metabase/parameters/utils/ui.js
new file mode 100644
index 00000000000..2abcf78ece7
--- /dev/null
+++ b/frontend/src/metabase/parameters/utils/ui.js
@@ -0,0 +1,33 @@
+import _ from "underscore";
+import { getParameterType } from "./parameter-type";
+
+export function getParameterIconName(parameter) {
+  const type = getParameterType(parameter);
+  switch (type) {
+    case "date":
+      return "calendar";
+    case "location":
+      return "location";
+    case "category":
+      return "string";
+    case "number":
+      return "number";
+    case "id":
+    default:
+      return "label";
+  }
+}
+
+export function buildHiddenParametersSlugSet(hiddenParameterSlugs) {
+  return _.isString(hiddenParameterSlugs)
+    ? new Set(hiddenParameterSlugs.split(","))
+    : new Set();
+}
+
+export function getVisibleParameters(parameters, hiddenParameterSlugs) {
+  const hiddenParametersSlugSet = buildHiddenParametersSlugSet(
+    hiddenParameterSlugs,
+  );
+
+  return parameters.filter(p => !hiddenParametersSlugSet.has(p.slug));
+}
diff --git a/frontend/src/metabase/parameters/utils/ui.unit.spec.js b/frontend/src/metabase/parameters/utils/ui.unit.spec.js
new file mode 100644
index 00000000000..8155721214b
--- /dev/null
+++ b/frontend/src/metabase/parameters/utils/ui.unit.spec.js
@@ -0,0 +1,67 @@
+import {
+  getParameterIconName,
+  buildHiddenParametersSlugSet,
+  getVisibleParameters,
+} from "./ui";
+
+describe("parameters/utils/ui", () => {
+  describe("getParameterIconName", () => {
+    it("should return an icon name for the given parameter", () => {
+      expect(getParameterIconName({ type: "category" })).toEqual("string");
+      expect(getParameterIconName({ type: "date/single" })).toEqual("calendar");
+    });
+
+    it("should safely default", () => {
+      expect(getParameterIconName({ type: "???" })).toEqual("label");
+    });
+  });
+
+  describe("buildHiddenParametersSlugSet", () => {
+    it("should turn the given string of slugs separated by commas into a set of slug strings", () => {
+      expect(buildHiddenParametersSlugSet("a,b,c")).toEqual(
+        new Set(["a", "b", "c"]),
+      );
+    });
+
+    it("should return an empty set for any input that is not a string", () => {
+      expect(buildHiddenParametersSlugSet(undefined)).toEqual(new Set());
+      expect(buildHiddenParametersSlugSet(111111)).toEqual(new Set());
+    });
+  });
+
+  describe("getVisibleParameters", () => {
+    const parameters = [
+      {
+        id: 1,
+        slug: "foo",
+      },
+      {
+        id: 2,
+        slug: "bar",
+      },
+      {
+        id: 3,
+        slug: "baz",
+      },
+      {
+        id: 4,
+        slug: "qux",
+      },
+    ];
+
+    const hiddenParameterSlugs = "bar,baz";
+
+    it("should return the parameters that are not hidden", () => {
+      expect(getVisibleParameters(parameters, hiddenParameterSlugs)).toEqual([
+        {
+          id: 1,
+          slug: "foo",
+        },
+        {
+          id: 4,
+          slug: "qux",
+        },
+      ]);
+    });
+  });
+});
diff --git a/frontend/src/metabase/public/containers/PublicQuestion.jsx b/frontend/src/metabase/public/containers/PublicQuestion.jsx
index b1fa133682d..edf5da38333 100644
--- a/frontend/src/metabase/public/containers/PublicQuestion.jsx
+++ b/frontend/src/metabase/public/containers/PublicQuestion.jsx
@@ -17,11 +17,11 @@ import {
   getParameterValuesBySlug,
   getParameterValuesByIdFromQueryParams,
 } from "metabase/parameters/utils/parameter-values";
+import { applyParameters } from "metabase/meta/Card";
 import {
   getParametersFromCard,
   getValueAndFieldIdPopulatedParametersFromCard,
-  applyParameters,
-} from "metabase/meta/Card";
+} from "metabase/parameters/utils/cards";
 
 import {
   PublicApi,
diff --git a/frontend/src/metabase/query_builder/actions.js b/frontend/src/metabase/query_builder/actions.js
index 508b40a4014..32c2474e798 100644
--- a/frontend/src/metabase/query_builder/actions.js
+++ b/frontend/src/metabase/query_builder/actions.js
@@ -29,11 +29,9 @@ import Utils from "metabase/lib/utils";
 import { defer } from "metabase/lib/promise";
 import Question from "metabase-lib/lib/Question";
 import { FieldDimension } from "metabase-lib/lib/Dimension";
-import {
-  cardIsEquivalent,
-  cardQueryIsEquivalent,
-  getValueAndFieldIdPopulatedParametersFromCard,
-} from "metabase/meta/Card";
+import { cardIsEquivalent, cardQueryIsEquivalent } from "metabase/meta/Card";
+import { getValueAndFieldIdPopulatedParametersFromCard } from "metabase/parameters/utils/cards";
+
 import { getParameterValuesByIdFromQueryParams } from "metabase/parameters/utils/parameter-values";
 import { normalize } from "cljs/metabase.mbql.js";
 
diff --git a/frontend/src/metabase/query_builder/containers/QuestionEmbedWidget.jsx b/frontend/src/metabase/query_builder/containers/QuestionEmbedWidget.jsx
index 15f4b3bd381..98f8f6c0a4a 100644
--- a/frontend/src/metabase/query_builder/containers/QuestionEmbedWidget.jsx
+++ b/frontend/src/metabase/query_builder/containers/QuestionEmbedWidget.jsx
@@ -11,8 +11,8 @@ import EmbedModalContent from "metabase/public/components/widgets/EmbedModalCont
 import * as Urls from "metabase/lib/urls";
 import MetabaseSettings from "metabase/lib/settings";
 import * as MetabaseAnalytics from "metabase/lib/analytics";
+import { getParametersFromCard } from "metabase/parameters/utils/cards";
 
-import { getParametersFromCard } from "metabase/meta/Card";
 import {
   createPublicLink,
   deletePublicLink,
diff --git a/frontend/src/metabase/query_builder/selectors.js b/frontend/src/metabase/query_builder/selectors.js
index c0312d7f374..a12fd8b387b 100644
--- a/frontend/src/metabase/query_builder/selectors.js
+++ b/frontend/src/metabase/query_builder/selectors.js
@@ -13,7 +13,7 @@ import {
   getVisualizationTransformed,
 } from "metabase/visualizations";
 import { getComputedSettingsForSeries } from "metabase/visualizations/lib/settings/visualization";
-import { getValueAndFieldIdPopulatedParametersFromCard } from "metabase/meta/Card";
+import { getValueAndFieldIdPopulatedParametersFromCard } from "metabase/parameters/utils/cards";
 import { normalizeParameterValue } from "metabase/parameters/utils/parameter-values";
 
 import Utils from "metabase/lib/utils";
diff --git a/src/metabase/api/embed.clj b/src/metabase/api/embed.clj
index fe5a2d99ea6..6b65eaabffe 100644
--- a/src/metabase/api/embed.clj
+++ b/src/metabase/api/embed.clj
@@ -130,7 +130,7 @@
 (defn- template-tag-parameters
   "Transforms native query's `template-tags` into `parameters`."
   [card]
-  ;; NOTE: this should mirror `getTemplateTagParameters` in frontend/src/metabase/meta/Parameter.js
+  ;; NOTE: this should mirror `getTemplateTagParameters` in frontend/src/metabase/parameters/utils/cards.js
   (for [[_ {tag-type :type, widget-type :widget-type, :as tag}] (get-in card [:dataset_query :native :template-tags])
         :when                         (and tag-type
                                            (or widget-type (not= tag-type :dimension)))]
-- 
GitLab