Add JSON activities API endpoint (#2783)
* Add JSON events API endpoint * Add regression test for event particulars defaults * Move JSON events API to a dedicated ActivitiesController The events endpoint served both the HTML day timeline and the JSON API feed, but the two paths shared no data or behavior — the HTML side uses DayTimelinesScoped while the JSON side built its own query. Splitting into ActivitiesController gives the API its own home at GET /:account/activities.json without dragging in the timeline before_actions. Also preloads comment creator in Event.preloaded to avoid an N+1 when rendering comment eventables in the JSON feed.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
class ActivitiesController < ApplicationController
|
||||
ACTIONS = %w[
|
||||
card_assigned
|
||||
card_auto_postponed
|
||||
card_board_changed
|
||||
card_closed
|
||||
card_postponed
|
||||
card_published
|
||||
card_reopened
|
||||
card_sent_back_to_triage
|
||||
card_title_changed
|
||||
card_triaged
|
||||
card_unassigned
|
||||
comment_created
|
||||
].freeze
|
||||
|
||||
def index
|
||||
set_page_and_extract_portion_from(activities)
|
||||
end
|
||||
|
||||
private
|
||||
def activities
|
||||
Current.user.accessible_events
|
||||
.preloaded
|
||||
.where(action: ACTIONS)
|
||||
.for_creators(params[:creator_ids])
|
||||
.for_boards(params[:board_ids])
|
||||
.reverse_chronologically
|
||||
end
|
||||
end
|
||||
+4
-1
@@ -9,10 +9,13 @@ class Event < ApplicationRecord
|
||||
has_many :webhook_deliveries, class_name: "Webhook::Delivery", dependent: :delete_all
|
||||
|
||||
scope :chronologically, -> { order created_at: :asc, id: :desc }
|
||||
scope :reverse_chronologically, -> { order created_at: :desc, id: :desc }
|
||||
scope :for_creators, ->(ids) { where(creator_id: ids) if ids.present? }
|
||||
scope :for_boards, ->(ids) { where(board_id: ids) if ids.present? }
|
||||
scope :preloaded, -> {
|
||||
includes(:creator, :board, {
|
||||
eventable: [
|
||||
:goldness, :closure, :image_attachment,
|
||||
:creator, :goldness, :closure, :image_attachment,
|
||||
{ rich_text_body: :embeds_attachments },
|
||||
{ rich_text_description: :embeds_attachments },
|
||||
{ card: [ :goldness, :closure, :image_attachment ] }
|
||||
|
||||
@@ -8,4 +8,21 @@ module Event::Particulars
|
||||
def assignees
|
||||
@assignees ||= User.where id: assignee_ids
|
||||
end
|
||||
|
||||
def api_particulars
|
||||
nested = particulars.dig("particulars") || {}
|
||||
|
||||
case action.to_s
|
||||
when "card_assigned", "card_unassigned"
|
||||
{ "assignee_ids" => Array(assignee_ids) }
|
||||
when "card_board_changed"
|
||||
{ "old_board" => nested["old_board"].to_s, "new_board" => nested["new_board"].to_s }
|
||||
when "card_title_changed"
|
||||
{ "old_title" => nested["old_title"].to_s, "new_title" => nested["new_title"].to_s }
|
||||
when "card_triaged"
|
||||
{ "column" => nested["column"].to_s }
|
||||
else
|
||||
{}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
json.(event, :id, :action)
|
||||
json.created_at event.created_at.utc
|
||||
json.description event.description_for(Current.user).to_plain_text
|
||||
json.particulars event.api_particulars
|
||||
json.url(
|
||||
case event.eventable
|
||||
when Comment then card_url(event.eventable.card, anchor: dom_id(event.eventable))
|
||||
else polymorphic_url(event.eventable)
|
||||
end
|
||||
)
|
||||
json.eventable_type event.eventable_type
|
||||
|
||||
json.eventable do
|
||||
case event.eventable
|
||||
when Card then json.partial! "cards/card", card: event.eventable
|
||||
when Comment then json.partial! "cards/comments/comment", comment: event.eventable
|
||||
end
|
||||
end
|
||||
|
||||
json.board event.board, partial: "boards/board", as: :board
|
||||
json.creator event.creator, partial: "users/user", as: :user
|
||||
@@ -0,0 +1 @@
|
||||
json.array! @page.records, partial: "activities/activity", as: :event
|
||||
Reference in New Issue
Block a user