Initial commit: Add logistics and order_detail message types
Some checks failed
Lock Threads / action (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot EE docker images / merge (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot CE docker images / merge (push) Has been cancelled
Run Chatwoot CE spec / lint-backend (push) Has been cancelled
Run Chatwoot CE spec / lint-frontend (push) Has been cancelled
Run Chatwoot CE spec / frontend-tests (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (0, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (1, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (10, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (11, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (12, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (13, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (14, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (15, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (2, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (3, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (4, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (5, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (6, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (7, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (8, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (9, 16) (push) Has been cancelled
Run Linux nightly installer / nightly (push) Has been cancelled
Some checks failed
Lock Threads / action (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot EE docker images / merge (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot CE docker images / merge (push) Has been cancelled
Run Chatwoot CE spec / lint-backend (push) Has been cancelled
Run Chatwoot CE spec / lint-frontend (push) Has been cancelled
Run Chatwoot CE spec / frontend-tests (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (0, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (1, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (10, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (11, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (12, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (13, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (14, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (15, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (2, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (3, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (4, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (5, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (6, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (7, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (8, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (9, 16) (push) Has been cancelled
Run Linux nightly installer / nightly (push) Has been cancelled
- Add Logistics component with progress tracking - Add OrderDetail component for order information - Support data-driven steps and actions - Add blue color scale to widget SCSS - Fix node overflow and progress bar rendering issues - Add English translations for dashboard components Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
43
app/services/conversations/assignment_service.rb
Normal file
43
app/services/conversations/assignment_service.rb
Normal file
@@ -0,0 +1,43 @@
|
||||
class Conversations::AssignmentService
|
||||
def initialize(conversation:, assignee_id:, assignee_type: nil)
|
||||
@conversation = conversation
|
||||
@assignee_id = assignee_id
|
||||
@assignee_type = assignee_type
|
||||
end
|
||||
|
||||
def perform
|
||||
agent_bot_assignment? ? assign_agent_bot : assign_agent
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :conversation, :assignee_id, :assignee_type
|
||||
|
||||
def assign_agent
|
||||
conversation.assignee = assignee
|
||||
conversation.assignee_agent_bot = nil
|
||||
conversation.save!
|
||||
assignee
|
||||
end
|
||||
|
||||
def assign_agent_bot
|
||||
return unless agent_bot
|
||||
|
||||
conversation.assignee = nil
|
||||
conversation.assignee_agent_bot = agent_bot
|
||||
conversation.save!
|
||||
agent_bot
|
||||
end
|
||||
|
||||
def assignee
|
||||
@assignee ||= conversation.account.users.find_by(id: assignee_id)
|
||||
end
|
||||
|
||||
def agent_bot
|
||||
@agent_bot ||= AgentBot.accessible_to(conversation.account).find_by(id: assignee_id)
|
||||
end
|
||||
|
||||
def agent_bot_assignment?
|
||||
assignee_type.to_s == 'AgentBot'
|
||||
end
|
||||
end
|
||||
52
app/services/conversations/filter_service.rb
Normal file
52
app/services/conversations/filter_service.rb
Normal file
@@ -0,0 +1,52 @@
|
||||
class Conversations::FilterService < FilterService
|
||||
ATTRIBUTE_MODEL = 'conversation_attribute'.freeze
|
||||
|
||||
def initialize(params, user, account)
|
||||
@account = account
|
||||
super(params, user)
|
||||
end
|
||||
|
||||
def perform
|
||||
validate_query_operator
|
||||
@conversations = query_builder(@filters['conversations'])
|
||||
mine_count, unassigned_count, all_count, = set_count_for_all_conversations
|
||||
assigned_count = all_count - unassigned_count
|
||||
|
||||
{
|
||||
conversations: conversations,
|
||||
count: {
|
||||
mine_count: mine_count,
|
||||
assigned_count: assigned_count,
|
||||
unassigned_count: unassigned_count,
|
||||
all_count: all_count
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def base_relation
|
||||
conversations = @account.conversations.includes(
|
||||
:taggings, :inbox, { assignee: { avatar_attachment: [:blob] } }, { contact: { avatar_attachment: [:blob] } }, :team, :messages, :contact_inbox
|
||||
)
|
||||
|
||||
Conversations::PermissionFilterService.new(
|
||||
conversations,
|
||||
@user,
|
||||
@account
|
||||
).perform
|
||||
end
|
||||
|
||||
def current_page
|
||||
@params[:page] || 1
|
||||
end
|
||||
|
||||
def filter_config
|
||||
{
|
||||
entity: 'Conversation',
|
||||
table_name: 'conversations'
|
||||
}
|
||||
end
|
||||
|
||||
def conversations
|
||||
@conversations.sort_on_last_activity_at.page(current_page)
|
||||
end
|
||||
end
|
||||
70
app/services/conversations/message_window_service.rb
Normal file
70
app/services/conversations/message_window_service.rb
Normal file
@@ -0,0 +1,70 @@
|
||||
class Conversations::MessageWindowService
|
||||
MESSAGING_WINDOW_24_HOURS = 24.hours
|
||||
MESSAGING_WINDOW_7_DAYS = 7.days
|
||||
|
||||
def initialize(conversation)
|
||||
@conversation = conversation
|
||||
end
|
||||
|
||||
def can_reply?
|
||||
return true if messaging_window.blank?
|
||||
|
||||
last_message_in_messaging_window?(messaging_window)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def messaging_window
|
||||
case @conversation.inbox.channel_type
|
||||
when 'Channel::Api'
|
||||
api_messaging_window
|
||||
when 'Channel::FacebookPage'
|
||||
messenger_messaging_window
|
||||
when 'Channel::Instagram'
|
||||
instagram_messaging_window
|
||||
when 'Channel::Tiktok'
|
||||
tiktok_messaging_window
|
||||
when 'Channel::Whatsapp'
|
||||
MESSAGING_WINDOW_24_HOURS
|
||||
when 'Channel::TwilioSms'
|
||||
twilio_messaging_window
|
||||
end
|
||||
end
|
||||
|
||||
def last_message_in_messaging_window?(time)
|
||||
return false if last_incoming_message.nil?
|
||||
|
||||
Time.current < last_incoming_message.created_at + time
|
||||
end
|
||||
|
||||
def api_messaging_window
|
||||
return if @conversation.inbox.channel.additional_attributes['agent_reply_time_window'].blank?
|
||||
|
||||
@conversation.inbox.channel.additional_attributes['agent_reply_time_window'].to_i.hours
|
||||
end
|
||||
|
||||
# Check medium of the inbox to determine the messaging window
|
||||
def twilio_messaging_window
|
||||
@conversation.inbox.channel.medium == 'whatsapp' ? MESSAGING_WINDOW_24_HOURS : nil
|
||||
end
|
||||
|
||||
def messenger_messaging_window
|
||||
meta_messaging_window('ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT')
|
||||
end
|
||||
|
||||
def instagram_messaging_window
|
||||
meta_messaging_window('ENABLE_INSTAGRAM_CHANNEL_HUMAN_AGENT')
|
||||
end
|
||||
|
||||
def tiktok_messaging_window
|
||||
48.hours
|
||||
end
|
||||
|
||||
def meta_messaging_window(config_key)
|
||||
GlobalConfigService.load(config_key, nil) ? MESSAGING_WINDOW_7_DAYS : MESSAGING_WINDOW_24_HOURS
|
||||
end
|
||||
|
||||
def last_incoming_message
|
||||
@last_incoming_message ||= @conversation.messages&.incoming&.last
|
||||
end
|
||||
end
|
||||
31
app/services/conversations/permission_filter_service.rb
Normal file
31
app/services/conversations/permission_filter_service.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
class Conversations::PermissionFilterService
|
||||
attr_reader :conversations, :user, :account
|
||||
|
||||
def initialize(conversations, user, account)
|
||||
@conversations = conversations
|
||||
@user = user
|
||||
@account = account
|
||||
end
|
||||
|
||||
def perform
|
||||
return conversations if user_role == 'administrator'
|
||||
|
||||
accessible_conversations
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def accessible_conversations
|
||||
conversations.where(inbox: user.inboxes.where(account_id: account.id))
|
||||
end
|
||||
|
||||
def account_user
|
||||
AccountUser.find_by(account_id: account.id, user_id: user.id)
|
||||
end
|
||||
|
||||
def user_role
|
||||
account_user&.role
|
||||
end
|
||||
end
|
||||
|
||||
Conversations::PermissionFilterService.prepend_mod_with('Conversations::PermissionFilterService')
|
||||
26
app/services/conversations/typing_status_manager.rb
Normal file
26
app/services/conversations/typing_status_manager.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
class Conversations::TypingStatusManager
|
||||
include Events::Types
|
||||
|
||||
attr_reader :conversation, :user, :params
|
||||
|
||||
def initialize(conversation, user, params)
|
||||
@conversation = conversation
|
||||
@user = user
|
||||
@params = params
|
||||
end
|
||||
|
||||
def trigger_typing_event(event, is_private)
|
||||
user = @user.presence || @resource
|
||||
Rails.configuration.dispatcher.dispatch(event, Time.zone.now, conversation: @conversation, user: user, is_private: is_private)
|
||||
end
|
||||
|
||||
def toggle_typing_status
|
||||
case params[:typing_status]
|
||||
when 'on'
|
||||
trigger_typing_event(CONVERSATION_TYPING_ON, params[:is_private])
|
||||
when 'off'
|
||||
trigger_typing_event(CONVERSATION_TYPING_OFF, params[:is_private])
|
||||
end
|
||||
# Return the head :ok response from the controller
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user