* fix(featurable): backport feature_flag_value helper from chatwoot-pro-main Adds the two's-complement-aware helper that returns a signed bigint-safe value for SQL queries against the feature_flags column. Mirrors the existing helper in chatwoot-pro-main so future backports of pro features that reference it (e.g. kanban filters) compile cleanly on main. Note: the helper does NOT fix FlagShihTzu's write path; new account-level toggles should use account.settings jsonb instead of feature_flags (see AGENTS.md). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(super-admin): toggle to hide assignee tabs for basic agents Adds two account-level settings, configurable from the super admin dashboard, that hide the "Unassigned" and "All" tabs of the conversation list for users with the basic agent role (admins and custom roles are unaffected). Hiding "Unassigned" implicitly hides "All", since seeing the full queue without the unassigned subset is incoherent. The constraint is enforced both in the backend (before_validation forces hide_agent_all_tab=true when hide_agent_unassigned_tab is on) and in the super admin form (the "All" checkbox is disabled and auto-checked when "Unassigned" is checked). Storage uses account.settings (jsonb) instead of feature_flags to sidestep the bigint bit-position overflow that happens once features.yml crosses 64 entries, and to keep keys stable across the main and chatwoot-pro-main forks where feature bit positions diverge. AGENTS.md documents the rationale and the recipe to add future toggles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(chat-list): guard activeAssigneeTabCount against missing tab When the visibility settings hide the currently selected tab, the fallback watch resets activeAssigneeTab to ME, but activeAssigneeTabCount re-evaluates in the same reactive cycle and can read .count on undefined before the watch flushes. Use optional chaining + nullish fallback so the count safely returns 0 during the brief inconsistency. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
134 lines
4.9 KiB
Ruby
134 lines
4.9 KiB
Ruby
require 'administrate/base_dashboard'
|
|
|
|
class AccountDashboard < 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.
|
|
|
|
enterprise_attribute_types = if ChatwootApp.enterprise?
|
|
attributes = {
|
|
limits: AccountLimitsField
|
|
}
|
|
|
|
# Only show manually managed features in Chatwoot Cloud deployment
|
|
attributes[:manually_managed_features] = ManuallyManagedFeaturesField if ChatwootApp.chatwoot_cloud?
|
|
|
|
# Add all_features last so it appears after manually_managed_features
|
|
attributes[:all_features] = AccountFeaturesField
|
|
|
|
attributes
|
|
else
|
|
{}
|
|
end
|
|
|
|
ATTRIBUTE_TYPES = {
|
|
id: Field::Number.with_options(searchable: true),
|
|
name: Field::String.with_options(searchable: true),
|
|
created_at: Field::DateTime,
|
|
updated_at: Field::DateTime,
|
|
users: CountField,
|
|
conversations: CountField,
|
|
locale: Field::Select.with_options(collection: LANGUAGES_CONFIG.map { |_x, y| y[:iso_639_1_code] }),
|
|
status: Field::Select.with_options(collection: [%w[Active active], %w[Suspended suspended]]),
|
|
account_users: Field::HasMany,
|
|
custom_attributes: Field::String,
|
|
hide_agent_unassigned_tab: Field::Boolean,
|
|
hide_agent_all_tab: HideAgentAllTabField
|
|
}.merge(enterprise_attribute_types).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
|
|
name
|
|
locale
|
|
users
|
|
conversations
|
|
status
|
|
].freeze
|
|
|
|
# SHOW_PAGE_ATTRIBUTES
|
|
# an array of attributes that will be displayed on the model's show page.
|
|
enterprise_show_page_attributes = if ChatwootApp.enterprise?
|
|
attrs = %i[custom_attributes limits]
|
|
attrs << :manually_managed_features if ChatwootApp.chatwoot_cloud?
|
|
attrs << :all_features
|
|
attrs
|
|
else
|
|
[]
|
|
end
|
|
SHOW_PAGE_ATTRIBUTES = (%i[
|
|
id
|
|
name
|
|
created_at
|
|
updated_at
|
|
locale
|
|
status
|
|
conversations
|
|
account_users
|
|
hide_agent_unassigned_tab
|
|
hide_agent_all_tab
|
|
] + enterprise_show_page_attributes).freeze
|
|
|
|
# FORM_ATTRIBUTES
|
|
# an array of attributes that will be displayed
|
|
# on the model's form (`new` and `edit`) pages.
|
|
enterprise_form_attributes = if ChatwootApp.enterprise?
|
|
attrs = %i[limits]
|
|
attrs << :manually_managed_features if ChatwootApp.chatwoot_cloud?
|
|
attrs << :all_features
|
|
attrs
|
|
else
|
|
[]
|
|
end
|
|
FORM_ATTRIBUTES = (%i[
|
|
name
|
|
locale
|
|
status
|
|
hide_agent_unassigned_tab
|
|
hide_agent_all_tab
|
|
] + enterprise_form_attributes).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 = {
|
|
active: ->(resources) { resources.where(status: :active) },
|
|
suspended: ->(resources) { resources.where(status: :suspended) },
|
|
recent: ->(resources) { resources.where('created_at > ?', 30.days.ago) },
|
|
marked_for_deletion: ->(resources) { resources.where("custom_attributes->>'marked_for_deletion_at' IS NOT NULL") }
|
|
}.freeze
|
|
|
|
# Overwrite this method to customize how accounts are displayed
|
|
# across all pages of the admin dashboard.
|
|
#
|
|
def display_resource(account)
|
|
"##{account.id} #{account.name}"
|
|
end
|
|
|
|
# We do not use the action parameter but we still need to define it
|
|
# to prevent an error from being raised (wrong number of arguments)
|
|
# Reference: https://github.com/thoughtbot/administrate/pull/2356/files#diff-4e220b661b88f9a19ac527c50d6f1577ef6ab7b0bed2bfdf048e22e6bfa74a05R204
|
|
def permitted_attributes(action)
|
|
attrs = super + [limits: {}]
|
|
|
|
# Add manually_managed_features to permitted attributes only for Chatwoot Cloud
|
|
attrs << { manually_managed_features: [] } if ChatwootApp.chatwoot_cloud?
|
|
|
|
attrs
|
|
end
|
|
end
|