From 635d062df274fd1c6261c6cb7a42e6230596ab9b Mon Sep 17 00:00:00 2001 From: Paul Slaughter Date: Tue, 3 Dec 2024 10:23:58 -0600 Subject: [PATCH] Feat(Q): Initialize AmazonQ onboarding admin pages - Note: we don't need to check for `admin` since this is already covered by Admin::ApplicationController --- .../application_settings/general.html.haml | 1 + .../admin/ai/amazon_q_settings_controller.rb | 33 +++++++++++ .../ai/amazon_q_settings/index.html.haml | 12 ++++ .../application_settings/_amazon_q.html.haml | 12 ++++ ee/app/views/admin/gitlab_duo/show.html.haml | 10 ++++ ee/config/routes/admin.rb | 2 + .../ai/amazon_q_settings_controller_spec.rb | 59 +++++++++++++++++++ .../admin/gitlab_duo_controller_spec.rb | 32 ++++++++++ .../_amazon_q.html.haml_spec.rb | 30 ++++++++++ .../general.html.haml_spec.rb | 8 +++ locale/gitlab.pot | 33 +++++++++++ 11 files changed, 232 insertions(+) create mode 100644 ee/app/controllers/admin/ai/amazon_q_settings_controller.rb create mode 100644 ee/app/views/admin/ai/amazon_q_settings/index.html.haml create mode 100644 ee/app/views/admin/application_settings/_amazon_q.html.haml create mode 100644 ee/spec/requests/admin/ai/amazon_q_settings_controller_spec.rb create mode 100644 ee/spec/views/admin/application_settings/_amazon_q.html.haml_spec.rb diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml index ab212e22694d91..bf08a03e84d298 100644 --- a/app/views/admin/application_settings/general.html.haml +++ b/app/views/admin/application_settings/general.html.haml @@ -109,3 +109,4 @@ = render 'admin/application_settings/slack' = render 'admin/application_settings/security_txt', expanded: expanded_by_default? = render_if_exists 'admin/application_settings/analytics' += render_if_exists 'admin/application_settings/amazon_q' diff --git a/ee/app/controllers/admin/ai/amazon_q_settings_controller.rb b/ee/app/controllers/admin/ai/amazon_q_settings_controller.rb new file mode 100644 index 00000000000000..d2a758cdb3e9de --- /dev/null +++ b/ee/app/controllers/admin/ai/amazon_q_settings_controller.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Admin + module Ai + # NOTE: This module is under development. See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/174614 + class AmazonQSettingsController < Admin::ApplicationController + feature_category :ai_abstraction_layer + + before_action :check_can_admin_amazon_q + + def index + setup_view_model + end + + private + + def setup_view_model + @view_model = { + submitUrl: admin_ai_amazon_q_settings_path, + amazonQSettings: { + ready: ::Ai::Setting.instance.amazon_q_ready, + roleArn: ::Ai::Setting.instance.amazon_q_role_arn, + availability: Gitlab::CurrentSettings.duo_availability + } + } + end + + def check_can_admin_amazon_q + render_404 unless ::Ai::AmazonQ.feature_available? + end + end + end +end diff --git a/ee/app/views/admin/ai/amazon_q_settings/index.html.haml b/ee/app/views/admin/ai/amazon_q_settings/index.html.haml new file mode 100644 index 00000000000000..b97451638c07cf --- /dev/null +++ b/ee/app/views/admin/ai/amazon_q_settings/index.html.haml @@ -0,0 +1,12 @@ +- page_title s_('AmazonQ|Amazon Q Configuration') +- add_to_breadcrumbs _("General"), general_admin_application_settings_path +- breadcrumb_title _("Amazon Q") + +%h2.gl-flex.gl-items-center.gl-gap-3 + = s_('AmazonQ|Configure GitLab Duo with Amazon Q') + = render Pajamas::BadgeComponent.new(s_('AmazonQ|Beta'), variant: :tier) +%p + - help_link = link_to('', help_page_path('user/duo_amazon_q/index.md'), target: '_blank', rel: 'noopener noreferrer') + = safe_format(s_('AmazonQ|Use GitLab Duo with Amazon Q to create and review merge requests and upgrade Java.%{br}GitLab Duo with Amazon Q is separate from GitLab Duo Pro and Enterprise. %{help_link_start}Learn more%{help_link_end}.'), tag_pair(help_link, :help_link_start, :help_link_end), br: '
'.html_safe) + +#js-amazon-q-settings{ data: { view_model: @view_model.to_json } } diff --git a/ee/app/views/admin/application_settings/_amazon_q.html.haml b/ee/app/views/admin/application_settings/_amazon_q.html.haml new file mode 100644 index 00000000000000..6da51e02cb88b2 --- /dev/null +++ b/ee/app/views/admin/application_settings/_amazon_q.html.haml @@ -0,0 +1,12 @@ +- return unless ::Ai::AmazonQ.feature_available? + += render ::Layouts::SettingsBlockComponent.new(s_('AmazonQ|GitLab Duo with Amazon Q'), + id: 'js-amazon-q-settings', + expanded: expanded_by_default?) do |c| + - c.with_description do + - link = link_to('', help_page_path('user/duo_amazon_q/index.md'), target: '_blank', rel: 'noopener noreferrer') + = safe_format(s_('AmazonQ|Use GitLab Duo with Amazon Q to create and review merge requests and upgrade Java. %{link_start}Learn more%{link_end}.'), tag_pair(link, :link_start, :link_end)) + - c.with_body do + .gl-mt-3 + = render Pajamas::ButtonComponent.new(variant: :confirm, href: admin_ai_amazon_q_settings_path) do + = s_('AmazonQ|View configuration setup') diff --git a/ee/app/views/admin/gitlab_duo/show.html.haml b/ee/app/views/admin/gitlab_duo/show.html.haml index 6f8c8f598ffd4a..6e413ae4fc72ab 100644 --- a/ee/app/views/admin/gitlab_duo/show.html.haml +++ b/ee/app/views/admin/gitlab_duo/show.html.haml @@ -3,4 +3,14 @@ - page_title gitlab_duo_text - breadcrumb_title gitlab_duo_text +- if ::Ai::AmazonQ.feature_available? && !::Ai::AmazonQ.connected? + = render Pajamas::BannerComponent.new(close_options: { class: '!gl-hidden'}, + svg_path: 'illustrations/tanuki-ai-sm.svg', + button_text: s_('AmazonQ|Get started'), + button_link: admin_ai_amazon_q_settings_path) do |c| + - c.with_title do + = s_('AmazonQ|Configure GitLab Duo with Amazon Q (Beta)') + %p + = s_('AmazonQ|Use Amazon Q to automate workflows, create a merge request from an issue, upgrade Java, and improve your code with AI-powered reviews.') + #js-gitlab-duo-admin-page{ data: admin_duo_home_app_data } diff --git a/ee/config/routes/admin.rb b/ee/config/routes/admin.rb index a7dce2bdc04c23..de071e2b6cdab7 100644 --- a/ee/config/routes/admin.rb +++ b/ee/config/routes/admin.rb @@ -58,6 +58,8 @@ resources :terms_and_conditions, only: [:index, :create] end end + + resources :amazon_q_settings, only: [:index] end # using `only: []` to keep duplicate routes from being created diff --git a/ee/spec/requests/admin/ai/amazon_q_settings_controller_spec.rb b/ee/spec/requests/admin/ai/amazon_q_settings_controller_spec.rb new file mode 100644 index 00000000000000..b19963da06c2c6 --- /dev/null +++ b/ee/spec/requests/admin/ai/amazon_q_settings_controller_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Admin::Ai::AmazonQSettingsController, :enable_admin_mode, feature_category: :ai_abstraction_layer do + let(:admin) { create(:admin) } + + let(:actual_view_model) do + Gitlab::Json.parse( + Nokogiri::HTML(response.body).css('#js-amazon-q-settings').first['data-view-model'] + ) + end + + before do + stub_licensed_features(amazon_q: true) + stub_feature_flags(amazon_q_integration: true) + + stub_ee_application_setting(duo_availability: 'default_on') + + # NOTE: Updating this singleton in the top-level before each for increasing predictability with tests + Ai::Setting.instance.update!( + amazon_q_ready: true, + amazon_q_role_arn: 'test-arn' + ) + + sign_in(admin) + end + + shared_examples 'returns 404 when feature is unavailable' do + before do + stub_licensed_features(amazon_q: false) + end + + it 'returns 404' do + perform_request + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + describe 'GET #index' do + let(:perform_request) { get admin_ai_amazon_q_settings_path } + + it_behaves_like 'returns 404 when feature is unavailable' + + it 'renders the frontend entrypoint with view model' do + perform_request + + expect(actual_view_model).to eq({ + "amazonQSettings" => { + "availability" => 'default_on', + "ready" => true, + "roleArn" => 'test-arn' + }, + "submitUrl" => admin_ai_amazon_q_settings_path + }) + end + end +end diff --git a/ee/spec/requests/admin/gitlab_duo_controller_spec.rb b/ee/spec/requests/admin/gitlab_duo_controller_spec.rb index 0df12c3457ecc7..9b51cdce57cd5e 100644 --- a/ee/spec/requests/admin/gitlab_duo_controller_spec.rb +++ b/ee/spec/requests/admin/gitlab_duo_controller_spec.rb @@ -100,6 +100,38 @@ it_behaves_like 'hides gitlab duo path' end + + context 'for AmazonQ banner' do + using RSpec::Parameterized::TableSyntax + + let_it_be(:amazon_q_banner) { s_('AmazonQ|Configure GitLab Duo with Amazon Q (Beta)') } + + where(:amazon_q_available, :amazon_q_connected, :expected_banner) do + true | true | false + true | false | true + false | true | false + false | false | false + end + + with_them do + before do + allow(::Ai::AmazonQ).to receive_messages( + feature_available?: amazon_q_available, + connected?: amazon_q_connected + ) + end + + it 'displays banner only when amazon q is available and connected' do + get admin_gitlab_duo_path + + if expected_banner + expect(response.body).to include(amazon_q_banner) + else + expect(response.body).not_to include(amazon_q_banner) + end + end + end + end end end end diff --git a/ee/spec/views/admin/application_settings/_amazon_q.html.haml_spec.rb b/ee/spec/views/admin/application_settings/_amazon_q.html.haml_spec.rb new file mode 100644 index 00000000000000..876f4997b03448 --- /dev/null +++ b/ee/spec/views/admin/application_settings/_amazon_q.html.haml_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'admin/application_settings/_amazon_q', feature_category: :ai_abstraction_layer do + let(:feature_available) { true } + + # We use `view.render`, because just `render` throws a "no implicit conversion of nil into String" exception + # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53093#note_499060593 + subject(:rendered) { view.render('admin/application_settings/amazon_q') } + + before do + allow(::Ai::AmazonQ).to receive(:feature_available?).and_return(feature_available) + end + + context 'when feature available' do + it 'renders settings' do + expect(rendered).to have_css('#js-amazon-q-settings') + expect(rendered).to have_link(s_('AmazonQ|View configuration setup'), href: admin_ai_amazon_q_settings_path) + end + end + + context 'when feature not available' do + let(:feature_available) { false } + + it 'renders nothing' do + expect(rendered).to be_nil + end + end +end diff --git a/ee/spec/views/admin/application_settings/general.html.haml_spec.rb b/ee/spec/views/admin/application_settings/general.html.haml_spec.rb index 7dcd3f8556e114..c55cdb9d026d25 100644 --- a/ee/spec/views/admin/application_settings/general.html.haml_spec.rb +++ b/ee/spec/views/admin/application_settings/general.html.haml_spec.rb @@ -137,4 +137,12 @@ expect(rendered).to render_template('admin/application_settings/_private_profile_restrictions') end end + + describe 'AmazonQ settings', feature_category: :ai_abstraction_layer do + it 'renders correct ee partial' do + render + + expect(rendered).to render_template('admin/application_settings/_amazon_q') + end + end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 7fd47b9d453deb..85742b0453a244 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -5880,6 +5880,39 @@ msgstr "" msgid "Amazon EKS integration allows you to provision EKS clusters from GitLab." msgstr "" +msgid "Amazon Q" +msgstr "" + +msgid "AmazonQ|Amazon Q Configuration" +msgstr "" + +msgid "AmazonQ|Beta" +msgstr "" + +msgid "AmazonQ|Configure GitLab Duo with Amazon Q" +msgstr "" + +msgid "AmazonQ|Configure GitLab Duo with Amazon Q (Beta)" +msgstr "" + +msgid "AmazonQ|Get started" +msgstr "" + +msgid "AmazonQ|GitLab Duo with Amazon Q" +msgstr "" + +msgid "AmazonQ|Use Amazon Q to automate workflows, create a merge request from an issue, upgrade Java, and improve your code with AI-powered reviews." +msgstr "" + +msgid "AmazonQ|Use GitLab Duo with Amazon Q to create and review merge requests and upgrade Java. %{link_start}Learn more%{link_end}." +msgstr "" + +msgid "AmazonQ|Use GitLab Duo with Amazon Q to create and review merge requests and upgrade Java.%{br}GitLab Duo with Amazon Q is separate from GitLab Duo Pro and Enterprise. %{help_link_start}Learn more%{help_link_end}." +msgstr "" + +msgid "AmazonQ|View configuration setup" +msgstr "" + msgid "AmbiguousRef|There is a branch and a tag with the same name of %{ref}." msgstr "" -- GitLab