Skip to content
Snippets Groups Projects
Commit 66e0d2be authored by Simon Belak's avatar Simon Belak
Browse files

Comprehensive and humanized filter values

parent 96c0c6bd
No related branches found
No related tags found
No related merge requests found
......@@ -160,7 +160,7 @@ const TransientFilter = ({ filter }) => (
/>
) : null,
])}
<span> is {filter.value}</span>
<span> {filter.value}</span>
</div>
);
......
......@@ -128,23 +128,149 @@
dashboard)))
dashboard)))))
(def ^:private ^{:arglists '([field])} periodic-date-time?
(comp #{:minute-of-hour :hour-of-day :day-of-week :day-of-month :day-of-year :week-of-year
:month-of-year :quarter-of-year}
:unit))
(defn- date-time?
[field]
(and (not (periodic-date-time? field))
(or (isa? (:base_type field) :type/DateTime)
(field/unix-timestamp? field))))
(defn- field-reference->field
[field-reference]
(-> field-reference collect-field-references first last Field))
(defmulti
^{:private true
:arglists '([op & args])}
humanize-filter-value (comp qp.util/normalize-token first))
(defn- either
[v & vs]
(if (empty? vs)
v
(loop [acc (format "either %s" v)
[v & vs] vs]
(cond
(nil? v) acc
(empty? vs) (format "%s or %s" acc v)
:else (recur (format "%s, %s" acc v) vs)))))
(defmethod humanize-filter-value :=
[[_ field-reference value & values]]
(let [field (field-reference->field field-reference)]
[{:field field-reference
:value (if (date-time? field)
(format "is on %s" value)
(format "is %s" (apply either value values)))}]))
(defmethod humanize-filter-value :not=
[[_ field-reference value]]
[{:field field-reference
:value (format "is not %s" value)}])
(defmethod humanize-filter-value :>
[[_ field-reference value]]
(let [field (field-reference->field field-reference)]
[{:field field-reference
:value (if (date-time? field)
(format "is after %s" value)
(format "is greater than %s" value))}]))
(defmethod humanize-filter-value :<
[[_ field-reference value]]
(let [field (field-reference->field field-reference)]
[{:field field-reference
:value (if (date-time? field)
(format "is before %s" value)
(format "is less than %s" value))}]))
(defmethod humanize-filter-value :>=
[[_ field-reference value]]
[{:field field-reference
:value (format "is greater than or equal to %s" value)}])
(defmethod humanize-filter-value :<=
[[_ field-reference value]]
[{:field field-reference
:value (format "is less than or equal to %s" value)}])
(defmethod humanize-filter-value :is-null
[[_ field-reference]]
[{:field field-reference
:value "is null"}])
(defmethod humanize-filter-value :not-null
[[_ field-reference]]
[{:field field-reference
:value "is not null"}])
(defmethod humanize-filter-value :between
[[_ field-reference min-value max-value]]
[{:field field-reference
:value (format "is between %s and %s" min-value max-value)}])
(defmethod humanize-filter-value :inside
[[_ lat-reference lon-reference lat-max lon-min lat-min lon-max]]
[{:field lat-reference
:value (format "is between %s and %s" lat-min lat-max)}
{:field lon-reference
:value (format "is between %s and %s" lon-min lon-max)}])
(defmethod humanize-filter-value :starts-with
[[_ field-reference value]]
[{:field field-reference
:value (format "starts with %s" value)}])
(defmethod humanize-filter-value :contains
[[_ field-reference value]]
[{:field field-reference
:value (format "contains %s" value)}])
(defmethod humanize-filter-value :does-not-contain
[[_ field-reference value]]
[{:field field-reference
:value (format "does not contain %s" value)}])
(defmethod humanize-filter-value :ends-with
[[_ field-reference value]]
[{:field field-reference
:value (format "ends with %s" value)}])
(defn- time-interval
[n unit]
(let [unit (name unit)]
(cond
(zero? n) (format "current %s" unit)
(= n -1) (format "previous %s" unit)
(= n 1) (format "next %s" unit)
(pos? n) (format "next %s %ss" n unit)
(neg? n) (format "previous %s %ss" n unit))))
(defmethod humanize-filter-value :time-interval
[[_ field-reference n unit]]
[{:field field-reference
:value (format "is during the %s" (time-interval n unit))}])
(defmethod humanize-filter-value :and
[[_ & clauses]]
(mapcat humanize-filter-value clauses))
(defn applied-filters
"Extract fields and their values from MBQL filter clauses."
[filter-clause]
(when filter-clause
(if (-> filter-clause first qp.util/normalize-token (#{:and :not :or}))
(mapcat applied-filters (rest filter-clause))
(let [[op lhs rhs & _] filter-clause]
(for [field-reference (collect-field-references lhs)]
(let [field (-> field-reference last Field)]
{:field (if (-> field-reference
first
qp.util/normalize-token
(= :fk->))
[(-> field :table_id Table :display_name)
(:display_name field)]
[(:display_name field)])
:field_id (:id field)
:type (filter-type field)
:value rhs
:op op}))))))
(for [{field-reference :field value :value} (humanize-filter-value filter-clause)]
(let [field (field-reference->field field-reference)]
{:field (if (-> field-reference
first
qp.util/normalize-token
(= :fk->))
[(-> field :table_id Table :display_name)
(:display_name field)]
[(:display_name field)])
:field_id (:id field)
:type (filter-type field)
:value value})))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment