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