diff --git a/app/views/admin/application_settings/general.html.haml b/app/views/admin/application_settings/general.html.haml index b8c7df18e89ceef07fe22228f0a441d02032008e..e480b9879b046eb27233e24178a6358ce7af3719 100644 --- a/app/views/admin/application_settings/general.html.haml +++ b/app/views/admin/application_settings/general.html.haml @@ -105,6 +105,7 @@ = render 'admin/application_settings/floc' = render_if_exists 'admin/application_settings/add_license' = render 'admin/application_settings/cluster_agents' += render_if_exists 'admin/application_settings/workspaces/agent_availability' = render 'admin/application_settings/jira_connect' = render 'admin/application_settings/slack' = render 'admin/application_settings/security_txt', expanded: expanded_by_default? diff --git a/ee/app/assets/javascripts/pages/admin/application_settings/general/index.js b/ee/app/assets/javascripts/pages/admin/application_settings/general/index.js index 46da4fb69a582c15ebe63e1a91fe945e00298601..242513b6f009c54c6576f92b28a0605de6c34a6e 100644 --- a/ee/app/assets/javascripts/pages/admin/application_settings/general/index.js +++ b/ee/app/assets/javascripts/pages/admin/application_settings/general/index.js @@ -1,4 +1,5 @@ import '~/pages/admin/application_settings/general/index'; +import { initWorkspacesAgentAvailabilityApp } from 'ee/workspaces/admin_settings/init_admin_settings_app'; import { initPrivateProfileRestrictions } from 'ee/admin/application_settings/user_restrictions'; import initAddLicenseApp from 'ee/admin/application_settings/general/add_license'; import { initScimTokenApp } from 'ee/saml_sso'; @@ -14,3 +15,4 @@ initScimTokenApp(); initPrivateProfileRestrictions(); initInputCopyToggleVisibility(); initAllowedIntegrations(); +initWorkspacesAgentAvailabilityApp(); diff --git a/ee/app/assets/javascripts/workspaces/admin_settings/constants.js b/ee/app/assets/javascripts/workspaces/admin_settings/constants.js new file mode 100644 index 0000000000000000000000000000000000000000..f9e3abc56e9c5e0f8375b89362bb277150f9f2cc --- /dev/null +++ b/ee/app/assets/javascripts/workspaces/admin_settings/constants.js @@ -0,0 +1,21 @@ +import { s__ } from '~/locale'; + +const AVAILABILITY_OPTIONS = { + AVAILABLE: 'available', + BLOCKED: 'blocked', +}; + +export const CONNECTION_STATUS = { + CONNECTED: 'connected', + NOT_CONNECTED: 'not_connected', +}; + +export const AVAILABILITY_TEXT = { + [AVAILABILITY_OPTIONS.AVAILABLE]: s__('Workspaces|Available'), + [AVAILABILITY_OPTIONS.BLOCKED]: s__('Workspaces|Blocked'), +}; + +export const CONNECTION_STATUS_TEXT = { + [CONNECTION_STATUS.CONNECTED]: s__('Workspaces|Connected'), + [CONNECTION_STATUS.NOT_CONNECTED]: s__('Workspaces|Not connected'), +}; diff --git a/ee/app/assets/javascripts/workspaces/admin_settings/init_admin_settings_app.js b/ee/app/assets/javascripts/workspaces/admin_settings/init_admin_settings_app.js new file mode 100644 index 0000000000000000000000000000000000000000..54e81abaa3c02ebe1a05ecd0b45093511db20f8f --- /dev/null +++ b/ee/app/assets/javascripts/workspaces/admin_settings/init_admin_settings_app.js @@ -0,0 +1,20 @@ +import Vue from 'vue'; +import WorkspacesAgentAvailabilityApp from './pages/app.vue'; + +const initWorkspacesAgentAvailabilityApp = () => { + const el = document.getElementById('js-workspaces-agent-availability-settings-body'); + + if (!el) return null; + + return new Vue({ + el, + components: { + WorkspacesAgentAvailabilityApp, + }, + render(createElement) { + return createElement(WorkspacesAgentAvailabilityApp); + }, + }); +}; + +export { initWorkspacesAgentAvailabilityApp }; diff --git a/ee/app/assets/javascripts/workspaces/admin_settings/pages/app.vue b/ee/app/assets/javascripts/workspaces/admin_settings/pages/app.vue new file mode 100644 index 0000000000000000000000000000000000000000..f50a6239cf206ff580ecaded26236a33eb56b318 --- /dev/null +++ b/ee/app/assets/javascripts/workspaces/admin_settings/pages/app.vue @@ -0,0 +1,99 @@ + + diff --git a/ee/app/views/admin/application_settings/workspaces/_agent_availability.html.haml b/ee/app/views/admin/application_settings/workspaces/_agent_availability.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..3a41cf7eda62b1ae9b58741ac84a38601968a9e2 --- /dev/null +++ b/ee/app/views/admin/application_settings/workspaces/_agent_availability.html.haml @@ -0,0 +1,9 @@ +- return unless ::License.feature_available?(:remote_development) && ::Feature.enabled?(:workspaces_agents_availability_admin, current_user) + += render ::Layouts::SettingsBlockComponent.new(s_('Workspaces|Workspaces Agent Availability'), + id: 'js-workspaces-agent-availability-settings', + expanded: expanded_by_default?) do |setting| + - setting.with_description do + = s_('Workspaces|Configure which Kubernetes agents are available for new workspaces. These settings do not affect existing workspaces.') + - setting.with_body do + #js-workspaces-agent-availability-settings-body diff --git a/ee/config/feature_flags/wip/workspaces_agents_availability_admin.yml b/ee/config/feature_flags/wip/workspaces_agents_availability_admin.yml new file mode 100644 index 0000000000000000000000000000000000000000..1ebf754f84cc4b9c8b00467584e490ca08e9cdde --- /dev/null +++ b/ee/config/feature_flags/wip/workspaces_agents_availability_admin.yml @@ -0,0 +1,10 @@ +--- +name: workspaces_agents_availability_admin +description: Enables the development of the Workspace agents availability admin page +feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/513370 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/191120 +rollout_issue_url: +milestone: '18.1' +group: group::remote development +type: wip +default_enabled: false 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 a102f52f04d009eeff477f78111e2ea5d00651c6..5e7385805c18c467a16e7328212c8e363d389a1e 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 @@ -153,4 +153,12 @@ end end end + + describe 'Workspaces agent availability settings', feature_category: :remote_development do + it 'renders correct ee partial' do + render + + expect(rendered).to render_template('admin/application_settings/workspaces/_agent_availability') + end + end end diff --git a/ee/spec/views/admin/application_settings/workspaces/_agent_availability.html.haml_spec.rb b/ee/spec/views/admin/application_settings/workspaces/_agent_availability.html.haml_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..2cf14d3ae22c9e64361c65c51c9722ad198462bb --- /dev/null +++ b/ee/spec/views/admin/application_settings/workspaces/_agent_availability.html.haml_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'admin/application_settings/_workspaces_agent_availability', feature_category: :workspaces do + let_it_be(:user) { build_stubbed(:admin) } + let_it_be(:app_settings) { build(:application_setting) } + + # 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/workspaces/agent_availability') } + + before do + assign(:application_setting, app_settings) + allow(view).to receive(:current_user).and_return(user) + end + + [true, false].each do |license_enabled| + [true, false].each do |flag_enabled| + context "when license is #{license_enabled ? 'enabled' : 'disabled'} " \ + "and flag is #{flag_enabled ? 'on' : 'off'}" do + before do + stub_licensed_features(remote_development: license_enabled) + stub_feature_flags(workspaces_agents_availability_admin: flag_enabled) + end + + it "#{license_enabled && flag_enabled ? 'renders' : 'does not render'} settings" do + if license_enabled && flag_enabled + expect(rendered).to have_selector('#js-workspaces-agent-availability-settings') + else + expect(rendered).to be_nil + end + end + end + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c269cb2ffadcc1a60ebb9fb72ad6ba03e2a5c667..bd6299c8538a05d82a7a301b4985b9154a73ea33 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -70137,12 +70137,21 @@ msgstr "" msgid "Workspaces|Allowed agents" msgstr "" +msgid "Workspaces|Availability" +msgstr "" + +msgid "Workspaces|Available" +msgstr "" + msgid "Workspaces|Block agent" msgstr "" msgid "Workspaces|Block this agent for all group members?" msgstr "" +msgid "Workspaces|Blocked" +msgstr "" + msgid "Workspaces|Blocking an agent doesn't delete it. Agents can only be deleted in the project where they were created." msgstr "" @@ -70152,6 +70161,12 @@ msgstr "" msgid "Workspaces|Cluster agent" msgstr "" +msgid "Workspaces|Configure which Kubernetes agents are available for new workspaces. These settings do not affect existing workspaces." +msgstr "" + +msgid "Workspaces|Connected" +msgstr "" + msgid "Workspaces|Could not load available agents. Refresh the page to try again." msgstr "" @@ -70209,6 +70224,9 @@ msgstr "" msgid "Workspaces|GitLab devfile" msgstr "" +msgid "Workspaces|Group" +msgstr "" + msgid "Workspaces|Group agents" msgstr "" @@ -70227,18 +70245,27 @@ msgstr "" msgid "Workspaces|Learn more." msgstr "" +msgid "Workspaces|Name" +msgstr "" + msgid "Workspaces|New workspace" msgstr "" msgid "Workspaces|No active workspaces" msgstr "" +msgid "Workspaces|No agents available" +msgstr "" + msgid "Workspaces|No agents available to create workspaces. Please consult %{linkStart}Workspaces documentation%{linkEnd} for troubleshooting." msgstr "" msgid "Workspaces|No terminated workspaces" msgstr "" +msgid "Workspaces|Not connected" +msgstr "" + msgid "Workspaces|Open workspace" msgstr "" @@ -70269,6 +70296,9 @@ msgstr "" msgid "Workspaces|Starting workspace" msgstr "" +msgid "Workspaces|Status" +msgstr "" + msgid "Workspaces|Stop" msgstr "" @@ -70329,6 +70359,9 @@ msgstr "" msgid "Workspaces|Workspaces" msgstr "" +msgid "Workspaces|Workspaces Agent Availability" +msgstr "" + msgid "Workspaces|Workspaces Settings" msgstr ""