From 13b4fdb34ce13aba73483eb583e3849a546c81cb Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Tue, 15 Jul 2025 21:28:39 -0700 Subject: [PATCH] chore: Add submenu for super admin settings (#11860) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Improve how settings are rendered in Chatwoot Super admin panel - Add google settings support - show setting for community edition ## Settings page - community edition Screenshot 2025-07-08 at 9 08 03 PM ## Expanded settings Screenshot 2025-07-03 at 2 17 16 AM --------- Co-authored-by: Sojan Jose Co-authored-by: Muhsin Keloth --- .../super_admin/app_configs_controller.rb | 3 +- .../super_admin/application_controller.rb | 3 +- .../helpers/super_admin/features.yml | 35 +++++++++++---- .../helpers/super_admin/features_helper.rb | 2 +- app/helpers/super_admin/navigation_helper.rb | 16 +++++++ .../super_admin/application/_icons.html.erb | 6 +++ .../application/_nav_item.html.erb | 4 +- .../application/_navigation.html.erb | 5 +-- .../application/_settings_menu.html.erb | 24 +++++++++++ .../_upgrade_button_community.html.erb | 4 ++ .../_upgrade_button_enterprise.html.erb | 4 ++ app/views/super_admin/settings/show.html.erb | 43 ++++++++++--------- config/installation_config.yml | 22 ++++++++++ lib/chatwoot_hub.rb | 4 ++ 14 files changed, 137 insertions(+), 38 deletions(-) rename {enterprise/app => app}/helpers/super_admin/features.yml (90%) rename {enterprise/app => app}/helpers/super_admin/features_helper.rb (78%) create mode 100644 app/helpers/super_admin/navigation_helper.rb create mode 100644 app/views/super_admin/application/_settings_menu.html.erb create mode 100644 app/views/super_admin/settings/_upgrade_button_community.html.erb create mode 100644 app/views/super_admin/settings/_upgrade_button_enterprise.html.erb diff --git a/app/controllers/super_admin/app_configs_controller.rb b/app/controllers/super_admin/app_configs_controller.rb index 3972d5a28..5cf158b98 100644 --- a/app/controllers/super_admin/app_configs_controller.rb +++ b/app/controllers/super_admin/app_configs_controller.rb @@ -41,7 +41,8 @@ class SuperAdmin::AppConfigsController < SuperAdmin::ApplicationController 'slack' => %w[SLACK_CLIENT_ID SLACK_CLIENT_SECRET], 'instagram' => %w[INSTAGRAM_APP_ID INSTAGRAM_APP_SECRET INSTAGRAM_VERIFY_TOKEN INSTAGRAM_API_VERSION ENABLE_INSTAGRAM_CHANNEL_HUMAN_AGENT], 'whatsapp_embedded' => %w[WHATSAPP_APP_ID WHATSAPP_APP_SECRET WHATSAPP_CONFIGURATION_ID WHATSAPP_API_VERSION], - 'notion' => %w[NOTION_CLIENT_ID NOTION_CLIENT_SECRET] + 'notion' => %w[NOTION_CLIENT_ID NOTION_CLIENT_SECRET], + 'google' => %w[GOOGLE_OAUTH_CLIENT_ID GOOGLE_OAUTH_CLIENT_SECRET GOOGLE_OAUTH_REDIRECT_URI] } @allowed_configs = mapping.fetch(@config, %w[ENABLE_ACCOUNT_SIGNUP FIREBASE_PROJECT_ID FIREBASE_CREDENTIALS]) diff --git a/app/controllers/super_admin/application_controller.rb b/app/controllers/super_admin/application_controller.rb index 775fb34fc..5b04fbb44 100644 --- a/app/controllers/super_admin/application_controller.rb +++ b/app/controllers/super_admin/application_controller.rb @@ -7,8 +7,9 @@ class SuperAdmin::ApplicationController < Administrate::ApplicationController include ActionView::Helpers::TagHelper include ActionView::Context + include SuperAdmin::NavigationHelper - helper_method :render_vue_component + helper_method :render_vue_component, :settings_open?, :settings_pages # authenticiation done via devise : SuperAdmin Model before_action :authenticate_super_admin! diff --git a/enterprise/app/helpers/super_admin/features.yml b/app/helpers/super_admin/features.yml similarity index 90% rename from enterprise/app/helpers/super_admin/features.yml rename to app/helpers/super_admin/features.yml index f2b2b263c..f49004e79 100644 --- a/enterprise/app/helpers/super_admin/features.yml +++ b/app/helpers/super_admin/features.yml @@ -1,5 +1,7 @@ # TODO: Move this values to features.yml itself # No need to replicate the same values in two places + +# ------- Premium Features ------- # captain: name: 'Captain' description: 'Enable AI-powered conversations with your customers.' @@ -32,6 +34,15 @@ disable_branding: enabled: <%= (ChatwootHub.pricing_plan != 'community') %> icon: 'icon-sailbot-fill' enterprise: true + +# ------- Product Features ------- # +help_center: + name: 'Help Center' + description: 'Allow agents to create help center articles and publish them in a portal.' + enabled: true + icon: 'icon-book-2-line' + +# ------- Communication Channels ------- # live_chat: name: 'Live Chat' description: 'Improve your customer experience using a live chat on your website.' @@ -42,6 +53,12 @@ email: description: 'Manage your email customer interactions from Chatwoot.' enabled: true icon: 'icon-mail-send-fill' + config_key: 'email' +sms: + name: 'SMS' + description: 'Manage your SMS customer interactions from Chatwoot.' + enabled: true + icon: 'icon-message-line' messenger: name: 'Messenger' description: 'Stay connected with your customers on Facebook & Instagram.' @@ -69,22 +86,22 @@ line: description: 'Manage your Line customer interactions from Chatwoot.' enabled: true icon: 'icon-line-line' -sms: - name: 'SMS' - description: 'Manage your SMS customer interactions from Chatwoot.' + +# ------- OAuth & Authentication ------- # +google: + name: 'Google' + description: 'Configuration for setting up Google OAuth Integration' enabled: true - icon: 'icon-message-line' -help_center: - name: 'Help Center' - description: 'Allow agents to create help center articles and publish them in a portal.' - enabled: true - icon: 'icon-book-2-line' + icon: 'icon-google' + config_key: 'google' microsoft: name: 'Microsoft' description: 'Configuration for setting up Microsoft Email' enabled: true icon: 'icon-microsoft' config_key: 'microsoft' + +# ------- Third-party Integrations ------- # linear: name: 'Linear' description: 'Configuration for setting up Linear Integration' diff --git a/enterprise/app/helpers/super_admin/features_helper.rb b/app/helpers/super_admin/features_helper.rb similarity index 78% rename from enterprise/app/helpers/super_admin/features_helper.rb rename to app/helpers/super_admin/features_helper.rb index 2fbcd1715..475ad6d25 100644 --- a/enterprise/app/helpers/super_admin/features_helper.rb +++ b/app/helpers/super_admin/features_helper.rb @@ -1,6 +1,6 @@ module SuperAdmin::FeaturesHelper def self.available_features - YAML.load(ERB.new(Rails.root.join('enterprise/app/helpers/super_admin/features.yml').read).result).with_indifferent_access + YAML.load(ERB.new(Rails.root.join('app/helpers/super_admin/features.yml').read).result).with_indifferent_access end def self.plan_details diff --git a/app/helpers/super_admin/navigation_helper.rb b/app/helpers/super_admin/navigation_helper.rb new file mode 100644 index 000000000..5fca3fa76 --- /dev/null +++ b/app/helpers/super_admin/navigation_helper.rb @@ -0,0 +1,16 @@ +module SuperAdmin::NavigationHelper + def settings_open? + params[:controller].in? %w[super_admin/settings super_admin/app_configs] + end + + def settings_pages + features = SuperAdmin::FeaturesHelper.available_features.select do |_feature, attrs| + attrs['config_key'].present? && attrs['enabled'] + end + + # Add general at the beginning + general_feature = [['general', { 'config_key' => 'general', 'name' => 'General' }]] + + general_feature + features.to_a + end +end diff --git a/app/views/super_admin/application/_icons.html.erb b/app/views/super_admin/application/_icons.html.erb index 6669fe87d..a45c4c1b3 100644 --- a/app/views/super_admin/application/_icons.html.erb +++ b/app/views/super_admin/application/_icons.html.erb @@ -2,6 +2,12 @@ + + + + + + diff --git a/app/views/super_admin/application/_nav_item.html.erb b/app/views/super_admin/application/_nav_item.html.erb index a6366d8b5..a32fddd11 100644 --- a/app/views/super_admin/application/_nav_item.html.erb +++ b/app/views/super_admin/application/_nav_item.html.erb @@ -1,6 +1,4 @@ -
  • +
  • <% text_class_name = current_page?(url) ? 'text-woot-500 bg-slate-25' : 'text-slate-800' %> <%= link_to(url, class: text_class_name + " -ml-1 focus:outline-none cursor-pointer flex items-center px-2 py-1.5 text-slate-800 cursor-pointer hover:text-woot-500 hover:bg-slate-25 rounded-lg") do %> diff --git a/app/views/super_admin/application/_navigation.html.erb b/app/views/super_admin/application/_navigation.html.erb index f673c6bd1..787576d33 100644 --- a/app/views/super_admin/application/_navigation.html.erb +++ b/app/views/super_admin/application/_navigation.html.erb @@ -39,14 +39,13 @@ as defined by the routes in the `admin/` namespace label: display_resource_name(resource), } %> + <% end %> + <%= render 'settings_menu', open: settings_open? %>
      - <% if ChatwootApp.enterprise? %> - <%= render partial: "nav_item", locals: { icon: 'icon-settings-2-line', url: super_admin_settings_url, label: 'Settings' } %> - <% end %> <%= render partial: "nav_item", locals: { icon: 'icon-mist-fill', url: sidekiq_web_url, label: 'Sidekiq Dashboard' } %> <%= render partial: "nav_item", locals: { icon: 'icon-health-book-line', url: super_admin_instance_status_url, label: 'Instance Health' } %> <%= render partial: "nav_item", locals: { icon: 'icon-dashboard-line', url: '/', label: 'Agent Dashboard' } %> diff --git a/app/views/super_admin/application/_settings_menu.html.erb b/app/views/super_admin/application/_settings_menu.html.erb new file mode 100644 index 000000000..3d5173c12 --- /dev/null +++ b/app/views/super_admin/application/_settings_menu.html.erb @@ -0,0 +1,24 @@ +
    • +
      > + + <%= link_to super_admin_settings_url, class: 'flex items-center flex-1' do %> + + Settings + <% end %> + + + + +
        + <% settings_pages.each do |_feature_key, attrs| %> + <% url = super_admin_app_config_url(config: attrs['config_key']) %> +
      • + <% text_class = current_page?(url) ? 'text-woot-500 bg-slate-25' : 'text-slate-800' %> + <%= link_to url, class: text_class + ' -ml-1 flex items-center px-2 py-1.5 hover:text-woot-500 hover:bg-slate-25 rounded-lg' do %> + <%= attrs['name'] %> + <% end %> +
      • + <% end %> +
      +
      +
    • diff --git a/app/views/super_admin/settings/_upgrade_button_community.html.erb b/app/views/super_admin/settings/_upgrade_button_community.html.erb new file mode 100644 index 000000000..b80ee44c8 --- /dev/null +++ b/app/views/super_admin/settings/_upgrade_button_community.html.erb @@ -0,0 +1,4 @@ + + + Switch to Enterprise edition + diff --git a/app/views/super_admin/settings/_upgrade_button_enterprise.html.erb b/app/views/super_admin/settings/_upgrade_button_enterprise.html.erb new file mode 100644 index 000000000..4fbd96367 --- /dev/null +++ b/app/views/super_admin/settings/_upgrade_button_enterprise.html.erb @@ -0,0 +1,4 @@ + + + Upgrade now + diff --git a/app/views/super_admin/settings/show.html.erb b/app/views/super_admin/settings/show.html.erb index 4c15cbdab..fd424ed90 100644 --- a/app/views/super_admin/settings/show.html.erb +++ b/app/views/super_admin/settings/show.html.erb @@ -39,24 +39,26 @@
    -
    -
    -
    -

    Current plan

    - - - Refresh - + <% if ChatwootApp.enterprise? %> +
    +
    +
    +

    Current plan

    + + + Refresh + +
    +

    <%= SuperAdmin::FeaturesHelper.plan_details.html_safe %>

    -

    <%= SuperAdmin::FeaturesHelper.plan_details.html_safe %>

    + + +
    - - - -
    + <% end %> <% if ChatwootHub.pricing_plan != 'community' && User.count > ChatwootHub.pricing_plan_quantity %>
    @@ -99,10 +101,11 @@
    <% if !attrs[:enabled] %> <% end %>
    diff --git a/config/installation_config.yml b/config/installation_config.yml index b17d3cec0..2e8d94a96 100644 --- a/config/installation_config.yml +++ b/config/installation_config.yml @@ -87,11 +87,14 @@ # ------- Email Related Config ------- # - name: MAILER_INBOUND_EMAIL_DOMAIN + display_title: 'Inbound Email Domain' value: description: 'The domain name to be used for generating conversation continuity emails (reply+id@domain.com)' locked: false - name: MAILER_SUPPORT_EMAIL + display_title: 'Support Email' value: + description: 'The support email address for your installation' locked: false # ------- End of Email Related Config ------- # @@ -394,3 +397,22 @@ locked: false type: secret # ------- End of OG Image Related Config ------- # + +## ------ Configs added for Google OAuth ------ ## +- name: GOOGLE_OAUTH_CLIENT_ID + display_title: 'Google OAuth Client ID' + value: + locked: false + description: 'Google OAuth Client ID for email authentication' +- name: GOOGLE_OAUTH_CLIENT_SECRET + display_title: 'Google OAuth Client Secret' + value: + locked: false + description: 'Google OAuth Client Secret for email authentication' + type: secret +- name: GOOGLE_OAUTH_REDIRECT_URI + display_title: 'Google OAuth Redirect URI' + value: + locked: false + description: 'The redirect URI configured in your Google OAuth app' +## ------ End of Configs added for Google OAuth ------ ## diff --git a/lib/chatwoot_hub.rb b/lib/chatwoot_hub.rb index 0d99becd3..c18fb299b 100644 --- a/lib/chatwoot_hub.rb +++ b/lib/chatwoot_hub.rb @@ -19,10 +19,14 @@ class ChatwootHub end def self.pricing_plan + return 'community' unless ChatwootApp.enterprise? + InstallationConfig.find_by(name: 'INSTALLATION_PRICING_PLAN')&.value || 'community' end def self.pricing_plan_quantity + return 0 unless ChatwootApp.enterprise? + InstallationConfig.find_by(name: 'INSTALLATION_PRICING_PLAN_QUANTITY')&.value || 0 end