From d1451e56921070415de751a75f9274f70d7c3fa0 Mon Sep 17 00:00:00 2001
From: Julie Huang <julhuang@gitlab.com>
Date: Thu, 3 Oct 2024 13:30:35 +0000
Subject: [PATCH] Invoke aiFeatureSettings query

- Invoke query
- Update tests
- Remove data stub
---
 .../ai/feature_settings/components/app.vue    | 59 ++++++++-----
 .../components/feature_settings_table.vue     | 11 +--
 .../components/model_select_dropdown.vue      | 69 ++++++++-------
 .../admin/ai/feature_settings/data_stub.js    | 34 -------
 ...pdate_ai_feature_setting.mutation.graphql} |  0
 .../get_ai_feature_settings.query.graphql     | 22 +++++
 .../admin/ai/feature_settings_controller.rb   |  4 -
 .../admin/ai/feature_settings/index.html.haml |  2 +-
 .../admin/ai/feature_settings/app_spec.js     | 88 ++++++++++++++++++-
 .../feature_settings_table_spec.js            |  5 +-
 .../admin/ai/feature_settings/mock_data.js    | 25 ++++--
 .../model_select_dropdown_spec.js             |  5 +-
 .../ai/feature_settings_controller_spec.rb    | 14 ---
 locale/gitlab.pot                             |  9 +-
 14 files changed, 212 insertions(+), 135 deletions(-)
 delete mode 100644 ee/app/assets/javascripts/pages/admin/ai/feature_settings/data_stub.js
 rename ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/mutations/{update_ai_feature_setting.graphql => update_ai_feature_setting.mutation.graphql} (100%)
 create mode 100644 ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/queries/get_ai_feature_settings.query.graphql

diff --git a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/app.vue b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/app.vue
index ff0d99246bbac..268fcbbc0be4c 100644
--- a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/app.vue
+++ b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/app.vue
@@ -1,52 +1,69 @@
 <script>
-import stubbedAiFeatureSettings from '../data_stub';
+import { GlSkeletonLoader } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import { createAlert } from '~/alert';
+import getAiFeatureSettingsQuery from '../graphql/queries/get_ai_feature_settings.query.graphql';
 import AiFeatureSettingsTable from './feature_settings_table.vue';
 
 export default {
   name: 'FeatureSettingsApp',
   components: {
+    GlSkeletonLoader,
     AiFeatureSettingsTable,
   },
   props: {
-    models: {
-      type: Array,
-      required: true,
-    },
     newSelfHostedModelPath: {
       type: String,
       required: true,
     },
-    // Return stubbed data for now
-    featureSettings: {
-      type: Array,
-      required: false,
-      default: () => {
-        return stubbedAiFeatureSettings;
+  },
+  i18n: {
+    title: s__('AdminAIPoweredFeatures|AI-powered features'),
+    description: s__(
+      'AdminAIPoweredFeatures|Features that can be enabled, disabled, or linked to a cloud-based or self-hosted model.',
+    ),
+    errorMessage: s__(
+      'AdminAIPoweredFeatures|An error occurred while loading the AI feature settings. Please try again.',
+    ),
+  },
+  data() {
+    return {
+      aiFeatureSettings: [],
+    };
+  },
+  apollo: {
+    aiFeatureSettings: {
+      query: getAiFeatureSettingsQuery,
+      update(data) {
+        return data?.aiFeatureSettings?.nodes || [];
+      },
+      error(error) {
+        createAlert({ message: this.$options.i18n.errorMessage, error, captureError: true });
       },
     },
   },
+  computed: {
+    isLoading() {
+      return this.$apollo?.queries?.aiFeatureSettings?.loading;
+    },
+  },
 };
 </script>
 <template>
   <div>
     <section>
       <h1 class="page-title gl-text-size-h-display">
-        {{ s__('AdminAIPoweredFeatures|AI-powered features') }}
+        {{ $options.i18n.title }}
       </h1>
       <div class="gl-items-top gl-flex gl-justify-between">
-        <p>
-          {{
-            s__(
-              'AdminAIPoweredFeatures|Features that can be enabled, disabled, or linked to a cloud-based or self-hosted model.',
-            )
-          }}
-        </p>
+        <p>{{ $options.i18n.description }}</p>
       </div>
     </section>
+    <gl-skeleton-loader v-if="isLoading" />
     <ai-feature-settings-table
-      :feature-settings="featureSettings"
+      v-else
+      :ai-feature-settings="aiFeatureSettings"
       :new-self-hosted-model-path="newSelfHostedModelPath"
-      :models="models"
     />
   </div>
 </template>
diff --git a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/feature_settings_table.vue b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/feature_settings_table.vue
index bd53cea0cb857..5a3bbdab750fb 100644
--- a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/feature_settings_table.vue
+++ b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/feature_settings_table.vue
@@ -10,7 +10,7 @@ export default {
     ModelSelectDropdown,
   },
   props: {
-    featureSettings: {
+    aiFeatureSettings: {
       type: Array,
       required: true,
     },
@@ -18,10 +18,6 @@ export default {
       type: String,
       required: true,
     },
-    models: {
-      type: Array,
-      required: true,
-    },
   },
   fields: [
     {
@@ -48,7 +44,7 @@ export default {
 <template>
   <gl-table-lite
     :fields="$options.fields"
-    :items="featureSettings"
+    :items="aiFeatureSettings"
     stacked="md"
     :hover="true"
     :selectable="false"
@@ -61,8 +57,7 @@ export default {
     </template>
     <template #cell(model_name)="{ item }">
       <model-select-dropdown
-        :feature-setting="item"
-        :models="models"
+        :ai-feature-setting="item"
         :new-self-hosted-model-path="newSelfHostedModelPath"
       />
     </template>
diff --git a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/model_select_dropdown.vue b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/model_select_dropdown.vue
index 9c71fe4779b20..959eea0e04f7b 100644
--- a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/model_select_dropdown.vue
+++ b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/components/model_select_dropdown.vue
@@ -2,13 +2,12 @@
 import { GlCollapsibleListbox, GlButton } from '@gitlab/ui';
 import { s__, sprintf } from '~/locale';
 import { createAlert } from '~/alert';
-import { convertToGraphQLId } from '~/graphql_shared/utils';
-import updateAiFeatureSetting from '../graphql/mutations/update_ai_feature_setting.graphql';
+import updateAiFeatureSetting from '../graphql/mutations/update_ai_feature_setting.mutation.graphql';
 
 const PROVIDERS = {
-  DISABLED: 'DISABLED',
-  VENDORED: 'VENDORED',
-  SELF_HOSTED: 'SELF_HOSTED',
+  DISABLED: 'disabled',
+  VENDORED: 'vendored',
+  SELF_HOSTED: 'self_hosted',
 };
 
 const FEATURE_DISABLED = 'DISABLED';
@@ -20,14 +19,10 @@ export default {
     GlButton,
   },
   props: {
-    featureSetting: {
+    aiFeatureSetting: {
       type: Object,
       required: true,
     },
-    models: {
-      type: Array,
-      required: true,
-    },
     newSelfHostedModelPath: {
       type: String,
       required: true,
@@ -40,17 +35,21 @@ export default {
     successMessage: s__('AdminSelfHostedModels|Successfully updated %{mainFeature} / %{title}'),
   },
   data() {
+    const { provider, selfHostedModel, validModels } = this.aiFeatureSetting;
+
+    const selectedOption = provider === PROVIDERS.DISABLED ? FEATURE_DISABLED : selfHostedModel?.id;
+
     return {
-      feature: this.featureSetting.feature,
-      provider: this.featureSetting.provider,
-      selfHostedModelId: this.featureSetting.selfHostedModelId,
-      selectedOption: null,
+      provider,
+      selfHostedModelId: selfHostedModel?.id,
+      compatibleModels: validModels?.nodes,
+      selectedOption,
       isSaving: false,
     };
   },
   computed: {
     dropdownItems() {
-      const modelOptions = this.models.map((model) => ({
+      const modelOptions = this.compatibleModels.map((model) => ({
         value: model.id,
         text: `${model.name} (${model.model})`,
       }));
@@ -64,13 +63,13 @@ export default {
       return [...modelOptions, disableOption];
     },
     selectedModel() {
-      return this.models.find((m) => m.id === this.selfHostedModelId);
+      return this.compatibleModels.find((m) => m.id === this.selfHostedModelId);
     },
     dropdownToggleText() {
-      if (!this.selectedOption) {
+      if (this.provider === PROVIDERS.VENDORED) {
         return s__('AdminAIPoweredFeatures|Select a self-hosted model');
       }
-      if (this.selectedOption === FEATURE_DISABLED) {
+      if (this.provider === PROVIDERS.DISABLED) {
         return s__('AdminAIPoweredFeatures|Disabled');
       }
 
@@ -82,18 +81,19 @@ export default {
       this.isSaving = true;
 
       try {
-        const provider = option === FEATURE_DISABLED ? PROVIDERS.DISABLED : PROVIDERS.SELF_HOSTED;
+        const selectedOption = {
+          option,
+          provider: option === FEATURE_DISABLED ? PROVIDERS.DISABLED : PROVIDERS.SELF_HOSTED,
+          selfHostedModelId: option === FEATURE_DISABLED ? null : option,
+        };
 
         const { data } = await this.$apollo.mutate({
           mutation: updateAiFeatureSetting,
           variables: {
             input: {
-              feature: this.feature.toUpperCase(),
-              provider,
-              selfHostedModelId:
-                option === FEATURE_DISABLED
-                  ? null
-                  : convertToGraphQLId('Ai::SelfHostedModel', option),
+              feature: this.aiFeatureSetting.feature.toUpperCase(),
+              provider: selectedOption.provider.toUpperCase(),
+              selfHostedModelId: selectedOption.selfHostedModelId,
             },
           },
         });
@@ -105,11 +105,9 @@ export default {
             throw new Error(errors[0]);
           }
 
-          this.selectedOption = option;
-          this.provider = provider;
-          this.selfHostedModelId = option === FEATURE_DISABLED ? null : option;
+          this.updateSelection(selectedOption);
           this.isSaving = false;
-          this.$toast.show(this.successMessage(this.featureSetting));
+          this.$toast.show(this.successMessage(this.aiFeatureSetting));
         }
       } catch (error) {
         createAlert({
@@ -120,13 +118,18 @@ export default {
         this.isSaving = false;
       }
     },
+    updateSelection(selectedOption) {
+      this.selectedOption = selectedOption.option;
+      this.provider = selectedOption.provider;
+      this.selfHostedModelId = selectedOption.selfHostedModelId;
+    },
     errorMessage(error) {
       return error.message || this.$options.i18n.defaultErrorMessage;
     },
-    successMessage(featureSetting) {
+    successMessage(aiFeatureSetting) {
       return sprintf(this.$options.i18n.successMessage, {
-        mainFeature: featureSetting.mainFeature,
-        title: featureSetting.title,
+        mainFeature: aiFeatureSetting.mainFeature,
+        title: aiFeatureSetting.title,
       });
     },
   },
@@ -138,7 +141,7 @@ export default {
     :selected="selectedOption"
     :items="dropdownItems"
     :toggle-text="dropdownToggleText"
-    :header-text="s__('AdminAIPoweredFeatures|Self-hosted models')"
+    :header-text="s__('AdminAIPoweredFeatures|Compatible models')"
     :loading="isSaving"
     category="primary"
     block
diff --git a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/data_stub.js b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/data_stub.js
deleted file mode 100644
index bfc0150afa9f5..0000000000000
--- a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/data_stub.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Temporary data stub for feature settings table
- *
- * TODO: Remove when feature settings data is ready.
- * See https://gitlab.com/gitlab-org/gitlab/-/issues/473005#note_2076997154
- */
-
-/* eslint-disable @gitlab/require-i18n-strings */
-const stubbedAiFeatureSettings = [
-  {
-    feature: 'code_generations',
-    title: 'Code Generation',
-    mainFeature: 'Code Suggestions',
-    provider: 'self_hosted',
-    selfHostedModel: null,
-  },
-  {
-    feature: 'code_completions',
-    title: 'Code Completion',
-    mainFeature: 'Code Suggestions',
-    provider: 'vendored',
-    selfHostedModel: null,
-  },
-  {
-    feature: 'duo_chat',
-    title: 'Duo Chat',
-    mainFeature: 'Duo Chat',
-    provider: 'self_hosted',
-    selfHostedModel: null,
-  },
-];
-/* eslint-enable @gitlab/require-i18n-strings */
-
-export default stubbedAiFeatureSettings;
diff --git a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/mutations/update_ai_feature_setting.graphql b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/mutations/update_ai_feature_setting.mutation.graphql
similarity index 100%
rename from ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/mutations/update_ai_feature_setting.graphql
rename to ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/mutations/update_ai_feature_setting.mutation.graphql
diff --git a/ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/queries/get_ai_feature_settings.query.graphql b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/queries/get_ai_feature_settings.query.graphql
new file mode 100644
index 0000000000000..d74d3c62be3d7
--- /dev/null
+++ b/ee/app/assets/javascripts/pages/admin/ai/feature_settings/graphql/queries/get_ai_feature_settings.query.graphql
@@ -0,0 +1,22 @@
+query getAiFeatureSetting {
+  aiFeatureSettings {
+    nodes {
+      feature
+      title
+      mainFeature
+      provider
+      selfHostedModel {
+        id
+        name
+        model
+      }
+      validModels {
+        nodes {
+          id
+          name
+          model
+        }
+      }
+    }
+  }
+}
diff --git a/ee/app/controllers/admin/ai/feature_settings_controller.rb b/ee/app/controllers/admin/ai/feature_settings_controller.rb
index 535dd9b68053a..76be4818c8e9d 100644
--- a/ee/app/controllers/admin/ai/feature_settings_controller.rb
+++ b/ee/app/controllers/admin/ai/feature_settings_controller.rb
@@ -12,10 +12,6 @@ class FeatureSettingsController < Admin::ApplicationController
 
       def index
         @feature_settings = ::Ai::FeatureSettings::FeatureSettingFinder.new.execute
-
-        return unless Feature.enabled?(:custom_models_feature_settings_vue_app, current_user)
-
-        @self_hosted_models = ::Ai::SelfHostedModel.all
       end
 
       # rubocop:disable CodeReuse/ActiveRecord -- Using find_or_initialize_by is reasonable
diff --git a/ee/app/views/admin/ai/feature_settings/index.html.haml b/ee/app/views/admin/ai/feature_settings/index.html.haml
index 45398b18e1d9c..73488f924c781 100644
--- a/ee/app/views/admin/ai/feature_settings/index.html.haml
+++ b/ee/app/views/admin/ai/feature_settings/index.html.haml
@@ -2,7 +2,7 @@
 - add_page_specific_style 'page_bundles/labels'
 
 - if Feature.enabled?(:custom_models_feature_settings_vue_app, current_user)
-  #js-ai-powered-features{ data: { view_model: { models: @self_hosted_models, newSelfHostedModelPath: new_admin_ai_self_hosted_model_path }.to_json } }
+  #js-ai-powered-features{ data: { view_model: { newSelfHostedModelPath: new_admin_ai_self_hosted_model_path }.to_json } }
 - else
   = render ::Layouts::CrudComponent.new(s_('AdminAIPoweredFeatures|AI-powered features'),
     options: { class: 'gl-mt-5' }) do |c|
diff --git a/ee/spec/frontend/pages/admin/ai/feature_settings/app_spec.js b/ee/spec/frontend/pages/admin/ai/feature_settings/app_spec.js
index 8a7d7852236c6..e39b024ddb8dd 100644
--- a/ee/spec/frontend/pages/admin/ai/feature_settings/app_spec.js
+++ b/ee/spec/frontend/pages/admin/ai/feature_settings/app_spec.js
@@ -1,17 +1,52 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import { GlSkeletonLoader } from '@gitlab/ui';
 import { shallowMount } from '@vue/test-utils';
+import waitForPromises from 'helpers/wait_for_promises';
+import createMockApollo from 'helpers/mock_apollo_helper';
 import FeatureSettingsApp from 'ee/pages/admin/ai/feature_settings/components/app.vue';
+import getAiFeatureSettingsQuery from 'ee/pages/admin/ai/feature_settings/graphql/queries/get_ai_feature_settings.query.graphql';
+import AiFeatureSettingsTable from 'ee/pages/admin/ai/feature_settings/components/feature_settings_table.vue';
+import { createAlert } from '~/alert';
+import { mockAiFeatureSettings } from './mock_data';
+
+Vue.use(VueApollo);
+
+jest.mock('~/alert');
 
 describe('FeatureSettingsApp', () => {
   let wrapper;
 
-  const createComponent = () => {
-    wrapper = shallowMount(FeatureSettingsApp);
+  const getAiFeatureSettingsSuccessHandler = jest.fn().mockResolvedValue({
+    data: {
+      aiFeatureSettings: {
+        nodes: mockAiFeatureSettings,
+        errors: [],
+      },
+    },
+  });
+
+  const createComponent = ({
+    apolloHandlers = [[getAiFeatureSettingsQuery, getAiFeatureSettingsSuccessHandler]],
+  } = {}) => {
+    const mockApollo = createMockApollo([...apolloHandlers]);
+    const newSelfHostedModelPath = '/admin/ai/self_hosted_models/new';
+
+    wrapper = shallowMount(FeatureSettingsApp, {
+      apolloProvider: mockApollo,
+      propsData: {
+        newSelfHostedModelPath,
+      },
+    });
   };
 
   beforeEach(() => {
     createComponent();
   });
 
+  const findAiFeatureSettingsTable = () => wrapper.findComponent(AiFeatureSettingsTable);
+  const findLoader = () => wrapper.findComponent(GlSkeletonLoader);
+
   it('has a title', () => {
     const title = wrapper.find('h1');
 
@@ -23,4 +58,53 @@ describe('FeatureSettingsApp', () => {
       'Features that can be enabled, disabled, or linked to a cloud-based or self-hosted model.',
     );
   });
+
+  describe('when AI feature settings are loading', () => {
+    it('renders skeleton loader', () => {
+      expect(findLoader().exists()).toBe(true);
+    });
+  });
+
+  describe('when the API request is successful', () => {
+    beforeEach(async () => {
+      createComponent();
+
+      await waitForPromises();
+    });
+
+    it('renders the feature settings table and passes the correct props', () => {
+      expect(findAiFeatureSettingsTable().props('aiFeatureSettings')).toEqual(
+        mockAiFeatureSettings,
+      );
+      expect(findAiFeatureSettingsTable().props('newSelfHostedModelPath')).toEqual(
+        '/admin/ai/self_hosted_models/new',
+      );
+    });
+  });
+
+  describe('when the API request is unsuccessful', () => {
+    const getAiFeatureSettingsErrorHandler = jest.fn().mockResolvedValue({
+      data: {
+        aiFeatureSettings: {
+          errors: ['An error occured'],
+        },
+      },
+    });
+
+    beforeEach(async () => {
+      createComponent({
+        apolloHandlers: [[getAiFeatureSettingsQuery, getAiFeatureSettingsErrorHandler]],
+      });
+
+      await waitForPromises();
+    });
+
+    it('displays an error message', () => {
+      expect(createAlert).toHaveBeenCalledWith(
+        expect.objectContaining({
+          message: 'An error occurred while loading the AI feature settings. Please try again.',
+        }),
+      );
+    });
+  });
 });
diff --git a/ee/spec/frontend/pages/admin/ai/feature_settings/feature_settings_table_spec.js b/ee/spec/frontend/pages/admin/ai/feature_settings/feature_settings_table_spec.js
index 25ef6f69bd61e..32f4bd0d3c19b 100644
--- a/ee/spec/frontend/pages/admin/ai/feature_settings/feature_settings_table_spec.js
+++ b/ee/spec/frontend/pages/admin/ai/feature_settings/feature_settings_table_spec.js
@@ -1,7 +1,7 @@
 import { GlTableLite } from '@gitlab/ui';
 import { mountExtended } from 'helpers/vue_test_utils_helper';
 import FeatureSettingsTable from 'ee/pages/admin/ai/feature_settings/components/feature_settings_table.vue';
-import { mockAiFeatureSettings, mockSelfHostedModels } from './mock_data';
+import { mockAiFeatureSettings } from './mock_data';
 
 describe('FeatureSettingsTable', () => {
   let wrapper;
@@ -19,8 +19,7 @@ describe('FeatureSettingsTable', () => {
   beforeEach(() => {
     createComponent({
       props: {
-        featureSettings: mockAiFeatureSettings,
-        models: mockSelfHostedModels,
+        aiFeatureSettings: mockAiFeatureSettings,
         newSelfHostedModelPath,
       },
     });
diff --git a/ee/spec/frontend/pages/admin/ai/feature_settings/mock_data.js b/ee/spec/frontend/pages/admin/ai/feature_settings/mock_data.js
index eae2a2d9f597b..556cccfccced0 100644
--- a/ee/spec/frontend/pages/admin/ai/feature_settings/mock_data.js
+++ b/ee/spec/frontend/pages/admin/ai/feature_settings/mock_data.js
@@ -1,29 +1,36 @@
+export const mockSelfHostedModels = [
+  { id: 1, name: 'Model 1', model: 'mistral' },
+  { id: 2, name: 'Model 2', model: 'codellama' },
+  { id: 3, name: 'Model 3', model: 'codegemma' },
+];
+
 export const mockAiFeatureSettings = [
   {
     feature: 'code_generations',
     title: 'Code Generation',
     mainFeature: 'Code Suggestions',
-    provider: 'self_hosted',
+    provider: 'vendored',
     selfHostedModel: null,
+    validModels: { nodes: mockSelfHostedModels },
   },
   {
     feature: 'code_completions',
     title: 'Code Completion',
     mainFeature: 'Code Suggestions',
-    provider: 'vendored',
+    provider: 'disabled',
     selfHostedModel: null,
+    validModels: { nodes: mockSelfHostedModels },
   },
   {
     feature: 'duo_chat',
     title: 'Duo Chat',
     mainFeature: 'Duo Chat',
     provider: 'self_hosted',
-    selfHostedModel: null,
+    selfHostedModel: {
+      id: 2,
+      name: 'Model 2',
+      model: 'codellama',
+    },
+    validModels: { nodes: mockSelfHostedModels },
   },
 ];
-
-export const mockSelfHostedModels = [
-  { id: 1, name: 'Model 1', model: 'mistral' },
-  { id: 2, name: 'Model 2', model: 'codellama' },
-  { id: 3, name: 'Model 3', model: 'codegemma' },
-];
diff --git a/ee/spec/frontend/pages/admin/ai/feature_settings/model_select_dropdown_spec.js b/ee/spec/frontend/pages/admin/ai/feature_settings/model_select_dropdown_spec.js
index 55213eb9781cc..66f33055479a0 100644
--- a/ee/spec/frontend/pages/admin/ai/feature_settings/model_select_dropdown_spec.js
+++ b/ee/spec/frontend/pages/admin/ai/feature_settings/model_select_dropdown_spec.js
@@ -5,7 +5,7 @@ import { mount } from '@vue/test-utils';
 import waitForPromises from 'helpers/wait_for_promises';
 import createMockApollo from 'helpers/mock_apollo_helper';
 import ModelSelectDropdown from 'ee/pages/admin/ai/feature_settings/components/model_select_dropdown.vue';
-import updateAiFeatureSetting from 'ee/pages/admin/ai/feature_settings/graphql/mutations/update_ai_feature_setting.graphql';
+import updateAiFeatureSetting from 'ee/pages/admin/ai/feature_settings/graphql/mutations/update_ai_feature_setting.mutation.graphql';
 import { createAlert } from '~/alert';
 import { mockSelfHostedModels, mockAiFeatureSettings } from './mock_data';
 
@@ -38,8 +38,7 @@ describe('ModelSelectDropdown', () => {
       apolloProvider: mockApollo,
       propsData: {
         newSelfHostedModelPath,
-        featureSetting: mockAiFeatureSetting,
-        models: mockSelfHostedModels,
+        aiFeatureSetting: mockAiFeatureSetting,
         ...props,
       },
       mocks: {
diff --git a/ee/spec/requests/admin/ai/feature_settings_controller_spec.rb b/ee/spec/requests/admin/ai/feature_settings_controller_spec.rb
index 65d42095733a6..0b5c3c69e6ac8 100644
--- a/ee/spec/requests/admin/ai/feature_settings_controller_spec.rb
+++ b/ee/spec/requests/admin/ai/feature_settings_controller_spec.rb
@@ -50,20 +50,6 @@
   end
 
   describe 'GET #index' do
-    context 'when custom_models_feature_settings_vue_app feature flag is enabled' do
-      let_it_be(:model) { create(:ai_self_hosted_model) }
-
-      before do
-        stub_feature_flags(custom_models_feature_settings_vue_app: true)
-      end
-
-      it 'returns self-hosted models' do
-        get admin_ai_feature_settings_path
-
-        expect(assigns(:self_hosted_models)).to match_array([model])
-      end
-    end
-
     it 'returns `flagged_features` if ai_duo_chat_sub_features_settings is enabled' do
       # it expect to go through the ::Ai::FeatureSetting.flagged_features method
       # So it only shows the stable features
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 22789b0e2dcc8..f1fa136facaf9 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3587,6 +3587,12 @@ msgstr ""
 msgid "AdminAIPoweredFeatures|Add self-hosted model"
 msgstr ""
 
+msgid "AdminAIPoweredFeatures|An error occurred while loading the AI feature settings. Please try again."
+msgstr ""
+
+msgid "AdminAIPoweredFeatures|Compatible models"
+msgstr ""
+
 msgid "AdminAIPoweredFeatures|Disabled"
 msgstr ""
 
@@ -3602,9 +3608,6 @@ msgstr ""
 msgid "AdminAIPoweredFeatures|Select a self-hosted model"
 msgstr ""
 
-msgid "AdminAIPoweredFeatures|Self-hosted models"
-msgstr ""
-
 msgid "AdminAIPoweredFeatures|Sub feature"
 msgstr ""
 
-- 
GitLab