Skip to content

Commit

Permalink
Add report_dashboard.last_viewed_at
Browse files Browse the repository at this point in the history
- defaults to `now()` (it's intended to be used as a timestamp after which
we're *sure* the item hasn't been used, not a definitive timestamp we're
sure the dashboard was actually used at)

- updated whenever the QP processes a query for a dashcard
  • Loading branch information
johnswanson committed Jul 11, 2024
1 parent e62d098 commit 07f058e
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,11 @@
;; for a deprecated feature
(m/update-existing-in p [:values_source_config :card_id] fully-qualified-name->card-id)))

(defn- parse-timestamp [ts]
(if (string? ts)
(u.date/parse ts)
ts))

(defn load-dashboards!
"Loads `dashboards` (which is a sequence of maps parsed from a YAML dump of dashboards) in a given `context`."
{:added "0.40.0"}
Expand All @@ -449,6 +454,7 @@
(for [dashboard dashboards]
(-> dashboard
(update :parameters resolve-dashboard-parameters)
(update :last_viewed_at parse-timestamp)
(dissoc :dashboard_cards)
(assoc :collection_id (:collection context)
:creator_id (default-user-id)))))
Expand Down
20 changes: 20 additions & 0 deletions resources/migrations/001_update_migrations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8349,6 +8349,26 @@ databaseChangeLog:
columnName: explicit_reference
defaultValueBoolean: true

- changeSet:
id: v51.2024-07-10T12:28:10
author: johnswanson
comment: Add `last_viewed_at` to dashboards
changes:
- addColumn:
tableName: report_dashboard
columns:
- column:
name: last_viewed_at
type: ${timestamp_type}
remarks: Timestamp of when this dashboard was last viewed
defaultValueComputed: current_timestamp
constraints:
nullable: false
rollback:
- dropColumn:
tableName: report_dashboard
columnName: last_viewed_at

# >>>>>>>>>> DO NOT ADD NEW MIGRATIONS BELOW THIS LINE! ADD THEM ABOVE <<<<<<<<<<

########################################################################################################################
Expand Down
11 changes: 11 additions & 0 deletions src/metabase/events/view_log.clj
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@
(catch Throwable e
(log/warnf e "Failed to process view event. %s" topic)))))

(derive ::dashboard-queried :metabase/event)
(derive :event/dashboard-queried ::dashboard-queried)

(m/defmethod events/publish-event! ::dashboard-queried
"Handle processing for a dashboard query being run"
[topic {:keys [object-id] :as _event}]
(try
(t2/update! :model/Dashboard {:id object-id} {:last_viewed_at :%now})
(catch Throwable e
(log/warnf e "Failed to process dashboard query event. %s" topic))))

(derive ::collection-read-event :metabase/event)
(derive :event/collection-read ::collection-read-event)

Expand Down
3 changes: 2 additions & 1 deletion src/metabase/models/dashboard.clj
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@
;; lower-numbered positions appearing before higher numbered ones.
;; TODO: querying on stats we don't have any dashboard that has a position, maybe we could just drop it?
:public_uuid :made_public_by_id
:position :initially_published_at :view_count])
:position :initially_published_at :view_count
:last_viewed_at])

(def ^:private excluded-columns-for-dashcard-revision
[:entity_id :created_at :updated_at :collection_authority_level])
Expand Down
2 changes: 2 additions & 0 deletions src/metabase/query_processor/dashboard.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[medley.core :as m]
[metabase.api.common :as api]
[metabase.driver.common.parameters.operators :as params.ops]
[metabase.events :as events]
[metabase.legacy-mbql.normalize :as mbql.normalize]
[metabase.lib.schema.id :as lib.schema.id]
[metabase.models.dashboard :as dashboard :refer [Dashboard]]
Expand Down Expand Up @@ -175,6 +176,7 @@
:attributes {:dashboard/id dashboard-id
:dashcard/id dashcard-id
:card/id card-id}}
(events/publish-event! :event/dashboard-queried {:object-id dashboard-id :user-id api/*current-user-id*})
;; make sure we can read this Dashboard. Card will get read-checked later on inside
;; [[qp.card/process-query-for-card]]
(api/read-check Dashboard dashboard-id)
Expand Down
2 changes: 2 additions & 0 deletions test/metabase/api/dashboard_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
(dissoc :id)
(assoc :created_at (boolean created_at)
:updated_at (boolean updated_at))
(update :last_viewed_at boolean)
(update :entity_id boolean)
(update :collection_id boolean)
(update :collection boolean)
Expand Down Expand Up @@ -206,6 +207,7 @@
:collection_position nil
:collection true
:created_at true ; assuming you call dashboard-response on the results
:last_viewed_at true
:description nil
:embedding_params nil
:enable_embedding false
Expand Down
2 changes: 1 addition & 1 deletion test/metabase/http_client.clj
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
;;; parse-response

(def ^:private auto-deserialize-dates-keys
#{:created_at :updated_at :last_login :date_joined :started_at :finished_at :last_analyzed :last_used_at})
#{:created_at :updated_at :last_login :date_joined :started_at :finished_at :last_analyzed :last_used_at :last_viewed_at})

(defn- auto-deserialize-dates
"Automatically recurse over `response` and look for keys that are known to correspond to dates. Parse their values and
Expand Down

0 comments on commit 07f058e

Please sign in to comment.