diff --git a/app/assets/stylesheets/administrate/components/_search.scss b/app/assets/stylesheets/administrate/components/_search.scss
index 9b61a696a..f3a259618 100644
--- a/app/assets/stylesheets/administrate/components/_search.scss
+++ b/app/assets/stylesheets/administrate/components/_search.scss
@@ -1,7 +1,7 @@
.search {
margin-left: auto;
margin-right: 2rem;
- max-width: 24rem;
+ max-width: 44rem;
position: relative;
width: 100%;
}
diff --git a/app/controllers/api/v1/accounts/conversations_controller.rb b/app/controllers/api/v1/accounts/conversations_controller.rb
index 849c36942..fcda432a5 100644
--- a/app/controllers/api/v1/accounts/conversations_controller.rb
+++ b/app/controllers/api/v1/accounts/conversations_controller.rb
@@ -27,7 +27,12 @@ class Api::V1::Accounts::ConversationsController < Api::BaseController
end
def toggle_status
- @status = @conversation.toggle_status
+ if params[:status]
+ @conversation.status = params[:status]
+ @status = @conversation.save
+ else
+ @status = @conversation.toggle_status
+ end
end
def toggle_typing_status
diff --git a/app/controllers/super_admin/account_users_controller.rb b/app/controllers/super_admin/account_users_controller.rb
index bf86a5af6..b210dea19 100644
--- a/app/controllers/super_admin/account_users_controller.rb
+++ b/app/controllers/super_admin/account_users_controller.rb
@@ -6,18 +6,8 @@ class SuperAdmin::AccountUsersController < SuperAdmin::ApplicationController
resource = resource_class.new(resource_params)
authorize_resource(resource)
- redirect_resource = params[:redirect_to] == 'user' ? resource.user : resource.account
- if resource.save
- redirect_to(
- [namespace, redirect_resource],
- notice: translate_with_resource('create.success')
- )
- else
- redirect_to(
- [namespace, redirect_resource],
- notice: resource.errors.full_messages.first
- )
- end
+ notice = resource.save ? translate_with_resource('create.success') : resource.errors.full_messages.first
+ redirect_back(fallback_location: [namespace, resource.account], notice: notice)
end
def destroy
@@ -26,7 +16,7 @@ class SuperAdmin::AccountUsersController < SuperAdmin::ApplicationController
else
flash[:error] = requested_resource.errors.full_messages.join('
')
end
- redirect_to([namespace, requested_resource.account])
+ redirect_back(fallback_location: [namespace, requested_resource.account])
end
# Override this method to specify custom lookup behavior.
diff --git a/app/controllers/super_admin/agent_bots_controller.rb b/app/controllers/super_admin/agent_bots_controller.rb
new file mode 100644
index 000000000..8e094e752
--- /dev/null
+++ b/app/controllers/super_admin/agent_bots_controller.rb
@@ -0,0 +1,44 @@
+class SuperAdmin::AgentBotsController < SuperAdmin::ApplicationController
+ # Overwrite any of the RESTful controller actions to implement custom behavior
+ # For example, you may want to send an email after a foo is updated.
+ #
+ # def update
+ # super
+ # send_foo_updated_email(requested_resource)
+ # end
+
+ # Override this method to specify custom lookup behavior.
+ # This will be used to set the resource for the `show`, `edit`, and `update`
+ # actions.
+ #
+ # def find_resource(param)
+ # Foo.find_by!(slug: param)
+ # end
+
+ # The result of this lookup will be available as `requested_resource`
+
+ # Override this if you have certain roles that require a subset
+ # this will be used to set the records shown on the `index` action.
+ #
+ # def scoped_resource
+ # if current_user.super_admin?
+ # resource_class
+ # else
+ # resource_class.with_less_stuff
+ # end
+ # end
+
+ # Override `resource_params` if you want to transform the submitted
+ # data before it's persisted. For example, the following would turn all
+ # empty values into nil values. It uses other APIs such as `resource_class`
+ # and `dashboard`:
+ #
+ # def resource_params
+ # params.require(resource_class.model_name.param_key).
+ # permit(dashboard.permitted_attributes).
+ # transform_values { |value| value == "" ? nil : value }
+ # end
+
+ # See https://administrate-prototype.herokuapp.com/customizing_controller_actions
+ # for more information
+end
diff --git a/app/dashboards/access_token_dashboard.rb b/app/dashboards/access_token_dashboard.rb
index bdc50a7db..6864b99d4 100644
--- a/app/dashboards/access_token_dashboard.rb
+++ b/app/dashboards/access_token_dashboard.rb
@@ -55,7 +55,11 @@ class AccessTokenDashboard < Administrate::BaseDashboard
# COLLECTION_FILTERS = {
# open: ->(resources) { resources.where(open: true) }
# }.freeze
- COLLECTION_FILTERS = {}.freeze
+ COLLECTION_FILTERS = {
+ user: ->(resources) { resources.where(owner_type: 'User') },
+ super_admin: ->(resources) { resources.where(owner_type: 'SuperAdmin') },
+ agent_bot: ->(resources) { resources.where(owner_type: 'AgentBot') }
+ }.freeze
# Overwrite this method to customize how access tokens are displayed
# across all pages of the admin dashboard.
diff --git a/app/dashboards/agent_bot_dashboard.rb b/app/dashboards/agent_bot_dashboard.rb
new file mode 100644
index 000000000..ca6ca7ad1
--- /dev/null
+++ b/app/dashboards/agent_bot_dashboard.rb
@@ -0,0 +1,73 @@
+require 'administrate/base_dashboard'
+
+class AgentBotDashboard < Administrate::BaseDashboard
+ # ATTRIBUTE_TYPES
+ # a hash that describes the type of each of the model's fields.
+ #
+ # Each different type represents an Administrate::Field object,
+ # which determines how the attribute is displayed
+ # on pages throughout the dashboard.
+ ATTRIBUTE_TYPES = {
+ access_token: Field::HasOne,
+ avatar_url: AvatarField,
+ id: Field::Number,
+ name: Field::String,
+ description: Field::String,
+ outgoing_url: Field::String,
+ created_at: Field::DateTime,
+ updated_at: Field::DateTime,
+ hide_input_for_bot_conversations: Field::Boolean
+ }.freeze
+
+ # COLLECTION_ATTRIBUTES
+ # an array of attributes that will be displayed on the model's index page.
+ #
+ # By default, it's limited to four items to reduce clutter on index pages.
+ # Feel free to add, remove, or rearrange items.
+ COLLECTION_ATTRIBUTES = %i[
+ id
+ avatar_url
+ name
+ outgoing_url
+ ].freeze
+
+ # SHOW_PAGE_ATTRIBUTES
+ # an array of attributes that will be displayed on the model's show page.
+ SHOW_PAGE_ATTRIBUTES = %i[
+ id
+ avatar_url
+ name
+ description
+ outgoing_url
+ hide_input_for_bot_conversations
+ ].freeze
+
+ # FORM_ATTRIBUTES
+ # an array of attributes that will be displayed
+ # on the model's form (`new` and `edit`) pages.
+ FORM_ATTRIBUTES = %i[
+ name
+ description
+ outgoing_url
+ hide_input_for_bot_conversations
+ ].freeze
+
+ # COLLECTION_FILTERS
+ # a hash that defines filters that can be used while searching via the search
+ # field of the dashboard.
+ #
+ # For example to add an option to search for open resources by typing "open:"
+ # in the search field:
+ #
+ # COLLECTION_FILTERS = {
+ # open: ->(resources) { resources.where(open: true) }
+ # }.freeze
+ COLLECTION_FILTERS = {}.freeze
+
+ # Overwrite this method to customize how agent bots are displayed
+ # across all pages of the admin dashboard.
+ #
+ # def display_resource(agent_bot)
+ # "AgentBot ##{agent_bot.id}"
+ # end
+end
diff --git a/app/models/conversation.rb b/app/models/conversation.rb
index 07a9e9fc2..db25c27da 100644
--- a/app/models/conversation.rb
+++ b/app/models/conversation.rb
@@ -50,13 +50,11 @@ class Conversation < ApplicationRecord
has_many :messages, dependent: :destroy, autosave: true
before_create :set_display_id, unless: :display_id?
-
before_create :set_bot_conversation
-
+ after_create :notify_conversation_creation
+ after_save :run_round_robin
after_update :notify_status_change, :create_activity
- after_create :notify_conversation_creation, :run_round_robin
-
acts_as_taggable_on :labels
def update_assignee(agent = nil)
@@ -173,10 +171,24 @@ class Conversation < ApplicationRecord
Rails.configuration.dispatcher.dispatch(event_name, Time.zone.now, conversation: self)
end
+ def should_round_robin?
+ return false unless inbox.enable_auto_assignment?
+
+ # run only if assignee is blank or doesn't have access to inbox
+ assignee.blank? || inbox.members.exclude?(assignee)
+ end
+
+ def conversation_status_changed_to_open?
+ return false unless open?
+ # saved_change_to_status? method only works in case of update
+ return true if previous_changes.key?(:id) || saved_change_to_status?
+ end
+
def run_round_robin
- return unless inbox.enable_auto_assignment
- return if assignee
- return if bot?
+ # Round robin kicks in on conversation create & update
+ # run it only when conversation status changes to open
+ return unless conversation_status_changed_to_open?
+ return unless should_round_robin?
inbox.next_available_agent.then { |new_assignee| update_assignee(new_assignee) }
end
diff --git a/app/services/message_templates/template/email_collect.rb b/app/services/message_templates/template/email_collect.rb
index 07004081e..e9e830d3b 100644
--- a/app/services/message_templates/template/email_collect.rb
+++ b/app/services/message_templates/template/email_collect.rb
@@ -18,8 +18,11 @@ class MessageTemplates::Template::EmailCollect
delegate :inbox, to: :message
def typical_reply_message_params
- content = I18n.t('conversations.templates.typical_reply_message_body',
- account_name: account.name)
+ content = @conversation.inbox&.channel&.agent_away_message
+ if content.blank?
+ content = I18n.t('conversations.templates.typical_reply_message_body',
+ account_name: account.name)
+ end
{
account_id: @conversation.account_id,
diff --git a/app/views/api/v1/models/_user.json.jbuilder b/app/views/api/v1/models/_user.json.jbuilder
index 4fdacf14a..5638fc233 100644
--- a/app/views/api/v1/models/_user.json.jbuilder
+++ b/app/views/api/v1/models/_user.json.jbuilder
@@ -4,10 +4,10 @@ json.uid resource.uid
json.name resource.name
json.nickname resource.nickname
json.email resource.email
-json.account_id resource.active_account_user.account_id
+json.account_id resource.active_account_user&.account_id
json.pubsub_token resource.pubsub_token
-json.role resource.active_account_user.role
-json.inviter_id resource.active_account_user.inviter_id
+json.role resource.active_account_user&.role
+json.inviter_id resource.active_account_user&.inviter_id
json.confirmed resource.confirmed?
json.avatar_url resource.avatar_url
json.access_token resource.access_token.token
diff --git a/app/views/super_admin/accounts/show.html.erb b/app/views/super_admin/accounts/show.html.erb
index ca08929a6..93cd37945 100644
--- a/app/views/super_admin/accounts/show.html.erb
+++ b/app/views/super_admin/accounts/show.html.erb
@@ -72,7 +72,6 @@ as well as a link to its edit page.
<% account_user_page.attributes.each do |attribute| -%>
<% if attribute.name == "account" %>
<%= f.hidden_field('account_id', value: page.resource.id) %>
- <%= f.hidden_field('redirect_to', value: 'user') %>
<% else %>