From 399f9e004a3c9bd1fe766db9f3b3156ab0ad801b Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Mon, 5 Oct 2020 22:52:43 +0530 Subject: [PATCH] fix: Use last_activity_at instead of updated_at for sorting (#1281) Co-authored-by: Akash Srivastava --- .../store/modules/conversations/index.js | 1 + app/models/conversation.rb | 3 +- app/models/message.rb | 7 ++++ .../conversations/event_data_presenter.rb | 2 +- .../conversations/search.json.jbuilder | 2 +- .../partials/_conversation.json.jbuilder | 2 +- ...22_add_last_activity_at_to_conversation.rb | 35 +++++++++++++++++++ db/schema.rb | 3 +- spec/models/conversation_spec.rb | 2 +- spec/models/message_spec.rb | 4 +++ .../event_data_presenter_spec.rb | 2 +- 11 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20200927135222_add_last_activity_at_to_conversation.rb diff --git a/app/javascript/dashboard/store/modules/conversations/index.js b/app/javascript/dashboard/store/modules/conversations/index.js index 107c94b1..8290f4f5 100644 --- a/app/javascript/dashboard/store/modules/conversations/index.js +++ b/app/javascript/dashboard/store/modules/conversations/index.js @@ -92,6 +92,7 @@ export const mutations = { ); if (previousMessageIndex === -1) { chat.messages.push(message); + chat.timestamp = message.created_at; if (_state.selectedChatId === message.conversation_id) { window.bus.$emit('scrollToMessage'); } diff --git a/app/models/conversation.rb b/app/models/conversation.rb index 45093a3a..8c1099c9 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -7,6 +7,7 @@ # agent_last_seen_at :datetime # contact_last_seen_at :datetime # identifier :string +# last_activity_at :datetime not null # locked :boolean default(FALSE) # status :integer default("open"), not null # uuid :uuid not null @@ -36,7 +37,7 @@ class Conversation < ApplicationRecord enum status: { open: 0, resolved: 1, bot: 2 } - scope :latest, -> { order(updated_at: :desc) } + scope :latest, -> { order(last_activity_at: :desc) } scope :unassigned, -> { where(assignee_id: nil) } scope :assigned_to, ->(agent) { where(assignee_id: agent.id) } diff --git a/app/models/message.rb b/app/models/message.rb index f7da472c..c1348a75 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -129,6 +129,7 @@ def webhook_data def execute_after_create_commit_callbacks # rails issue with order of active record callbacks being executed # https://github.com/rails/rails/issues/20911 + set_conversation_activity dispatch_create_events send_reply execute_message_template_hooks @@ -191,4 +192,10 @@ def conversation_mail_key def validate_attachments_limit(_attachment) errors.add(attachments: 'exceeded maximum allowed') if attachments.size >= NUMBER_OF_PERMITTED_ATTACHMENTS end + + def set_conversation_activity + # rubocop:disable Rails/SkipsModelValidations + conversation.update_columns(last_activity_at: created_at) + # rubocop:enable Rails/SkipsModelValidations + end end diff --git a/app/presenters/conversations/event_data_presenter.rb b/app/presenters/conversations/event_data_presenter.rb index bf09dd0b..4a658c4c 100644 --- a/app/presenters/conversations/event_data_presenter.rb +++ b/app/presenters/conversations/event_data_presenter.rb @@ -32,7 +32,7 @@ def push_timestamps { agent_last_seen_at: agent_last_seen_at.to_i, contact_last_seen_at: contact_last_seen_at.to_i, - timestamp: created_at.to_i + timestamp: last_activity_at.to_i } end end diff --git a/app/views/api/v1/accounts/conversations/search.json.jbuilder b/app/views/api/v1/accounts/conversations/search.json.jbuilder index e55ae8f3..ca8bb58e 100644 --- a/app/views/api/v1/accounts/conversations/search.json.jbuilder +++ b/app/views/api/v1/accounts/conversations/search.json.jbuilder @@ -11,7 +11,7 @@ json.data do json.status conversation.status json.muted conversation.muted? json.can_reply conversation.can_reply? - json.timestamp conversation.messages.last.try(:created_at).try(:to_i) + json.timestamp conversation.last_activity_at.to_i json.contact_last_seen_at conversation.contact_last_seen_at.to_i json.agent_last_seen_at conversation.agent_last_seen_at.to_i json.additional_attributes conversation.additional_attributes diff --git a/app/views/api/v1/conversations/partials/_conversation.json.jbuilder b/app/views/api/v1/conversations/partials/_conversation.json.jbuilder index d9068fe2..8201230f 100644 --- a/app/views/api/v1/conversations/partials/_conversation.json.jbuilder +++ b/app/views/api/v1/conversations/partials/_conversation.json.jbuilder @@ -21,7 +21,7 @@ json.inbox_id conversation.inbox_id json.status conversation.status json.muted conversation.muted? json.can_reply conversation.can_reply? -json.timestamp conversation.messages.last.try(:created_at).try(:to_i) +json.timestamp conversation.last_activity_at.to_i json.contact_last_seen_at conversation.contact_last_seen_at.to_i json.agent_last_seen_at conversation.agent_last_seen_at.to_i json.unread_count conversation.unread_incoming_messages.count diff --git a/db/migrate/20200927135222_add_last_activity_at_to_conversation.rb b/db/migrate/20200927135222_add_last_activity_at_to_conversation.rb new file mode 100644 index 00000000..353c414c --- /dev/null +++ b/db/migrate/20200927135222_add_last_activity_at_to_conversation.rb @@ -0,0 +1,35 @@ +class AddLastActivityAtToConversation < ActiveRecord::Migration[6.0] + def up + add_column :conversations, + :last_activity_at, + :datetime, + default: -> { 'CURRENT_TIMESTAMP' }, + index: true + + add_last_activity_at_to_conversations + + change_column_null(:conversations, :last_activity_at, false) + end + + def down + remove_column(:conversations, :last_activity_at) + end + + private + + def add_last_activity_at_to_conversations + ::Conversation.find_in_batches do |conversation_batch| + Rails.logger.info "Migrated till #{conversation_batch.first.id}\n" + conversation_batch.each do |conversation| + # rubocop:disable Rails/SkipsModelValidations + last_activity_at = if conversation.messages.last + conversation.messages.last.created_at + else + conversation.created_at + end + conversation.update_columns(last_activity_at: last_activity_at) + # rubocop:enable Rails/SkipsModelValidations + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index ae2cbf2e..231b95f1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_09_07_094912) do +ActiveRecord::Schema.define(version: 2020_09_27_135222) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" @@ -226,6 +226,7 @@ t.bigint "contact_inbox_id" t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false t.string "identifier" + t.datetime "last_activity_at", default: -> { "CURRENT_TIMESTAMP" }, null: false t.index ["account_id", "display_id"], name: "index_conversations_on_account_id_and_display_id", unique: true t.index ["account_id"], name: "index_conversations_on_account_id" t.index ["contact_inbox_id"], name: "index_conversations_on_contact_inbox_id" diff --git a/spec/models/conversation_spec.rb b/spec/models/conversation_spec.rb index 383bf972..4a1642b7 100644 --- a/spec/models/conversation_spec.rb +++ b/spec/models/conversation_spec.rb @@ -370,7 +370,7 @@ messages: [], inbox_id: conversation.inbox_id, status: conversation.status, - timestamp: conversation.created_at.to_i, + timestamp: conversation.last_activity_at.to_i, can_reply: true, channel: 'Channel::WebWidget', contact_last_seen_at: conversation.contact_last_seen_at.to_i, diff --git a/spec/models/message_spec.rb b/spec/models/message_spec.rb index b7b78da9..290bdef0 100644 --- a/spec/models/message_spec.rb +++ b/spec/models/message_spec.rb @@ -12,6 +12,10 @@ context 'when message is created' do let(:message) { build(:message, account: create(:account)) } + it 'updates conversation last_activity_at when created' do + expect(message.created_at).to eq message.conversation.last_activity_at + end + it 'triggers ::MessageTemplates::HookExecutionService' do hook_execution_service = double allow(::MessageTemplates::HookExecutionService).to receive(:new).and_return(hook_execution_service) diff --git a/spec/presenters/conversations/event_data_presenter_spec.rb b/spec/presenters/conversations/event_data_presenter_spec.rb index 430c7280..5c8cbd00 100644 --- a/spec/presenters/conversations/event_data_presenter_spec.rb +++ b/spec/presenters/conversations/event_data_presenter_spec.rb @@ -24,7 +24,7 @@ status: conversation.status, can_reply: conversation.can_reply?, channel: conversation.inbox.channel_type, - timestamp: conversation.created_at.to_i, + timestamp: conversation.last_activity_at.to_i, contact_last_seen_at: conversation.contact_last_seen_at.to_i, agent_last_seen_at: conversation.agent_last_seen_at.to_i, unread_count: 0