diff --git a/app/assets/javascripts/ci/runner/components/registration/cli_command.vue b/app/assets/javascripts/ci/runner/components/registration/cli_command.vue index e9e9f5e15fa..848722b1196 100644 --- a/app/assets/javascripts/ci/runner/components/registration/cli_command.vue +++ b/app/assets/javascripts/ci/runner/components/registration/cli_command.vue @@ -47,7 +47,7 @@ export default {
{{ prompt }} 
+ >{{ prompt }} diff --git a/app/assets/javascripts/clusters/agents/components/show.vue b/app/assets/javascripts/clusters/agents/components/show.vue index 9d4a720c416..f29bc09b70b 100644 --- a/app/assets/javascripts/clusters/agents/components/show.vue +++ b/app/assets/javascripts/clusters/agents/components/show.vue @@ -8,9 +8,13 @@ import { GlSprintf, GlTab, GlTabs, + GlButton, + GlModalDirective, } from '@gitlab/ui'; import { s__, __ } from '~/locale'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; +import { CONNECT_MODAL_ID } from '~/clusters_list/constants'; +import ConnectToAgentModal from '~/clusters_list/components/connect_to_agent_modal.vue'; import { MAX_LIST_COUNT } from '../constants'; import getClusterAgentQuery from '../graphql/queries/get_cluster_agent.query.graphql'; import TokenTable from './token_table.vue'; @@ -24,7 +28,9 @@ export default { tokens: s__('ClusterAgents|Access tokens'), unknownUser: s__('ClusterAgents|Unknown user'), activity: __('Activity'), + connectButtonText: s__('ClusterAgents|Connect to %{agentName}'), }, + connectModalId: CONNECT_MODAL_ID, apollo: { clusterAgent: { query: getClusterAgentQuery, @@ -49,10 +55,15 @@ export default { GlSprintf, GlTab, GlTabs, + GlButton, TimeAgoTooltip, TokenTable, ActivityEvents, IntegrationStatus, + ConnectToAgentModal, + }, + directives: { + GlModalDirective, }, inject: ['agentName', 'projectPath'], data() { @@ -85,6 +96,9 @@ export default { tokens() { return this.clusterAgent?.tokens?.nodes || []; }, + isUserAccessConfigured() { + return Boolean(this.clusterAgent?.userAccessAuthorizations); + }, }, methods: { nextPage() { @@ -107,7 +121,19 @@ export default { diff --git a/app/assets/javascripts/clusters/agents/graphql/queries/get_cluster_agent.query.graphql b/app/assets/javascripts/clusters/agents/graphql/queries/get_cluster_agent.query.graphql index 7be524f92c4..8b7695fba01 100644 --- a/app/assets/javascripts/clusters/agents/graphql/queries/get_cluster_agent.query.graphql +++ b/app/assets/javascripts/clusters/agents/graphql/queries/get_cluster_agent.query.graphql @@ -15,6 +15,10 @@ query getClusterAgent( id createdAt + userAccessAuthorizations { + config + } + createdByUser { id name diff --git a/app/assets/javascripts/clusters_list/components/agent_table.vue b/app/assets/javascripts/clusters_list/components/agent_table.vue index ea8716c78c6..b8dc4bb63f2 100644 --- a/app/assets/javascripts/clusters_list/components/agent_table.vue +++ b/app/assets/javascripts/clusters_list/components/agent_table.vue @@ -9,20 +9,30 @@ import { GlPopover, GlBadge, GlPagination, + GlDisclosureDropdown, + GlDisclosureDropdownItem, + GlModalDirective, } from '@gitlab/ui'; import semverLt from 'semver/functions/lt'; import semverInc from 'semver/functions/inc'; import semverPrerelease from 'semver/functions/prerelease'; +import { __, s__, sprintf } from '~/locale'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import timeagoMixin from '~/vue_shared/mixins/timeago'; import { helpPagePath } from '~/helpers/help_page_helper'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { MAX_LIST_COUNT, AGENT_STATUSES, I18N_AGENT_TABLE } from '../constants'; +import { MAX_LIST_COUNT, AGENT_STATUSES, I18N_AGENT_TABLE, CONNECT_MODAL_ID } from '../constants'; import { getAgentConfigPath } from '../clusters_util'; import DeleteAgentButton from './delete_agent_button.vue'; +import ConnectToAgentModal from './connect_to_agent_modal.vue'; export default { - i18n: I18N_AGENT_TABLE, + i18n: { + ...I18N_AGENT_TABLE, + connectActionText: s__('ClusterAgents|Connect to %{agentName}'), + deleteActionText: s__('ClusterAgents|Delete agent'), + actions: __('Actions'), + }, components: { GlLink, GlTable, @@ -32,11 +42,15 @@ export default { GlPopover, GlBadge, GlPagination, + GlDisclosureDropdown, + GlDisclosureDropdownItem, TimeAgoTooltip, DeleteAgentButton, + ConnectToAgentModal, }, directives: { GlTooltip: GlTooltipDirective, + GlModalDirective, }, mixins: [timeagoMixin], AGENT_STATUSES, @@ -47,7 +61,7 @@ export default { configHelpLink: helpPagePath('user/clusters/agent/install/index', { anchor: 'create-an-agent-configuration-file', }), - inject: ['kasCheckVersion'], + inject: ['kasCheckVersion', 'projectPath'], props: { agents: { required: true, @@ -68,6 +82,7 @@ export default { return { currentPage: 1, limit: this.maxAgents ?? MAX_LIST_COUNT, + selectedAgent: null, }; }, computed: { @@ -131,6 +146,9 @@ export default { const nextPage = this.currentPage + 1; return nextPage > Math.ceil(this.agents.length / this.limit) ? null : nextPage; }, + isUserAccessConfigured() { + return Boolean(this.selectedAgent?.userAccessAuthorizations); + }, }, methods: { getStatusCellId(item) { @@ -198,6 +216,31 @@ export default { return null; }, + + getActions(item) { + const connectAction = { + text: sprintf(this.$options.i18n.connectActionText, { agentName: item.name }), + name: 'connect-agent', + modalId: CONNECT_MODAL_ID, + action: () => { + this.selectedAgent = item; + }, + }; + const deleteAction = { + text: this.$options.i18n.deleteActionText, + name: 'delete-agent', + action: () => { + this.selectedAgent = item; + }, + }; + + const actions = [connectAction]; + if (!item.isShared) { + actions.push(deleteAction); + } + + return actions; + }, }, }; @@ -342,11 +385,32 @@ export default { @@ -358,5 +422,12 @@ export default { align="center" class="gl-mt-5" /> + + diff --git a/app/assets/javascripts/clusters_list/components/connect_to_agent_modal.vue b/app/assets/javascripts/clusters_list/components/connect_to_agent_modal.vue new file mode 100644 index 00000000000..0a8bd546e72 --- /dev/null +++ b/app/assets/javascripts/clusters_list/components/connect_to_agent_modal.vue @@ -0,0 +1,130 @@ + + + diff --git a/app/assets/javascripts/clusters_list/components/delete_agent_button.vue b/app/assets/javascripts/clusters_list/components/delete_agent_button.vue index 4088d5c79f7..ead87d93f22 100644 --- a/app/assets/javascripts/clusters_list/components/delete_agent_button.vue +++ b/app/assets/javascripts/clusters_list/components/delete_agent_button.vue @@ -7,6 +7,7 @@ import { GlFormGroup, GlFormInput, GlTooltipDirective, + GlDisclosureDropdownItem, } from '@gitlab/ui'; import { sprintf } from '~/locale'; import { DELETE_AGENT_BUTTON, DELETE_AGENT_MODAL_ID } from '../constants'; @@ -22,6 +23,7 @@ export default { GlSprintf, GlFormGroup, GlFormInput, + GlDisclosureDropdownItem, }, directives: { GlModalDirective, @@ -53,8 +55,7 @@ export default { return this.loading || !this.canAdminCluster; }, deleteButtonTooltip() { - const { deleteButton, disabledHint } = this.$options.i18n; - return this.deleteButtonDisabled ? disabledHint : deleteButton; + return this.deleteButtonDisabled ? this.$options.i18n.disabledHint : ''; }, getAgentsQueryVariables() { return { @@ -145,28 +146,33 @@ export default { this.error = null; this.deleteConfirmText = null; }, + showModal() { + this.$refs.modal?.show(); + }, }, };