Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/clusters_list/components/install_agent_modal.vue')
-rw-r--r--app/assets/javascripts/clusters_list/components/install_agent_modal.vue325
1 files changed, 231 insertions, 94 deletions
diff --git a/app/assets/javascripts/clusters_list/components/install_agent_modal.vue b/app/assets/javascripts/clusters_list/components/install_agent_modal.vue
index 6eb2e85ecea..5eef76252bd 100644
--- a/app/assets/javascripts/clusters_list/components/install_agent_modal.vue
+++ b/app/assets/javascripts/clusters_list/components/install_agent_modal.vue
@@ -9,22 +9,48 @@ import {
GlSprintf,
} from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
import CodeBlock from '~/vue_shared/components/code_block.vue';
+import Tracking from '~/tracking';
import { generateAgentRegistrationCommand } from '../clusters_util';
-import { INSTALL_AGENT_MODAL_ID, I18N_INSTALL_AGENT_MODAL } from '../constants';
-import { addAgentToStore } from '../graphql/cache_update';
+import {
+ INSTALL_AGENT_MODAL_ID,
+ I18N_AGENT_MODAL,
+ KAS_DISABLED_ERROR,
+ EVENT_LABEL_MODAL,
+ EVENT_ACTIONS_OPEN,
+ EVENT_ACTIONS_SELECT,
+ EVENT_ACTIONS_CLICK,
+ MODAL_TYPE_EMPTY,
+ MODAL_TYPE_REGISTER,
+} from '../constants';
+import { addAgentToStore, addAgentConfigToStore } from '../graphql/cache_update';
import createAgent from '../graphql/mutations/create_agent.mutation.graphql';
import createAgentToken from '../graphql/mutations/create_agent_token.mutation.graphql';
import getAgentsQuery from '../graphql/queries/get_agents.query.graphql';
+import agentConfigurations from '../graphql/queries/agent_configurations.query.graphql';
import AvailableAgentsDropdown from './available_agents_dropdown.vue';
+const trackingMixin = Tracking.mixin({ label: EVENT_LABEL_MODAL });
+
export default {
modalId: INSTALL_AGENT_MODAL_ID,
- i18n: I18N_INSTALL_AGENT_MODAL,
+ EVENT_ACTIONS_OPEN,
+ EVENT_ACTIONS_CLICK,
+ EVENT_LABEL_MODAL,
+ basicInstallPath: helpPagePath('user/clusters/agent/install/index', {
+ anchor: 'install-the-agent-into-the-cluster',
+ }),
+ advancedInstallPath: helpPagePath('user/clusters/agent/install/index', {
+ anchor: 'advanced-installation',
+ }),
+ enableKasPath: helpPagePath('administration/clusters/kas'),
+ installAgentPath: helpPagePath('user/clusters/agent/install/index'),
+ registerAgentPath: helpPagePath('user/clusters/agent/install/index', {
+ anchor: 'register-an-agent-with-gitlab',
+ }),
components: {
AvailableAgentsDropdown,
- ClipboardButton,
CodeBlock,
GlAlert,
GlButton,
@@ -33,8 +59,10 @@ export default {
GlLink,
GlModal,
GlSprintf,
+ ModalCopyButton,
},
- inject: ['projectPath', 'kasAddress'],
+ mixins: [trackingMixin],
+ inject: ['projectPath', 'kasAddress', 'emptyStateImage'],
props: {
defaultBranchName: {
default: '.noBranch',
@@ -46,6 +74,22 @@ export default {
type: Number,
},
},
+ apollo: {
+ agents: {
+ query: agentConfigurations,
+ variables() {
+ return {
+ projectPath: this.projectPath,
+ };
+ },
+ update(data) {
+ this.populateAvailableAgents(data);
+ },
+ error(error) {
+ this.kasDisabled = error?.message?.indexOf(KAS_DISABLED_ERROR) >= 0;
+ },
+ },
+ },
data() {
return {
registering: false,
@@ -53,6 +97,8 @@ export default {
agentToken: null,
error: null,
clusterAgent: null,
+ availableAgents: [],
+ kasDisabled: false,
};
},
computed: {
@@ -63,19 +109,11 @@ export default {
return !this.registering && this.agentName !== null;
},
canCancel() {
- return !this.registered && !this.registering;
+ return !this.registered && !this.registering && this.isAgentRegistrationModal;
},
agentRegistrationCommand() {
return generateAgentRegistrationCommand(this.agentToken, this.kasAddress);
},
- basicInstallPath() {
- return helpPagePath('user/clusters/agent/install/index', {
- anchor: 'install-the-agent-into-the-cluster',
- });
- },
- advancedInstallPath() {
- return helpPagePath('user/clusters/agent/install/index', { anchor: 'advanced-installation' });
- },
getAgentsQueryVariables() {
return {
defaultBranchName: this.defaultBranchName,
@@ -84,10 +122,31 @@ export default {
projectPath: this.projectPath,
};
},
+ i18n() {
+ return I18N_AGENT_MODAL[this.modalType];
+ },
+ repositoryPath() {
+ return `/${this.projectPath}`;
+ },
+ modalType() {
+ return !this.availableAgents?.length && !this.registered
+ ? MODAL_TYPE_EMPTY
+ : MODAL_TYPE_REGISTER;
+ },
+ modalSize() {
+ return this.isEmptyStateModal ? 'sm' : 'md';
+ },
+ isEmptyStateModal() {
+ return this.modalType === MODAL_TYPE_EMPTY;
+ },
+ isAgentRegistrationModal() {
+ return this.modalType === MODAL_TYPE_REGISTER;
+ },
},
methods: {
setAgentName(name) {
this.agentName = name;
+ this.track(EVENT_ACTIONS_SELECT);
},
closeModal() {
this.$refs.modal.hide();
@@ -96,8 +155,16 @@ export default {
this.registering = false;
this.agentName = null;
this.agentToken = null;
+ this.clusterAgent = null;
this.error = null;
},
+ populateAvailableAgents(data) {
+ const installedAgents = data?.project?.clusterAgents?.nodes.map((agent) => agent.name) ?? [];
+ const configuredAgents =
+ data?.project?.agentConfigurations?.nodes.map((config) => config.agentName) ?? [];
+
+ this.availableAgents = configuredAgents.filter((agent) => !installedAgents.includes(agent));
+ },
createAgentMutation() {
return this.$apollo
.mutate({
@@ -117,7 +184,9 @@ export default {
);
},
})
- .then(({ data: { createClusterAgent } }) => createClusterAgent);
+ .then(({ data: { createClusterAgent } }) => {
+ return createClusterAgent;
+ });
},
createAgentTokenMutation(agendId) {
return this.$apollo
@@ -129,6 +198,17 @@ export default {
name: this.agentName,
},
},
+ update: (store, { data: { clusterAgentTokenCreate } }) => {
+ addAgentConfigToStore(
+ store,
+ clusterAgentTokenCreate,
+ this.clusterAgent,
+ agentConfigurations,
+ {
+ projectPath: this.projectPath,
+ },
+ );
+ },
})
.then(({ data: { clusterAgentTokenCreate } }) => clusterAgentTokenCreate);
},
@@ -158,7 +238,7 @@ export default {
if (error) {
this.error = error.message;
} else {
- this.error = this.$options.i18n.unknownError;
+ this.error = this.i18n.unknownError;
}
} finally {
this.registering = false;
@@ -172,115 +252,172 @@ export default {
<gl-modal
ref="modal"
:modal-id="$options.modalId"
- :title="$options.i18n.modalTitle"
+ :title="i18n.modalTitle"
+ :size="modalSize"
static
lazy
@hidden="resetModal"
+ @show="track($options.EVENT_ACTIONS_OPEN, { property: modalType })"
>
- <template v-if="!registered">
- <p>
- <strong>{{ $options.i18n.selectAgentTitle }}</strong>
- </p>
+ <template v-if="isAgentRegistrationModal">
+ <template v-if="!registered">
+ <p>
+ <strong>{{ i18n.selectAgentTitle }}</strong>
+ </p>
- <p>
- <gl-sprintf :message="$options.i18n.selectAgentBody">
- <template #link="{ content }">
- <gl-link :href="basicInstallPath" target="_blank"> {{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
+ <p class="gl-mb-0">{{ i18n.selectAgentBody }}</p>
+ <p>
+ <gl-link :href="$options.registerAgentPath"> {{ i18n.learnMoreLink }}</gl-link>
+ </p>
- <form>
- <gl-form-group label-for="agent-name">
- <available-agents-dropdown
- class="gl-w-70p"
- :is-registering="registering"
- @agentSelected="setAgentName"
- />
- </gl-form-group>
- </form>
+ <form>
+ <gl-form-group label-for="agent-name">
+ <available-agents-dropdown
+ class="gl-w-70p"
+ :is-registering="registering"
+ :available-agents="availableAgents"
+ @agentSelected="setAgentName"
+ />
+ </gl-form-group>
+ </form>
- <p v-if="error">
- <gl-alert
- :title="$options.i18n.registrationErrorTitle"
- variant="danger"
- :dismissible="false"
- >
- {{ error }}
- </gl-alert>
- </p>
- </template>
+ <p v-if="error">
+ <gl-alert :title="i18n.registrationErrorTitle" variant="danger" :dismissible="false">
+ {{ error }}
+ </gl-alert>
+ </p>
+ </template>
- <template v-else>
- <p>
- <strong>{{ $options.i18n.tokenTitle }}</strong>
- </p>
+ <template v-else>
+ <p>
+ <strong>{{ i18n.tokenTitle }}</strong>
+ </p>
- <p>
- <gl-sprintf :message="$options.i18n.tokenBody">
- <template #link="{ content }">
- <gl-link :href="basicInstallPath" target="_blank"> {{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
+ <p>
+ <gl-sprintf :message="i18n.tokenBody">
+ <template #link="{ content }">
+ <gl-link :href="$options.basicInstallPath" target="_blank"> {{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
- <p>
- <gl-alert
- :title="$options.i18n.tokenSingleUseWarningTitle"
- variant="warning"
- :dismissible="false"
- >
- {{ $options.i18n.tokenSingleUseWarningBody }}
- </gl-alert>
- </p>
+ <p>
+ <gl-alert :title="i18n.tokenSingleUseWarningTitle" variant="warning" :dismissible="false">
+ {{ i18n.tokenSingleUseWarningBody }}
+ </gl-alert>
+ </p>
- <p>
- <gl-form-input-group readonly :value="agentToken" :select-on-click="true">
- <template #append>
- <clipboard-button :text="agentToken" :title="$options.i18n.copyToken" />
- </template>
- </gl-form-input-group>
- </p>
+ <p>
+ <gl-form-input-group readonly :value="agentToken" :select-on-click="true">
+ <template #append>
+ <modal-copy-button
+ :text="agentToken"
+ :title="i18n.copyToken"
+ :modal-id="$options.modalId"
+ />
+ </template>
+ </gl-form-input-group>
+ </p>
- <p>
- <strong>{{ $options.i18n.basicInstallTitle }}</strong>
- </p>
+ <p>
+ <strong>{{ i18n.basicInstallTitle }}</strong>
+ </p>
- <p>
- {{ $options.i18n.basicInstallBody }}
- </p>
+ <p>
+ {{ i18n.basicInstallBody }}
+ </p>
- <p>
- <code-block :code="agentRegistrationCommand" />
- </p>
+ <p>
+ <code-block :code="agentRegistrationCommand" />
+ </p>
+
+ <p>
+ <strong>{{ i18n.advancedInstallTitle }}</strong>
+ </p>
+
+ <p>
+ <gl-sprintf :message="i18n.advancedInstallBody">
+ <template #link="{ content }">
+ <gl-link :href="$options.advancedInstallPath" target="_blank"> {{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ </template>
+ </template>
+
+ <template v-else>
+ <div class="gl-text-center gl-mb-5">
+ <img :alt="i18n.altText" :src="emptyStateImage" height="100" />
+ </div>
<p>
- <strong>{{ $options.i18n.advancedInstallTitle }}</strong>
+ <gl-sprintf :message="i18n.modalBody">
+ <template #link="{ content }">
+ <gl-link :href="$options.installAgentPath"> {{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
</p>
- <p>
- <gl-sprintf :message="$options.i18n.advancedInstallBody">
+ <p v-if="kasDisabled">
+ <gl-sprintf :message="i18n.enableKasText">
<template #link="{ content }">
- <gl-link :href="advancedInstallPath" target="_blank"> {{ content }}</gl-link>
+ <gl-link :href="$options.enableKasPath"> {{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
</template>
<template #modal-footer>
- <gl-button v-if="canCancel" @click="closeModal">{{ $options.i18n.cancel }} </gl-button>
-
- <gl-button v-if="registered" variant="confirm" category="primary" @click="closeModal"
- >{{ $options.i18n.close }}
+ <gl-button
+ v-if="registered"
+ variant="confirm"
+ category="primary"
+ :data-track-action="$options.EVENT_ACTIONS_CLICK"
+ :data-track-label="$options.EVENT_LABEL_MODAL"
+ data-track-property="close"
+ @click="closeModal"
+ >{{ i18n.close }}
</gl-button>
<gl-button
- v-else
+ v-else-if="isAgentRegistrationModal"
:disabled="!nextButtonDisabled"
variant="confirm"
category="primary"
+ :data-track-action="$options.EVENT_ACTIONS_CLICK"
+ :data-track-label="$options.EVENT_LABEL_MODAL"
+ data-track-property="register"
@click="registerAgent"
- >{{ $options.i18n.registerAgentButton }}
+ >{{ i18n.registerAgentButton }}
+ </gl-button>
+
+ <gl-button
+ v-if="canCancel"
+ :data-track-action="$options.EVENT_ACTIONS_CLICK"
+ :data-track-label="$options.EVENT_LABEL_MODAL"
+ data-track-property="cancel"
+ @click="closeModal"
+ >{{ i18n.cancel }}
+ </gl-button>
+
+ <gl-button
+ v-if="isEmptyStateModal"
+ :href="repositoryPath"
+ variant="confirm"
+ category="secondary"
+ data-testid="agent-secondary-button"
+ >{{ i18n.secondaryButton }}
+ </gl-button>
+
+ <gl-button
+ v-if="isEmptyStateModal"
+ variant="confirm"
+ category="primary"
+ :data-track-action="$options.EVENT_ACTIONS_CLICK"
+ :data-track-label="$options.EVENT_LABEL_MODAL"
+ data-track-property="done"
+ @click="closeModal"
+ >{{ i18n.done }}
</gl-button>
</template>
</gl-modal>