From 15398b74fa868efcd72d5e1fa2262dddc67b6a95 Mon Sep 17 00:00:00 2001
From: Case Nelson <case@metabase.com>
Date: Tue, 30 Aug 2022 15:58:18 -0600
Subject: [PATCH] [Apps] Hydrate action on dashcards (#25110)

* [Apps] Hydrate action on dashcards

It is useful for the frontend if we hydrate :action in the same way that
we hydrate :card on :ordered_cards.

* Add docstring
---
 src/metabase/api/dashboard.clj       |  2 +-
 src/metabase/models/action.clj       | 10 ++++++++++
 test/metabase/api/dashboard_test.clj |  4 ++--
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/metabase/api/dashboard.clj b/src/metabase/api/dashboard.clj
index 767878fb020..8a0c0c0f61d 100644
--- a/src/metabase/api/dashboard.clj
+++ b/src/metabase/api/dashboard.clj
@@ -208,7 +208,7 @@
       ;; i'm a bit worried that this is an n+1 situation here. The cards can be batch hydrated i think because they
       ;; have a hydration key and an id. moderation_reviews currently aren't batch hydrated but i'm worried they
       ;; cannot be in this situation
-      (hydrate [:ordered_cards [:card [:moderation_reviews :moderator_details]] :series] :collection_authority_level :can_write :param_fields)
+      (hydrate [:ordered_cards [:card [:moderation_reviews :moderator_details]] :series :dashcard/action] :collection_authority_level :can_write :param_fields)
       (cond-> api/*is-superuser?* (hydrate [:emitters [:action :card]]))
       api/read-check
       api/check-not-archived
diff --git a/src/metabase/models/action.clj b/src/metabase/models/action.clj
index 84a59413932..a6822f19e49 100644
--- a/src/metabase/models/action.clj
+++ b/src/metabase/models/action.clj
@@ -151,3 +151,13 @@
     (for [card cards]
       (m/assoc-some card :action_id (get card-id->action-id (:id card))))
     cards))
+
+(defn dashcard-action
+  "Hydrates action from DashboardCard"
+  {:batched-hydrate :dashcard/action}
+  [dashcards]
+  (if-let [action-ids (not-empty (keep :action_id dashcards))]
+    (let [actions-by-id (m/index-by :id (select-actions :id [:in action-ids]))]
+      (for [dashcard dashcards]
+        (m/assoc-some dashcard :action (get actions-by-id (:action_id dashcard)))))
+    dashcards))
diff --git a/test/metabase/api/dashboard_test.clj b/test/metabase/api/dashboard_test.clj
index 4eac0536783..24a0b9c9dc5 100644
--- a/test/metabase/api/dashboard_test.clj
+++ b/test/metabase/api/dashboard_test.clj
@@ -1859,7 +1859,7 @@
             (is (partial= {:action_id action-id}
                           (mt/user-http-request :crowberto :post 200 (format "dashboard/%s/cards" dashboard-id)
                                                 {:sizeX 1 :sizeY 1 :row 1 :col 1 :action_id action-id})))
-            (is (partial= {:ordered_cards [{:action_id action-id}]}
+            (is (partial= {:ordered_cards [{:action_id action-id :action {:id action-id}}]}
                           (mt/user-http-request :crowberto :get 200 (format "dashboard/%s" dashboard-id))))))
         (testing "Updating dashcard action"
           (mt/with-temp* [Dashboard [{dashboard-id :id}]
@@ -1867,7 +1867,7 @@
             (is (partial= {:status "ok"}
                           (mt/user-http-request :crowberto :put 200 (format "dashboard/%s/cards" dashboard-id)
                                                 {:cards [(assoc dashcard :action_id action-id)]})))
-            (is (partial= {:ordered_cards [{:action_id action-id}]}
+            (is (partial= {:ordered_cards [{:action_id action-id :action {:id action-id}}]}
                           (mt/user-http-request :crowberto :get 200 (format "dashboard/%s" dashboard-id))))))))))
 
 (deftest dashcard-query-action-execution-test
-- 
GitLab