diff --git a/ee/app/assets/javascripts/workspaces/agent_mapping/components/agent_mapping.vue b/ee/app/assets/javascripts/workspaces/agent_mapping/components/agent_mapping.vue index c340fb97109174211ae69cee1fa462f08e665b12..c7b8e2abc3e7fc87b3661b61270438129f21c794 100644 --- a/ee/app/assets/javascripts/workspaces/agent_mapping/components/agent_mapping.vue +++ b/ee/app/assets/javascripts/workspaces/agent_mapping/components/agent_mapping.vue @@ -31,6 +31,7 @@ export default { return { agents: [], errorMessage: '', + namespaceId: '', }; }, computed: { @@ -48,7 +49,8 @@ export default { }, }, methods: { - onQueryResult({ agents }) { + onQueryResult({ agents, namespaceId }) { + this.namespaceId = namespaceId; this.agents = agents; }, onErrorResult() { @@ -80,6 +82,7 @@ export default { v-if="!errorMessage" data-testid="allowed-agents-table" :agents="allowedAgents" + :namespace-id="namespaceId" :is-loading="loading" :empty-state-message="allowedAgentsTableEmptyMessage" /> @@ -93,9 +96,10 @@ export default { diff --git a/ee/app/assets/javascripts/workspaces/agent_mapping/components/agents_table.vue b/ee/app/assets/javascripts/workspaces/agent_mapping/components/agents_table.vue index 8adca77416cd2094420901ddbf45e539411f3c05..ac204e5b222687c8198e6c7609cba1615c284c0d 100644 --- a/ee/app/assets/javascripts/workspaces/agent_mapping/components/agents_table.vue +++ b/ee/app/assets/javascripts/workspaces/agent_mapping/components/agents_table.vue @@ -35,6 +35,11 @@ export default { type: Array, required: true, }, + namespaceId: { + type: String, + required: false, + default: '', + }, emptyStateMessage: { type: String, required: true, diff --git a/ee/app/assets/javascripts/workspaces/agent_mapping/components/get_agents_with_mapping_status_query.vue b/ee/app/assets/javascripts/workspaces/agent_mapping/components/get_agents_with_mapping_status_query.vue index 1303a52d3e0b68e0a14357b6df33f7e0aca09c3b..bf78bfe6b2c476d8a682b083edc39245dde82528 100644 --- a/ee/app/assets/javascripts/workspaces/agent_mapping/components/get_agents_with_mapping_status_query.vue +++ b/ee/app/assets/javascripts/workspaces/agent_mapping/components/get_agents_with_mapping_status_query.vue @@ -34,7 +34,11 @@ export default { return; } - const { remoteDevelopmentClusterAgents, clusterAgents } = result.data.group; + const { + remoteDevelopmentClusterAgents, + clusterAgents, + id: namespaceId, + } = result.data.group; const agents = clusterAgents?.nodes.map(({ id, name }) => { @@ -51,7 +55,7 @@ export default { }; }) || []; - this.$emit('result', { agents }); + this.$emit('result', { namespaceId, agents }); }, }, }, diff --git a/ee/app/assets/javascripts/workspaces/settings/init_settings_app.js b/ee/app/assets/javascripts/workspaces/settings/init_settings_app.js index c5d39a2a1d8ffc825ae6ce0c9a3a3325cbafa38d..814a3e397ffbbd70086c32a6c6e933348a841b5e 100644 --- a/ee/app/assets/javascripts/workspaces/settings/init_settings_app.js +++ b/ee/app/assets/javascripts/workspaces/settings/init_settings_app.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createDefaultClient from '~/lib/graphql'; -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils'; import App from './pages/app.vue'; Vue.use(VueApollo); @@ -19,7 +19,7 @@ const initWorkspacesSettingsApp = () => { return null; } - const { namespace } = convertObjectPropsToCamelCase(el.dataset); + const { namespace, canAdminClusterAgentMapping } = convertObjectPropsToCamelCase(el.dataset); return new Vue({ el, @@ -27,6 +27,7 @@ const initWorkspacesSettingsApp = () => { apolloProvider: createApolloProvider(), provide: { namespace, + canAdminClusterAgentMapping: parseBoolean(canAdminClusterAgentMapping), }, render: (createElement) => createElement(App), }); diff --git a/ee/app/views/groups/settings/remote_development/workspaces/show.html.haml b/ee/app/views/groups/settings/remote_development/workspaces/show.html.haml index 6ca6e3c6cbdbfeca777dd9349dc6673fad79effc..1b72edee5a973e2e05ffc5de6c0e846d9c272ba6 100644 --- a/ee/app/views/groups/settings/remote_development/workspaces/show.html.haml +++ b/ee/app/views/groups/settings/remote_development/workspaces/show.html.haml @@ -1,4 +1,6 @@ - page_title s_('Workspaces|Workspaces Settings') - breadcrumb_title s_("Workspaces|Workspaces Settings") -#js-workspaces-settings{ data: { namespace: @group.full_path } } +#js-workspaces-settings{ data: { + namespace: @group.full_path, + can_admin_cluster_agent_mapping: can?(current_user, :admin_remote_development_cluster_agent_mapping, @group).to_s } } diff --git a/ee/spec/frontend/workspaces/agent_mapping/components/agent_mapping_spec.js b/ee/spec/frontend/workspaces/agent_mapping/components/agent_mapping_spec.js index f12e09f1bec20b4636e72dea8e3c5aac19c106ab..bb419233bc66cc08df07563adf6a2a426e61abd5 100644 --- a/ee/spec/frontend/workspaces/agent_mapping/components/agent_mapping_spec.js +++ b/ee/spec/frontend/workspaces/agent_mapping/components/agent_mapping_spec.js @@ -1,16 +1,13 @@ import { nextTick } from 'vue'; import { GlAlert, GlTabs, GlTab, GlBadge } from '@gitlab/ui'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; - -import { - AGENT_MAPPING_STATUS_MAPPED, - AGENT_MAPPING_STATUS_UNMAPPED, -} from 'ee/workspaces/agent_mapping/constants'; import AgentMapping from 'ee_component/workspaces/agent_mapping/components/agent_mapping.vue'; import GetAgentsWithMappingStatusQuery from 'ee_component/workspaces/agent_mapping/components/get_agents_with_mapping_status_query.vue'; +import { AGENT_MAPPING_STATUS_MAPPED } from 'ee/workspaces/agent_mapping/constants'; import { stubComponent } from 'helpers/stub_component'; +import { NAMESPACE_ID, MAPPED_CLUSTER_AGENT, UNMAPPED_CLUSTER_AGENT } from '../../mock_data'; -describe('workspaces/agent_mapping/components/agent_mapping.vue', () => { +describe('workspaces/agent_mapping/components/agent_mapping', () => { let wrapper; const NAMESPACE = 'foo/bar'; @@ -38,6 +35,12 @@ describe('workspaces/agent_mapping/components/agent_mapping.vue', () => { const findErrorAlert = () => wrapper.findComponent(GlAlert); const findAllowedAgentsTab = () => wrapper.findByTestId('allowed-agents-tab'); const findAllAgentsTab = () => wrapper.findByTestId('all-agents-tab'); + const triggerQueryResultEvent = (result) => { + findGetAgentsWithMappingStatusQuery().vm.$emit('result', { + namespaceId: NAMESPACE_ID, + ...result, + }); + }; describe('default', () => { beforeEach(() => { @@ -64,26 +67,18 @@ describe('workspaces/agent_mapping/components/agent_mapping.vue', () => { buildWrapper(); agents = [ + MAPPED_CLUSTER_AGENT, + UNMAPPED_CLUSTER_AGENT, { - id: 'agent-1', - name: 'agent one', - mappingStatus: AGENT_MAPPING_STATUS_MAPPED, - }, - { - id: 'agent-2', - name: 'agent two', - mappingStatus: AGENT_MAPPING_STATUS_UNMAPPED, - }, - { + ...UNMAPPED_CLUSTER_AGENT, id: 'agent-3', name: 'agent three', - mappingStatus: AGENT_MAPPING_STATUS_UNMAPPED, }, ]; allowedAgents = agents.filter( (agent) => agent.mappingStatus === AGENT_MAPPING_STATUS_MAPPED, ); - findGetAgentsWithMappingStatusQuery().vm.$emit('result', { agents }); + triggerQueryResultEvent({ agents }); await nextTick(); }); @@ -99,6 +94,11 @@ describe('workspaces/agent_mapping/components/agent_mapping.vue', () => { ); }); + it('passes namespaceId to all tables', () => { + expect(findAllowedAgentsTable().props('namespaceId')).toEqual(NAMESPACE_ID); + expect(findAllAgentsTable().props('namespaceId')).toEqual(NAMESPACE_ID); + }); + it('passes allowed agents to the allowed agents table', () => { expect(findAllowedAgentsTable().props('agents')).toEqual(allowedAgents); }); @@ -116,18 +116,14 @@ describe('workspaces/agent_mapping/components/agent_mapping.vue', () => { buildWrapper(); agents = [ + UNMAPPED_CLUSTER_AGENT, { - id: 'agent-2', - name: 'agent two', - mappingStatus: AGENT_MAPPING_STATUS_UNMAPPED, - }, - { + ...UNMAPPED_CLUSTER_AGENT, id: 'agent-3', name: 'agent three', - mappingStatus: AGENT_MAPPING_STATUS_UNMAPPED, }, ]; - findGetAgentsWithMappingStatusQuery().vm.$emit('result', { agents }); + triggerQueryResultEvent({ agents }); await nextTick(); }); @@ -143,7 +139,7 @@ describe('workspaces/agent_mapping/components/agent_mapping.vue', () => { buildWrapper(); agents = []; - findGetAgentsWithMappingStatusQuery().vm.$emit('result', { agents }); + triggerQueryResultEvent({ agents }); await nextTick(); }); diff --git a/ee/spec/frontend/workspaces/agent_mapping/components/get_agents_with_mapping_status_query_spec.js b/ee/spec/frontend/workspaces/agent_mapping/components/get_agents_with_mapping_status_query_spec.js index d260c1cd620125331852411418ac5cabbc40d5be..e9bd806f1e6bb08066cc01c353c66de459fa097c 100644 --- a/ee/spec/frontend/workspaces/agent_mapping/components/get_agents_with_mapping_status_query_spec.js +++ b/ee/spec/frontend/workspaces/agent_mapping/components/get_agents_with_mapping_status_query_spec.js @@ -85,6 +85,7 @@ describe('workspaces/agent_mapping/components/get_agents_with_mapping_status_que expect(wrapper.emitted('result')).toEqual([ [ { + namespaceId: GET_AGENTS_WITH_MAPPING_STATUS_QUERY_RESULT.data.group.id, agents: [ { id: 'gid://gitlab/Clusters::Agent/1', diff --git a/ee/spec/frontend/workspaces/mock_data/index.js b/ee/spec/frontend/workspaces/mock_data/index.js index 4fb266153ca925ac31a8bc774f211d6d26f22770..b884e492e6459c127abd3a2c8df0a589eb64ea03 100644 --- a/ee/spec/frontend/workspaces/mock_data/index.js +++ b/ee/spec/frontend/workspaces/mock_data/index.js @@ -1,6 +1,10 @@ import { cloneDeep } from 'lodash'; import { TEST_HOST } from 'helpers/test_constants'; import { WORKSPACE_DESIRED_STATES, WORKSPACE_STATES } from 'ee/workspaces/common/constants'; +import { + AGENT_MAPPING_STATUS_MAPPED, + AGENT_MAPPING_STATUS_UNMAPPED, +} from 'ee/workspaces/agent_mapping/constants'; export const WORKSPACE = { __typename: 'Workspace', @@ -402,3 +406,33 @@ export const WORKSPACE_UPDATE_MUTATION_RESULT = { }, }, }; + +export const CREATE_CLUSTER_AGENT_MAPPING_MUTATION_RESULT = { + data: { + namespaceCreateRemoteDevelopmentClusterAgentMapping: { + clientMutationId: null, + }, + }, +}; + +export const DELETE_CLUSTER_AGENT_MAPPING_MUTATION_RESULT = { + data: { + namespaceDeleteRemoteDevelopmentClusterAgentMapping: { + clientMutationId: null, + }, + }, +}; + +export const MAPPED_CLUSTER_AGENT = { + id: 'gid://gitlab/Clusters::Agent/1', + name: 'rootgroup-agent', + mappingStatus: AGENT_MAPPING_STATUS_MAPPED, +}; + +export const UNMAPPED_CLUSTER_AGENT = { + id: 'gid://gitlab/Clusters::Agent/2', + name: 'rootgroup-agent-2', + mappingStatus: AGENT_MAPPING_STATUS_UNMAPPED, +}; + +export const NAMESPACE_ID = 'gid://gitlab/Group/81';