Skip to content
Snippets Groups Projects
Unverified Commit 8302a44a authored by Cam Saul's avatar Cam Saul
Browse files

Field remappings endpoints

parent 3da3b364
No related branches found
No related tags found
No related merge requests found
......@@ -343,7 +343,11 @@
:query-params query-params)))
;;; -------------------------------------------- Field Values & Searching --------------------------------------------
;;; +----------------------------------------------------------------------------------------------------------------+
;;; | FieldValues, Search, Remappings |
;;; +----------------------------------------------------------------------------------------------------------------+
;;; -------------------------------------------------- Field Values --------------------------------------------------
(api/defendpoint GET "/card/:token/field/:field-id/values"
"Fetch FieldValues for a Field that is referenced by an embedded Card."
......@@ -362,6 +366,8 @@
(public-api/dashboard-and-field-id->values dashboard-id field-id)))
;;; --------------------------------------------------- Searching ----------------------------------------------------
(api/defendpoint GET "/card/:token/field/:field-id/search/:search-field-id"
"Search for values of a Field that is referenced by an embedded Card."
[token field-id search-field-id value limit]
......@@ -378,7 +384,25 @@
limit (s/maybe su/IntStringGreaterThanZero)}
(let [unsigned-token (eu/unsign token)
dashboard-id (eu/get-in-unsigned-token-or-throw unsigned-token [:resource :dashboard])]
(public-api/search-dashboard-fields dashboard-id field-id search-field-id value (when limit (Integer/parseInt limit)))))
(public-api/search-dashboard-fields dashboard-id field-id search-field-id value (when limit
(Integer/parseInt limit)))))
;;; --------------------------------------------------- Remappings ---------------------------------------------------
(api/defendpoint GET "/card/:token/field/:field-id/remapping/:remapped-id"
[token field-id remapped-id value]
{value su/NonBlankString}
(let [unsigned-token (eu/unsign token)
card-id (eu/get-in-unsigned-token-or-throw unsigned-token [:resource :question])]
(public-api/card-field-remapped-values card-id field-id remapped-id value)))
(api/defendpoint GET "/dashboard/:token/field/:field-id/remapping/:remapped-id"
[token field-id remapped-id value]
{value su/NonBlankString}
(let [unsigned-token (eu/unsign token)
dashboard-id (eu/get-in-unsigned-token-or-throw unsigned-token [:resource :dashboard])]
(public-api/dashboard-field-remapped-values dashboard-id field-id remapped-id value)))
(api/define-routes)
......@@ -319,14 +319,20 @@
;; return first row if it exists
(first (get-in results [:data :rows]))))
(defn parse-query-param-value-for-field
"Parse a `value` passed as a URL query param in a way appropriate for the `field` it belongs to. E.g. for text Fields
the value doesn't need to be parsed; for numeric Fields we should parse it as a number."
[field, ^String value]
(if (isa? (:base_type field) :type/Number)
(.parse (NumberFormat/getInstance) value)
value))
(api/defendpoint GET "/:id/remapping/:remapped-id"
"Fetch remapped Field values."
[id remapped-id, ^String value]
(let [field (api/read-check Field id)
remapped-field (api/read-check Field remapped-id)
value (if (isa? (:base_type field) :type/Number)
(.parse (NumberFormat/getInstance) value)
value)]
value (parse-query-param-value-for-field field value)]
(remapped-value field remapped-field value)))
......
......@@ -176,7 +176,11 @@
:html (embed/iframe url width height)}))
;;; -------------------------------------------- Field Values & Searching --------------------------------------------
;;; +----------------------------------------------------------------------------------------------------------------+
;;; | FieldValues, Search, Remappings |
;;; +----------------------------------------------------------------------------------------------------------------+
;;; -------------------------------------------------- Field Values --------------------------------------------------
;; TODO - this is a stupid, inefficient way of doing things. Figure out a better way to do it. :(
(defn- query->referenced-field-ids
......@@ -224,7 +228,7 @@
(when-let [table-id (db/select-one-field :table_id Field :id field-id, :special_type (mdb/isa :type/PK))]
(db/exists? Field :id search-field-id, :table_id table-id, :special_type (mdb/isa :type/Name))))))
(defn- check-field-is-dashboard-parameter
(defn- check-field-is-referenced-by-dashboard
"Check that `field-id` belongs to a Field that is used as a parameter in a Dashboard with `dashboard-id`, or throw a
404 Exception."
[field-id dashboard-id]
......@@ -248,7 +252,7 @@
"Return the FieldValues for a Field with `field-id` that is referenced by Card with `card-id` which itself is present
in Dashboard with `dashboard-id`."
[dashboard-id field-id]
(check-field-is-dashboard-parameter field-id dashboard-id)
(check-field-is-referenced-by-dashboard field-id dashboard-id)
(field-api/field->values (Field field-id)))
(api/defendpoint GET "/dashboard/:uuid/field/:field-id/values"
......@@ -259,6 +263,8 @@
(dashboard-and-field-id->values dashboard-id field-id)))
;;; --------------------------------------------------- Searching ----------------------------------------------------
(defn search-card-fields
"Wrapper for `metabase.api.field/search-values` for use with public/embedded Cards. See that functions
documentation for a more detailed explanation of exactly what this does."
......@@ -271,7 +277,7 @@
"Wrapper for `metabase.api.field/search-values` for use with public/embedded Dashboards. See that functions
documentation for a more detailed explanation of exactly what this does."
[dashboard-id field-id search-id value limit]
(check-field-is-dashboard-parameter field-id dashboard-id)
(check-field-is-referenced-by-dashboard field-id dashboard-id)
(check-search-field-is-allowed field-id search-id)
(field-api/search-values (Field field-id) (Field search-id) value limit))
......@@ -294,4 +300,49 @@
(search-dashboard-fields dashboard-id field-id search-field-id value (when limit (Integer/parseInt limit)))))
;;; --------------------------------------------------- Remappings ---------------------------------------------------
(defn- field-remapped-values [field-id remapped-field-id, ^String value-str]
;; TODO - how do we check that `remapped-field` is allowed to be used here????????
(let [field (api/check-404 (Field field-id))
remapped-field (api/check-404 (Field remapped-field-id))]
(field-api/remapped-value field remapped-field (field-api/parse-query-param-value-for-field field value-str))))
(defn card-field-remapped-values
"Return the reampped Field values for a Field referenced by a *Card*. This explanation is almost useless, so see the
one in `metabase.api.field/remapped-value` if you would actually like to understand what is going on here."
[card-id field-id remapped-field-id, ^String value-str]
(check-field-is-referenced-by-card field-id card-id)
(field-remapped-values field-id remapped-field-id value-str))
(defn dashboard-field-remapped-values
"Return the reampped Field values for a Field referenced by a *Dashboard*. This explanation is almost useless, so see
the one in `metabase.api.field/remapped-value` if you would actually like to understand what is going on here."
[dashboard-id field-id remapped-field-id, ^String value-str]
(check-field-is-referenced-by-dashboard field-id dashboard-id)
(field-remapped-values field-id remapped-field-id value-str))
(api/defendpoint GET "/card/:uuid/field/:field-id/remapping/:remapped-id"
[uuid field-id remapped-id value]
{value su/NonBlankString}
(api/check-public-sharing-enabled)
(let [card-id (api/check-404 (db/select-one-id Dashboard :public_uuid uuid, :archived false))]
(card-field-remapped-values card-id field-id remapped-id value)))
(api/defendpoint GET "/dashboard/:uuid/field/:field-id/remapping/:remapped-id"
[uuid field-id remapped-id value]
{value su/NonBlankString}
(api/check-public-sharing-enabled)
(let [dashboard-id (db/select-one-id Card :public_uuid uuid, :archived false)]
(dashboard-field-remapped-values dashboard-id field-id remapped-id value)))
;;; ----------------------------------------- Route Definitions & Complaints -----------------------------------------
;; TODO - why don't we just make these routes have a bit of middleware that includes the
;; `api/check-public-sharing-enabled` check in each of them? That way we don't need to remember to include the line in
;; every single endpoint definition here? Wouldn't that be 100x better?!
;;
;; TODO - also a smart person would probably just parse the UUIDs automatically in middleware as appropriate for
;;`/dashboard` vs `/card`
(api/define-routes)
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