fix: Use last_activity_at instead of updated_at for sorting (#1281)
Co-authored-by: Akash Srivastava <akash.srivastava.1911@gmail.com>
This commit is contained in:
parent
ee119b2174
commit
399f9e004a
11 changed files with 56 additions and 7 deletions
|
@ -92,6 +92,7 @@ export const mutations = {
|
||||||
);
|
);
|
||||||
if (previousMessageIndex === -1) {
|
if (previousMessageIndex === -1) {
|
||||||
chat.messages.push(message);
|
chat.messages.push(message);
|
||||||
|
chat.timestamp = message.created_at;
|
||||||
if (_state.selectedChatId === message.conversation_id) {
|
if (_state.selectedChatId === message.conversation_id) {
|
||||||
window.bus.$emit('scrollToMessage');
|
window.bus.$emit('scrollToMessage');
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
# agent_last_seen_at :datetime
|
# agent_last_seen_at :datetime
|
||||||
# contact_last_seen_at :datetime
|
# contact_last_seen_at :datetime
|
||||||
# identifier :string
|
# identifier :string
|
||||||
|
# last_activity_at :datetime not null
|
||||||
# locked :boolean default(FALSE)
|
# locked :boolean default(FALSE)
|
||||||
# status :integer default("open"), not null
|
# status :integer default("open"), not null
|
||||||
# uuid :uuid not null
|
# uuid :uuid not null
|
||||||
|
@ -36,7 +37,7 @@ class Conversation < ApplicationRecord
|
||||||
|
|
||||||
enum status: { open: 0, resolved: 1, bot: 2 }
|
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 :unassigned, -> { where(assignee_id: nil) }
|
||||||
scope :assigned_to, ->(agent) { where(assignee_id: agent.id) }
|
scope :assigned_to, ->(agent) { where(assignee_id: agent.id) }
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,7 @@ class Message < ApplicationRecord
|
||||||
def execute_after_create_commit_callbacks
|
def execute_after_create_commit_callbacks
|
||||||
# rails issue with order of active record callbacks being executed
|
# rails issue with order of active record callbacks being executed
|
||||||
# https://github.com/rails/rails/issues/20911
|
# https://github.com/rails/rails/issues/20911
|
||||||
|
set_conversation_activity
|
||||||
dispatch_create_events
|
dispatch_create_events
|
||||||
send_reply
|
send_reply
|
||||||
execute_message_template_hooks
|
execute_message_template_hooks
|
||||||
|
@ -191,4 +192,10 @@ class Message < ApplicationRecord
|
||||||
def validate_attachments_limit(_attachment)
|
def validate_attachments_limit(_attachment)
|
||||||
errors.add(attachments: 'exceeded maximum allowed') if attachments.size >= NUMBER_OF_PERMITTED_ATTACHMENTS
|
errors.add(attachments: 'exceeded maximum allowed') if attachments.size >= NUMBER_OF_PERMITTED_ATTACHMENTS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_conversation_activity
|
||||||
|
# rubocop:disable Rails/SkipsModelValidations
|
||||||
|
conversation.update_columns(last_activity_at: created_at)
|
||||||
|
# rubocop:enable Rails/SkipsModelValidations
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Conversations::EventDataPresenter < SimpleDelegator
|
||||||
{
|
{
|
||||||
agent_last_seen_at: agent_last_seen_at.to_i,
|
agent_last_seen_at: agent_last_seen_at.to_i,
|
||||||
contact_last_seen_at: contact_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
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,7 @@ json.data do
|
||||||
json.status conversation.status
|
json.status conversation.status
|
||||||
json.muted conversation.muted?
|
json.muted conversation.muted?
|
||||||
json.can_reply conversation.can_reply?
|
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.contact_last_seen_at conversation.contact_last_seen_at.to_i
|
||||||
json.agent_last_seen_at conversation.agent_last_seen_at.to_i
|
json.agent_last_seen_at conversation.agent_last_seen_at.to_i
|
||||||
json.additional_attributes conversation.additional_attributes
|
json.additional_attributes conversation.additional_attributes
|
||||||
|
|
|
@ -21,7 +21,7 @@ json.inbox_id conversation.inbox_id
|
||||||
json.status conversation.status
|
json.status conversation.status
|
||||||
json.muted conversation.muted?
|
json.muted conversation.muted?
|
||||||
json.can_reply conversation.can_reply?
|
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.contact_last_seen_at conversation.contact_last_seen_at.to_i
|
||||||
json.agent_last_seen_at conversation.agent_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
|
json.unread_count conversation.unread_incoming_messages.count
|
||||||
|
|
|
@ -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
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pgcrypto"
|
enable_extension "pgcrypto"
|
||||||
|
@ -226,6 +226,7 @@ ActiveRecord::Schema.define(version: 2020_09_07_094912) do
|
||||||
t.bigint "contact_inbox_id"
|
t.bigint "contact_inbox_id"
|
||||||
t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false
|
t.uuid "uuid", default: -> { "gen_random_uuid()" }, null: false
|
||||||
t.string "identifier"
|
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", "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 ["account_id"], name: "index_conversations_on_account_id"
|
||||||
t.index ["contact_inbox_id"], name: "index_conversations_on_contact_inbox_id"
|
t.index ["contact_inbox_id"], name: "index_conversations_on_contact_inbox_id"
|
||||||
|
|
|
@ -370,7 +370,7 @@ RSpec.describe Conversation, type: :model do
|
||||||
messages: [],
|
messages: [],
|
||||||
inbox_id: conversation.inbox_id,
|
inbox_id: conversation.inbox_id,
|
||||||
status: conversation.status,
|
status: conversation.status,
|
||||||
timestamp: conversation.created_at.to_i,
|
timestamp: conversation.last_activity_at.to_i,
|
||||||
can_reply: true,
|
can_reply: true,
|
||||||
channel: 'Channel::WebWidget',
|
channel: 'Channel::WebWidget',
|
||||||
contact_last_seen_at: conversation.contact_last_seen_at.to_i,
|
contact_last_seen_at: conversation.contact_last_seen_at.to_i,
|
||||||
|
|
|
@ -12,6 +12,10 @@ RSpec.describe Message, type: :model do
|
||||||
context 'when message is created' do
|
context 'when message is created' do
|
||||||
let(:message) { build(:message, account: create(:account)) }
|
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
|
it 'triggers ::MessageTemplates::HookExecutionService' do
|
||||||
hook_execution_service = double
|
hook_execution_service = double
|
||||||
allow(::MessageTemplates::HookExecutionService).to receive(:new).and_return(hook_execution_service)
|
allow(::MessageTemplates::HookExecutionService).to receive(:new).and_return(hook_execution_service)
|
||||||
|
|
|
@ -24,7 +24,7 @@ RSpec.describe Conversations::EventDataPresenter do
|
||||||
status: conversation.status,
|
status: conversation.status,
|
||||||
can_reply: conversation.can_reply?,
|
can_reply: conversation.can_reply?,
|
||||||
channel: conversation.inbox.channel_type,
|
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,
|
contact_last_seen_at: conversation.contact_last_seen_at.to_i,
|
||||||
agent_last_seen_at: conversation.agent_last_seen_at.to_i,
|
agent_last_seen_at: conversation.agent_last_seen_at.to_i,
|
||||||
unread_count: 0
|
unread_count: 0
|
||||||
|
|
Loading…
Reference in a new issue