diff --git a/app/graphql/mutations/user_preferences/update.rb b/app/graphql/mutations/user_preferences/update.rb
index 16c7b37532c5d36eb187f4ec81a51ad954962e01..111bd2587757e78ad55bbd457249a23b0e959f50 100644
--- a/app/graphql/mutations/user_preferences/update.rb
+++ b/app/graphql/mutations/user_preferences/update.rb
@@ -5,9 +5,17 @@ module UserPreferences
class Update < BaseMutation
graphql_name 'UserPreferencesUpdate'
+ NON_NULLABLE_ARGS = [
+ :use_web_ide_extension_marketplace,
+ :visibility_pipeline_id_type
+ ].freeze
+
argument :issues_sort, Types::IssueSortEnum,
required: false,
description: 'Sort order for issue lists.'
+ argument :use_web_ide_extension_marketplace, GraphQL::Types::Boolean,
+ required: false,
+ description: 'Whether Web IDE Extension Marketplace is enabled for the user.'
argument :visibility_pipeline_id_type, Types::VisibilityPipelineIdTypeEnum,
required: false,
description: 'Determines whether the pipeline list shows ID or IID.'
@@ -18,6 +26,7 @@ class Update < BaseMutation
description: 'User preferences after mutation.'
def resolve(**attributes)
+ attributes.delete_if { |key, value| NON_NULLABLE_ARGS.include?(key) && value.nil? }
user_preferences = current_user.user_preference
user_preferences.update(attributes)
diff --git a/app/graphql/types/user_preferences_type.rb b/app/graphql/types/user_preferences_type.rb
index 094c7352c96b67ee801630842aa260b21fa4a4eb..e9ac3a28a5303c6a60996bcddcffcba2dd9becce 100644
--- a/app/graphql/types/user_preferences_type.rb
+++ b/app/graphql/types/user_preferences_type.rb
@@ -14,6 +14,10 @@ class UserPreferencesType < BaseObject
description: 'Determines whether the pipeline list shows ID or IID.',
null: true
+ field :use_web_ide_extension_marketplace, GraphQL::Types::Boolean,
+ description: 'Whether Web IDE Extension Marketplace is enabled for the user.',
+ null: false
+
def issues_sort
object.issues_sort.to_sym
end
diff --git a/app/models/user.rb b/app/models/user.rb
index d7880579092823ad8c0218f2ee731874df2772dc..87249f7cf1b81172a8947fac656e6cb1de3379a7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -388,6 +388,7 @@ def update_tracked_fields!(request)
:tab_width, :tab_width=,
:sourcegraph_enabled, :sourcegraph_enabled=,
:gitpod_enabled, :gitpod_enabled=,
+ :use_web_ide_extension_marketplace, :use_web_ide_extension_marketplace=,
:setup_for_company, :setup_for_company=,
:project_shortcut_buttons, :project_shortcut_buttons=,
:keyboard_shortcuts_enabled, :keyboard_shortcuts_enabled=,
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index b8c4c8597a47be713ff466ae3d25d88543d77863..70ffe0c85f8269fe5d120bd7be87626288054ff4 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -42,6 +42,7 @@ class UserPreference < MainClusterwide::ApplicationRecord
attribute :render_whitespace_in_code, default: false
attribute :project_shortcut_buttons, default: true
attribute :keyboard_shortcuts_enabled, default: true
+ attribute :use_web_ide_extension_marketplace, default: false
enum visibility_pipeline_id_type: { id: 0, iid: 1 }
diff --git a/db/migrate/20231206183312_add_use_web_ide_extension_marketplace_to_user_preferences.rb b/db/migrate/20231206183312_add_use_web_ide_extension_marketplace_to_user_preferences.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1ea85760dbca96d71a7b54e4ee18272cd490f51e
--- /dev/null
+++ b/db/migrate/20231206183312_add_use_web_ide_extension_marketplace_to_user_preferences.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddUseWebIdeExtensionMarketplaceToUserPreferences < Gitlab::Database::Migration[2.2]
+ milestone '16.7'
+ enable_lock_retries!
+
+ def change
+ add_column :user_preferences, :use_web_ide_extension_marketplace, :boolean, default: false, null: false
+ end
+end
diff --git a/db/schema_migrations/20231206183312 b/db/schema_migrations/20231206183312
new file mode 100644
index 0000000000000000000000000000000000000000..639acbcf395790b99925a202c6c57ecc88fc0364
--- /dev/null
+++ b/db/schema_migrations/20231206183312
@@ -0,0 +1 @@
+6b1b75bc747a32ef9b360c4077579e8979eda1f81783c58b213a23803799ae31
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 1f2ed208630eaf7c2c356a4365156886625d4c9b..cb9877ecb6763421a69a9d7885e7df3f8dc2312a 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -24664,6 +24664,7 @@ CREATE TABLE user_preferences (
keyboard_shortcuts_enabled boolean DEFAULT true NOT NULL,
time_display_format smallint DEFAULT 0 NOT NULL,
home_organization_id bigint,
+ use_web_ide_extension_marketplace boolean DEFAULT false NOT NULL,
CONSTRAINT check_89bf269f41 CHECK ((char_length(diffs_deletion_color) <= 7)),
CONSTRAINT check_d07ccd35f7 CHECK ((char_length(diffs_addition_color) <= 7))
);
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 3f998bdef3155468a1fdfcb164e3a6df1283f16d..ccab04338899dd4802587109971d5fd567e81aab 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -8012,6 +8012,7 @@ Input type: `UserPreferencesUpdateInput`
| ---- | ---- | ----------- |
| `clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| `issuesSort` | [`IssueSort`](#issuesort) | Sort order for issue lists. |
+| `useWebIdeExtensionMarketplace` | [`Boolean`](#boolean) | Whether Web IDE Extension Marketplace is enabled for the user. |
| `visibilityPipelineIdType` | [`VisibilityPipelineIdType`](#visibilitypipelineidtype) | Determines whether the pipeline list shows ID or IID. |
#### Fields
@@ -27923,6 +27924,7 @@ fields relate to interactions between the two entities.
| Name | Type | Description |
| ---- | ---- | ----------- |
| `issuesSort` | [`IssueSort`](#issuesort) | Sort order for issue lists. |
+| `useWebIdeExtensionMarketplace` | [`Boolean!`](#boolean) | Whether Web IDE Extension Marketplace is enabled for the user. |
| `visibilityPipelineIdType` | [`VisibilityPipelineIdType`](#visibilitypipelineidtype) | Determines whether the pipeline list shows ID or IID. |
### `UserStatus`
diff --git a/spec/graphql/types/user_preferences_type_spec.rb b/spec/graphql/types/user_preferences_type_spec.rb
index 06749dda239ca85ee764520322184ee522b32c19..87fac17a5ba6b7d21457950f8645009716152b18 100644
--- a/spec/graphql/types/user_preferences_type_spec.rb
+++ b/spec/graphql/types/user_preferences_type_spec.rb
@@ -9,6 +9,7 @@
expected_fields = %i[
issues_sort
visibility_pipeline_id_type
+ use_web_ide_extension_marketplace
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb
index 65b8083c74f402727a4a887275f5c4d938a450d5..b1cd3259eebe8ffab06e127dde36ccaf61ad45af 100644
--- a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb
@@ -12,7 +12,8 @@
let(:input) do
{
'issuesSort' => sort_value,
- 'visibilityPipelineIdType' => 'IID'
+ 'visibilityPipelineIdType' => 'IID',
+ 'useWebIdeExtensionMarketplace' => true
}
end
@@ -26,19 +27,26 @@
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response['userPreferences']['issuesSort']).to eq(sort_value)
expect(mutation_response['userPreferences']['visibilityPipelineIdType']).to eq('IID')
+ expect(mutation_response['userPreferences']['useWebIdeExtensionMarketplace']).to eq(true)
expect(current_user.user_preference.persisted?).to eq(true)
expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s)
expect(current_user.user_preference.visibility_pipeline_id_type).to eq('iid')
+ expect(current_user.user_preference.use_web_ide_extension_marketplace).to eq(true)
end
end
context 'when user has existing preference' do
- before do
- current_user.create_user_preference!(
+ let(:init_user_preference) do
+ {
issues_sort: Types::IssueSortEnum.values['TITLE_DESC'].value,
- visibility_pipeline_id_type: 'id'
- )
+ visibility_pipeline_id_type: 'id',
+ use_web_ide_extension_marketplace: true
+ }
+ end
+
+ before do
+ current_user.create_user_preference!(init_user_preference)
end
it 'updates the existing value' do
@@ -53,5 +61,29 @@
expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s)
expect(current_user.user_preference.visibility_pipeline_id_type).to eq('iid')
end
+
+ context 'when input has nil attributes' do
+ let(:input) do
+ {
+ 'issuesSort' => nil,
+ 'visibilityPipelineIdType' => nil,
+ 'useWebIdeExtensionMarketplace' => nil
+ }
+ end
+
+ it 'updates only nullable attributes' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ current_user.user_preference.reload
+
+ expect(current_user.user_preference).to have_attributes({
+ # These are nullable and are exepcted to change
+ issues_sort: nil,
+ # These should not have changed
+ visibility_pipeline_id_type: init_user_preference[:visibility_pipeline_id_type],
+ use_web_ide_extension_marketplace: init_user_preference[:use_web_ide_extension_marketplace]
+ })
+ end
+ end
end
end