Commit 5652c056 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '357028-kubernetes-ui-updates' into 'master'

Kubernetes UI updates

See merge request gitlab-org/gitlab!84108
parents cbcfbee7 d1873459
<script> <script>
import { GlButton, GlEmptyState, GlLink, GlSprintf, GlModalDirective } from '@gitlab/ui'; import { GlEmptyState, GlLink, GlSprintf } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper'; import { helpPagePath } from '~/helpers/help_page_helper';
import { INSTALL_AGENT_MODAL_ID, I18N_AGENTS_EMPTY_STATE } from '../constants'; import { I18N_AGENTS_EMPTY_STATE } from '../constants';
export default { export default {
i18n: I18N_AGENTS_EMPTY_STATE, i18n: I18N_AGENTS_EMPTY_STATE,
modalId: INSTALL_AGENT_MODAL_ID,
agentDocsUrl: helpPagePath('user/clusters/agent/index'), agentDocsUrl: helpPagePath('user/clusters/agent/index'),
components: { components: {
GlButton,
GlEmptyState, GlEmptyState,
GlLink, GlLink,
GlSprintf, GlSprintf,
}, },
directives: {
GlModalDirective,
},
inject: ['emptyStateImage'], inject: ['emptyStateImage'],
props: {
isChildComponent: {
default: false,
required: false,
type: Boolean,
},
},
}; };
</script> </script>
<template> <template>
<gl-empty-state :svg-path="emptyStateImage" title="" class="agents-empty-state"> <gl-empty-state :svg-path="emptyStateImage" :svg-height="100">
<template #description> <template #title>
<p class="gl-text-left">
<gl-sprintf :message="$options.i18n.introText"> <gl-sprintf :message="$options.i18n.introText">
<template #link="{ content }"> <template #link="{ content }">
<gl-link :href="$options.agentDocsUrl"> <gl-link :href="$options.agentDocsUrl">
...@@ -38,18 +25,6 @@ export default { ...@@ -38,18 +25,6 @@ export default {
</gl-link> </gl-link>
</template> </template>
</gl-sprintf> </gl-sprintf>
</p>
</template>
<template #actions>
<gl-button
v-if="!isChildComponent"
v-gl-modal-directive="$options.modalId"
category="primary"
variant="confirm"
>
{{ $options.i18n.buttonText }}
</gl-button>
</template> </template>
</gl-empty-state> </gl-empty-state>
</template> </template>
...@@ -20,7 +20,7 @@ export default { ...@@ -20,7 +20,7 @@ export default {
'ClusterAgents|We would love to learn more about your experience with the GitLab Agent.', 'ClusterAgents|We would love to learn more about your experience with the GitLab Agent.',
), ),
feedbackBannerButton: s__('ClusterAgents|Give feedback'), feedbackBannerButton: s__('ClusterAgents|Give feedback'),
error: s__('ClusterAgents|An error occurred while loading your Agents'), error: s__('ClusterAgents|An error occurred while loading your agents'),
}, },
AGENT_FEEDBACK_ISSUE, AGENT_FEEDBACK_ISSUE,
AGENT_FEEDBACK_KEY, AGENT_FEEDBACK_KEY,
...@@ -208,7 +208,7 @@ export default { ...@@ -208,7 +208,7 @@ export default {
</div> </div>
</div> </div>
<agent-empty-state v-else :is-child-component="isChildComponent" /> <agent-empty-state v-else />
</section> </section>
<gl-alert v-else variant="danger" :dismissible="false"> <gl-alert v-else variant="danger" :dismissible="false">
......
...@@ -57,6 +57,7 @@ export default { ...@@ -57,6 +57,7 @@ export default {
<gl-dropdown <gl-dropdown
ref="dropdown" ref="dropdown"
v-gl-modal-directive="shouldTriggerModal && $options.INSTALL_AGENT_MODAL_ID" v-gl-modal-directive="shouldTriggerModal && $options.INSTALL_AGENT_MODAL_ID"
data-qa-selector="clusters_actions_button"
category="primary" category="primary"
variant="confirm" variant="confirm"
:text="defaultActionText" :text="defaultActionText"
......
<script> <script>
import { GlEmptyState, GlButton, GlLink, GlSprintf, GlAlert } from '@gitlab/ui'; import { GlEmptyState, GlLink, GlSprintf, GlAlert } from '@gitlab/ui';
import { mapState } from 'vuex';
import { helpPagePath } from '~/helpers/help_page_helper'; import { helpPagePath } from '~/helpers/help_page_helper';
import { I18N_CLUSTERS_EMPTY_STATE } from '../constants'; import { I18N_CLUSTERS_EMPTY_STATE } from '../constants';
...@@ -8,35 +7,24 @@ export default { ...@@ -8,35 +7,24 @@ export default {
i18n: I18N_CLUSTERS_EMPTY_STATE, i18n: I18N_CLUSTERS_EMPTY_STATE,
components: { components: {
GlEmptyState, GlEmptyState,
GlButton,
GlLink, GlLink,
GlSprintf, GlSprintf,
GlAlert, GlAlert,
}, },
inject: ['emptyStateHelpText', 'clustersEmptyStateImage', 'addClusterPath'], inject: ['emptyStateHelpText', 'clustersEmptyStateImage'],
props: {
isChildComponent: {
default: false,
required: false,
type: Boolean,
},
},
clustersHelpUrl: helpPagePath('user/infrastructure/clusters/index', { clustersHelpUrl: helpPagePath('user/infrastructure/clusters/index', {
anchor: 'certificate-based-kubernetes-integration-deprecated', anchor: 'certificate-based-kubernetes-integration-deprecated',
}), }),
blogPostUrl: blogPostUrl:
'https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/', 'https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/',
computed: {
...mapState(['canAddCluster']),
},
}; };
</script> </script>
<template> <template>
<div> <div>
<gl-empty-state :svg-path="clustersEmptyStateImage" title=""> <gl-empty-state :svg-path="clustersEmptyStateImage" :svg-height="100">
<template #description> <template #title>
<p class="gl-text-left"> <p>
<gl-sprintf :message="$options.i18n.introText"> <gl-sprintf :message="$options.i18n.introText">
<template #link="{ content }"> <template #link="{ content }">
<gl-link :href="$options.clustersHelpUrl">{{ content }}</gl-link> <gl-link :href="$options.clustersHelpUrl">{{ content }}</gl-link>
...@@ -48,28 +36,12 @@ export default { ...@@ -48,28 +36,12 @@ export default {
{{ emptyStateHelpText }} {{ emptyStateHelpText }}
</p> </p>
</template> </template>
<template #actions>
<gl-button
v-if="!isChildComponent"
data-testid="integration-primary-button"
data-qa-selector="add_kubernetes_cluster_link"
category="primary"
variant="confirm"
:disabled="!canAddCluster"
:href="addClusterPath"
>
{{ $options.i18n.buttonText }}
</gl-button>
</template>
</gl-empty-state> </gl-empty-state>
<gl-alert variant="warning" :dismissible="false"> <gl-alert variant="warning" :dismissible="false">
<gl-sprintf :message="$options.i18n.alertText"> <gl-sprintf :message="$options.i18n.alertText">
<template #link="{ content }"> <template #link="{ content }">
<gl-link :href="$options.blogPostUrl" target="_blank"> <gl-link :href="$options.blogPostUrl" target="_blank">{{ content }}</gl-link>
{{ content }}
</gl-link>
</template> </template>
</gl-sprintf> </gl-sprintf>
</gl-alert> </gl-alert>
......
<script> <script>
import { import { GlCard, GlSprintf, GlPopover, GlLink, GlBadge, GlLoadingIcon } from '@gitlab/ui';
GlCard,
GlSprintf,
GlPopover,
GlLink,
GlButton,
GlBadge,
GlLoadingIcon,
GlModalDirective,
GlTooltipDirective,
} from '@gitlab/ui';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
import { import { AGENT_CARD_INFO, CERTIFICATE_BASED_CARD_INFO, MAX_CLUSTERS_LIST } from '../constants';
AGENT_CARD_INFO,
CERTIFICATE_BASED_CARD_INFO,
MAX_CLUSTERS_LIST,
INSTALL_AGENT_MODAL_ID,
} from '../constants';
import Clusters from './clusters.vue'; import Clusters from './clusters.vue';
import Agents from './agents.vue'; import Agents from './agents.vue';
...@@ -26,23 +11,16 @@ export default { ...@@ -26,23 +11,16 @@ export default {
GlSprintf, GlSprintf,
GlPopover, GlPopover,
GlLink, GlLink,
GlButton,
GlBadge, GlBadge,
GlLoadingIcon, GlLoadingIcon,
Clusters, Clusters,
Agents, Agents,
}, },
directives: {
GlModalDirective,
GlTooltip: GlTooltipDirective,
},
MAX_CLUSTERS_LIST, MAX_CLUSTERS_LIST,
INSTALL_AGENT_MODAL_ID,
i18n: { i18n: {
agent: AGENT_CARD_INFO, agent: AGENT_CARD_INFO,
certificate: CERTIFICATE_BASED_CARD_INFO, certificate: CERTIFICATE_BASED_CARD_INFO,
}, },
inject: ['addClusterPath', 'canAddCluster'],
props: { props: {
defaultBranchName: { defaultBranchName: {
default: '.noBranch', default: '.noBranch',
...@@ -93,14 +71,6 @@ export default { ...@@ -93,14 +71,6 @@ export default {
return cardTitle; return cardTitle;
}, },
installAgentTooltip() {
return this.canAddCluster ? '' : this.$options.i18n.agent.installAgentDisabledHint;
},
connectExistingClusterTooltip() {
return this.canAddCluster
? ''
: this.$options.i18n.certificate.connectExistingClusterDisabledHint;
},
}, },
methods: { methods: {
cardFooterNumber(number) { cardFooterNumber(number) {
...@@ -177,21 +147,6 @@ export default { ...@@ -177,21 +147,6 @@ export default {
><template #number>{{ cardFooterNumber(totalAgents) }}</template></gl-sprintf ><template #number>{{ cardFooterNumber(totalAgents) }}</template></gl-sprintf
></gl-link ></gl-link
> >
<div
v-gl-tooltip="installAgentTooltip"
class="gl-display-inline-block"
tabindex="-1"
data-testid="install-agent-button-tooltip"
>
<gl-button
v-gl-modal-directive="$options.INSTALL_AGENT_MODAL_ID"
class="gl-ml-4"
category="secondary"
variant="confirm"
:disabled="!canAddCluster"
>{{ $options.i18n.agent.actionText }}</gl-button
>
</div>
</template> </template>
</gl-card> </gl-card>
...@@ -214,7 +169,7 @@ export default { ...@@ -214,7 +169,7 @@ export default {
<gl-badge variant="warning">{{ $options.i18n.certificate.badgeText }}</gl-badge> <gl-badge variant="warning">{{ $options.i18n.certificate.badgeText }}</gl-badge>
</template> </template>
<clusters :limit="$options.MAX_CLUSTERS_LIST" :is-child-component="true" /> <clusters :limit="$options.MAX_CLUSTERS_LIST" />
<template #footer> <template #footer>
<gl-link <gl-link
...@@ -226,22 +181,6 @@ export default { ...@@ -226,22 +181,6 @@ export default {
><template #number>{{ cardFooterNumber(totalClusters) }}</template></gl-sprintf ><template #number>{{ cardFooterNumber(totalClusters) }}</template></gl-sprintf
></gl-link ></gl-link
> >
<div
v-gl-tooltip="connectExistingClusterTooltip"
class="gl-display-inline-block"
tabindex="-1"
data-testid="connect-existing-cluster-button-tooltip"
>
<gl-button
category="secondary"
data-qa-selector="connect_existing_cluster_button"
variant="confirm"
class="gl-ml-4"
:href="addClusterPath"
:disabled="!canAddCluster"
>{{ $options.i18n.certificate.actionText }}</gl-button
>
</div>
</template> </template>
</gl-card> </gl-card>
</div> </div>
......
...@@ -119,7 +119,7 @@ export const I18N_AGENT_MODAL = { ...@@ -119,7 +119,7 @@ export const I18N_AGENT_MODAL = {
enableKasText: s__( enableKasText: s__(
"ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it.", "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it.",
), ),
altText: s__('ClusterAgents|GitLab Agent for Kubernetes'), altText: s__('ClusterAgents|GitLab agent for Kubernetes'),
learnMoreLink: s__('ClusterAgents|How do I register an agent?'), learnMoreLink: s__('ClusterAgents|How do I register an agent?'),
registrationErrorTitle: s__('ClusterAgents|Failed to register an agent'), registrationErrorTitle: s__('ClusterAgents|Failed to register an agent'),
unknownError: s__('ClusterAgents|An unknown error occurred. Please try again.'), unknownError: s__('ClusterAgents|An unknown error occurred. Please try again.'),
...@@ -169,16 +169,14 @@ export const AGENT_STATUSES = { ...@@ -169,16 +169,14 @@ export const AGENT_STATUSES = {
export const I18N_AGENTS_EMPTY_STATE = { export const I18N_AGENTS_EMPTY_STATE = {
introText: s__( introText: s__(
'ClusterIntegration|Use the %{linkStart}GitLab Agent%{linkEnd} to safely connect your Kubernetes clusters to GitLab. You can deploy your applications, run your pipelines, use Review Apps, and much more.', 'ClusterIntegration|Use the %{linkStart}GitLab agent%{linkEnd} to safely connect your Kubernetes clusters to GitLab. You can deploy your applications, run your pipelines, use Review Apps, and much more.',
), ),
buttonText: s__('ClusterAgents|Connect with the GitLab Agent'),
}; };
export const I18N_CLUSTERS_EMPTY_STATE = { export const I18N_CLUSTERS_EMPTY_STATE = {
introText: s__( introText: s__(
'ClusterIntegration|Connect your cluster to GitLab through %{linkStart}cluster certificates%{linkEnd}.', 'ClusterIntegration|Connect your cluster to GitLab through %{linkStart}cluster certificates%{linkEnd}.',
), ),
buttonText: s__('ClusterIntegration|Connect with a certificate'),
alertText: s__( alertText: s__(
'ClusterIntegration|The certificate-based method to connect clusters to GitLab was %{linkStart}deprecated%{linkEnd} in GitLab 14.5.', 'ClusterIntegration|The certificate-based method to connect clusters to GitLab was %{linkStart}deprecated%{linkEnd} in GitLab 14.5.',
), ),
...@@ -190,19 +188,15 @@ export const AGENT_CARD_INFO = { ...@@ -190,19 +188,15 @@ export const AGENT_CARD_INFO = {
emptyTitle: s__('ClusterAgents|No agents'), emptyTitle: s__('ClusterAgents|No agents'),
tooltip: { tooltip: {
label: s__('ClusterAgents|Recommended'), label: s__('ClusterAgents|Recommended'),
title: s__('ClusterAgents|GitLab Agent'), title: s__('ClusterAgents|GitLab agent'),
text: sprintf( text: sprintf(
s__( s__(
'ClusterAgents|The GitLab Agent provides an increased level of security when connecting Kubernetes clusters to GitLab. %{linkStart}Learn more about the GitLab Agent.%{linkEnd}', 'ClusterAgents|The GitLab agent provides an increased level of security when connecting Kubernetes clusters to GitLab. %{linkStart}Learn more about the GitLab agent.%{linkEnd}',
), ),
), ),
link: helpPagePath('user/clusters/agent/index'), link: helpPagePath('user/clusters/agent/index'),
}, },
actionText: s__('ClusterAgents|Install a new agent'),
footerText: sprintf(s__('ClusterAgents|View all %{number} agents')), footerText: sprintf(s__('ClusterAgents|View all %{number} agents')),
installAgentDisabledHint: s__(
'ClusterAgents|Requires a Maintainer or greater role to install new agents',
),
}; };
export const CERTIFICATE_BASED_CARD_INFO = { export const CERTIFICATE_BASED_CARD_INFO = {
...@@ -211,12 +205,8 @@ export const CERTIFICATE_BASED_CARD_INFO = { ...@@ -211,12 +205,8 @@ export const CERTIFICATE_BASED_CARD_INFO = {
s__('ClusterAgents|%{number} of %{total} clusters connected through cluster certificates'), s__('ClusterAgents|%{number} of %{total} clusters connected through cluster certificates'),
), ),
emptyTitle: s__('ClusterAgents|No clusters connected through cluster certificates'), emptyTitle: s__('ClusterAgents|No clusters connected through cluster certificates'),
actionText: s__('ClusterAgents|Connect existing cluster'),
footerText: sprintf(s__('ClusterAgents|View all %{number} clusters')), footerText: sprintf(s__('ClusterAgents|View all %{number} clusters')),
badgeText: s__('ClusterAgents|Deprecated'), badgeText: s__('ClusterAgents|Deprecated'),
connectExistingClusterDisabledHint: s__(
'ClusterAgents|Requires a maintainer or greater role to connect existing clusters',
),
}; };
export const MAX_CLUSTERS_LIST = 6; export const MAX_CLUSTERS_LIST = 6;
......
.clusters-container { .clusters-container {
.empty-state .svg-content {
@include gl-pb-0;
img {
width: 100px;
}
}
@include media-breakpoint-down(xs) { @include media-breakpoint-down(xs) {
.nav-controls { .nav-controls {
@include gl-w-full; @include gl-w-full;
......
...@@ -7882,10 +7882,10 @@ msgstr "" ...@@ -7882,10 +7882,10 @@ msgstr ""
msgid "ClusterAgents|All" msgid "ClusterAgents|All"
msgstr "" msgstr ""
msgid "ClusterAgents|An error occurred while loading your Agents" msgid "ClusterAgents|An error occurred while loading your agent"
msgstr "" msgstr ""
msgid "ClusterAgents|An error occurred while loading your agent" msgid "ClusterAgents|An error occurred while loading your agents"
msgstr "" msgstr ""
msgid "ClusterAgents|An error occurred while retrieving GitLab Agent activity. Reload the page to try again." msgid "ClusterAgents|An error occurred while retrieving GitLab Agent activity. Reload the page to try again."
...@@ -7918,12 +7918,6 @@ msgstr "" ...@@ -7918,12 +7918,6 @@ msgstr ""
msgid "ClusterAgents|Connect a cluster (deprecated)" msgid "ClusterAgents|Connect a cluster (deprecated)"
msgstr "" msgstr ""
msgid "ClusterAgents|Connect existing cluster"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
msgid "ClusterAgents|Connected" msgid "ClusterAgents|Connected"
msgstr "" msgstr ""
...@@ -7990,10 +7984,10 @@ msgstr "" ...@@ -7990,10 +7984,10 @@ msgstr ""
msgid "ClusterAgents|From a terminal, connect to your cluster and run this command. The token is included." msgid "ClusterAgents|From a terminal, connect to your cluster and run this command. The token is included."
msgstr "" msgstr ""
msgid "ClusterAgents|GitLab Agent" msgid "ClusterAgents|GitLab agent"
msgstr "" msgstr ""
msgid "ClusterAgents|GitLab Agent for Kubernetes" msgid "ClusterAgents|GitLab agent for Kubernetes"
msgstr "" msgstr ""
msgid "ClusterAgents|Give feedback" msgid "ClusterAgents|Give feedback"
...@@ -8005,9 +7999,6 @@ msgstr "" ...@@ -8005,9 +7999,6 @@ msgstr ""
msgid "ClusterAgents|How to update an agent?" msgid "ClusterAgents|How to update an agent?"
msgstr "" msgstr ""
msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}." msgid "ClusterAgents|Last connected %{timeAgo}."
msgstr "" msgstr ""
...@@ -8053,15 +8044,9 @@ msgstr "" ...@@ -8053,15 +8044,9 @@ msgstr ""
msgid "ClusterAgents|Requires a Maintainer or greater role to delete agents" msgid "ClusterAgents|Requires a Maintainer or greater role to delete agents"
msgstr "" msgstr ""
msgid "ClusterAgents|Requires a Maintainer or greater role to install new agents"
msgstr ""
msgid "ClusterAgents|Requires a Maintainer or greater role to perform these actions" msgid "ClusterAgents|Requires a Maintainer or greater role to perform these actions"
msgstr "" msgstr ""
msgid "ClusterAgents|Requires a maintainer or greater role to connect existing clusters"
msgstr ""
msgid "ClusterAgents|Security" msgid "ClusterAgents|Security"
msgstr "" msgstr ""
...@@ -8074,7 +8059,7 @@ msgstr "" ...@@ -8074,7 +8059,7 @@ msgstr ""
msgid "ClusterAgents|Tell us what you think" msgid "ClusterAgents|Tell us what you think"
msgstr "" msgstr ""
msgid "ClusterAgents|The GitLab Agent provides an increased level of security when connecting Kubernetes clusters to GitLab. %{linkStart}Learn more about the GitLab Agent.%{linkEnd}" msgid "ClusterAgents|The GitLab agent provides an increased level of security when connecting Kubernetes clusters to GitLab. %{linkStart}Learn more about the GitLab agent.%{linkEnd}"
msgstr "" msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}." msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
...@@ -8274,9 +8259,6 @@ msgstr "" ...@@ -8274,9 +8259,6 @@ msgstr ""
msgid "ClusterIntegration|Connect a Kubernetes cluster" msgid "ClusterIntegration|Connect a Kubernetes cluster"
msgstr "" msgstr ""
msgid "ClusterIntegration|Connect with a certificate"
msgstr ""
msgid "ClusterIntegration|Connect your cluster to GitLab through %{linkStart}cluster certificates%{linkEnd}." msgid "ClusterIntegration|Connect your cluster to GitLab through %{linkStart}cluster certificates%{linkEnd}."
msgstr "" msgstr ""
...@@ -8826,7 +8808,7 @@ msgstr "" ...@@ -8826,7 +8808,7 @@ msgstr ""
msgid "ClusterIntegration|Use GitLab to deploy to your cluster, run jobs, use review apps, and more." msgid "ClusterIntegration|Use GitLab to deploy to your cluster, run jobs, use review apps, and more."
msgstr "" msgstr ""
msgid "ClusterIntegration|Use the %{linkStart}GitLab Agent%{linkEnd} to safely connect your Kubernetes clusters to GitLab. You can deploy your applications, run your pipelines, use Review Apps, and much more." msgid "ClusterIntegration|Use the %{linkStart}GitLab agent%{linkEnd} to safely connect your Kubernetes clusters to GitLab. You can deploy your applications, run your pipelines, use Review Apps, and much more."
msgstr "" msgstr ""
msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster." msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
......
...@@ -6,12 +6,13 @@ module QA ...@@ -6,12 +6,13 @@ module QA
module Infrastructure module Infrastructure
module Kubernetes module Kubernetes
class Index < Page::Base class Index < Page::Base
view 'app/assets/javascripts/clusters_list/components/clusters_view_all.vue' do view 'app/assets/javascripts/clusters_list/components/clusters_actions.vue' do
element :connect_existing_cluster_button element :clusters_actions_button
end end
def connect_existing_cluster def connect_existing_cluster
click_link 'Connect existing cluster' within_element(:clusters_actions_button) { click_button(class: 'dropdown-toggle-split') }
click_link 'Connect a cluster (certificate - deprecated)'
end end
def has_cluster?(cluster) def has_cluster?(cluster)
......
...@@ -25,7 +25,7 @@ RSpec.describe 'User Cluster', :js do ...@@ -25,7 +25,7 @@ RSpec.describe 'User Cluster', :js do
before do before do
visit group_clusters_path(group) visit group_clusters_path(group)
click_link 'Connect with a certificate' click_link 'Connect a cluster (deprecated)'
end end
context 'when user filled form with valid parameters' do context 'when user filled form with valid parameters' do
...@@ -119,7 +119,6 @@ RSpec.describe 'User Cluster', :js do ...@@ -119,7 +119,6 @@ RSpec.describe 'User Cluster', :js do
it 'user sees creation form with the successful message' do it 'user sees creation form with the successful message' do
expect(page).to have_content('Kubernetes cluster integration was successfully removed.') expect(page).to have_content('Kubernetes cluster integration was successfully removed.')
expect(page).to have_link('Connect with a certificate')
end end
end end
end end
......
...@@ -27,7 +27,6 @@ RSpec.describe 'ClusterAgents', :js do ...@@ -27,7 +27,6 @@ RSpec.describe 'ClusterAgents', :js do
end end
it 'displays empty state', :aggregate_failures do it 'displays empty state', :aggregate_failures do
expect(page).to have_content('Install a new agent')
expect(page).to have_selector('.empty-state') expect(page).to have_selector('.empty-state')
end end
end end
......
...@@ -154,7 +154,6 @@ RSpec.describe 'Gcp Cluster', :js do ...@@ -154,7 +154,6 @@ RSpec.describe 'Gcp Cluster', :js do
it 'user sees creation form with the successful message' do it 'user sees creation form with the successful message' do
expect(page).to have_content('Kubernetes cluster integration was successfully removed.') expect(page).to have_content('Kubernetes cluster integration was successfully removed.')
expect(page).to have_link('Connect with a certificate')
end end
end end
end end
......
...@@ -25,8 +25,8 @@ RSpec.describe 'User Cluster', :js do ...@@ -25,8 +25,8 @@ RSpec.describe 'User Cluster', :js do
before do before do
visit project_clusters_path(project) visit project_clusters_path(project)
click_link 'Certificate' click_button(class: 'dropdown-toggle-split')
click_link 'Connect with a certificate' click_link 'Connect a cluster (certificate - deprecated)'
end end
context 'when user filled form with valid parameters' do context 'when user filled form with valid parameters' do
...@@ -108,7 +108,6 @@ RSpec.describe 'User Cluster', :js do ...@@ -108,7 +108,6 @@ RSpec.describe 'User Cluster', :js do
it 'user sees creation form with the successful message' do it 'user sees creation form with the successful message' do
expect(page).to have_content('Kubernetes cluster integration was successfully removed.') expect(page).to have_content('Kubernetes cluster integration was successfully removed.')
expect(page).to have_link('Connect with a certificate')
end end
end end
end end
......
...@@ -20,7 +20,6 @@ RSpec.describe 'Clusters', :js do ...@@ -20,7 +20,6 @@ RSpec.describe 'Clusters', :js do
end end
it 'sees empty state' do it 'sees empty state' do
expect(page).to have_link('Connect with a certificate')
expect(page).to have_selector('.empty-state') expect(page).to have_selector('.empty-state')
end end
end end
......
import { GlEmptyState, GlSprintf, GlLink, GlButton } from '@gitlab/ui'; import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
import AgentEmptyState from '~/clusters_list/components/agent_empty_state.vue'; import AgentEmptyState from '~/clusters_list/components/agent_empty_state.vue';
import { INSTALL_AGENT_MODAL_ID } from '~/clusters_list/constants';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { helpPagePath } from '~/helpers/help_page_helper'; import { helpPagePath } from '~/helpers/help_page_helper';
const emptyStateImage = '/path/to/image'; const emptyStateImage = '/path/to/image';
...@@ -15,16 +13,12 @@ describe('AgentEmptyStateComponent', () => { ...@@ -15,16 +13,12 @@ describe('AgentEmptyStateComponent', () => {
}; };
const findInstallDocsLink = () => wrapper.findComponent(GlLink); const findInstallDocsLink = () => wrapper.findComponent(GlLink);
const findIntegrationButton = () => wrapper.findComponent(GlButton);
const findEmptyState = () => wrapper.findComponent(GlEmptyState); const findEmptyState = () => wrapper.findComponent(GlEmptyState);
beforeEach(() => { beforeEach(() => {
wrapper = shallowMountExtended(AgentEmptyState, { wrapper = shallowMountExtended(AgentEmptyState, {
provide: provideData, provide: provideData,
directives: { stubs: { GlSprintf },
GlModalDirective: createMockDirective(),
},
stubs: { GlEmptyState, GlSprintf },
}); });
}); });
...@@ -38,17 +32,7 @@ describe('AgentEmptyStateComponent', () => { ...@@ -38,17 +32,7 @@ describe('AgentEmptyStateComponent', () => {
expect(findEmptyState().exists()).toBe(true); expect(findEmptyState().exists()).toBe(true);
}); });
it('renders button for the agent registration', () => {
expect(findIntegrationButton().exists()).toBe(true);
});
it('renders correct href attributes for the docs link', () => { it('renders correct href attributes for the docs link', () => {
expect(findInstallDocsLink().attributes('href')).toBe(installDocsUrl); expect(findInstallDocsLink().attributes('href')).toBe(installDocsUrl);
}); });
it('renders correct modal id for the agent registration modal', () => {
const binding = getBinding(findIntegrationButton().element, 'gl-modal-directive');
expect(binding.value).toBe(INSTALL_AGENT_MODAL_ID);
});
}); });
...@@ -308,7 +308,7 @@ describe('Agents', () => { ...@@ -308,7 +308,7 @@ describe('Agents', () => {
}); });
it('displays an alert message', () => { it('displays an alert message', () => {
expect(findAlert().text()).toBe('An error occurred while loading your Agents'); expect(findAlert().text()).toBe('An error occurred while loading your agents');
}); });
}); });
......
import { GlEmptyState, GlButton } from '@gitlab/ui'; import { GlEmptyState } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ClustersEmptyState from '~/clusters_list/components/clusters_empty_state.vue'; import ClustersEmptyState from '~/clusters_list/components/clusters_empty_state.vue';
import ClusterStore from '~/clusters_list/store';
const clustersEmptyStateImage = 'path/to/svg'; const clustersEmptyStateImage = 'path/to/svg';
const addClusterPath = '/path/to/connect/cluster';
const emptyStateHelpText = 'empty state text'; const emptyStateHelpText = 'empty state text';
describe('ClustersEmptyStateComponent', () => { describe('ClustersEmptyStateComponent', () => {
...@@ -12,52 +10,28 @@ describe('ClustersEmptyStateComponent', () => { ...@@ -12,52 +10,28 @@ describe('ClustersEmptyStateComponent', () => {
const defaultProvideData = { const defaultProvideData = {
clustersEmptyStateImage, clustersEmptyStateImage,
addClusterPath,
}; };
const findButton = () => wrapper.findComponent(GlButton);
const findEmptyStateText = () => wrapper.findByTestId('clusters-empty-state-text'); const findEmptyStateText = () => wrapper.findByTestId('clusters-empty-state-text');
const createWrapper = ({ const createWrapper = ({ provideData = { emptyStateHelpText: null } } = {}) => {
provideData = { emptyStateHelpText: null },
isChildComponent = false,
canAddCluster = true,
} = {}) => {
wrapper = shallowMountExtended(ClustersEmptyState, { wrapper = shallowMountExtended(ClustersEmptyState, {
store: ClusterStore({ canAddCluster }),
propsData: { isChildComponent },
provide: { ...defaultProvideData, ...provideData }, provide: { ...defaultProvideData, ...provideData },
stubs: { GlEmptyState }, stubs: { GlEmptyState },
}); });
}; };
beforeEach(() => {
createWrapper();
});
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
}); });
describe('when the component is loaded independently', () => {
it('should render the action button', () => {
expect(findButton().exists()).toBe(true);
});
});
describe('when the help text is not provided', () => { describe('when the help text is not provided', () => {
it('should not render the empty state text', () => {
expect(findEmptyStateText().exists()).toBe(false);
});
});
describe('when the component is loaded as a child component', () => {
beforeEach(() => { beforeEach(() => {
createWrapper({ isChildComponent: true }); createWrapper();
}); });
it('should not render the action button', () => { it('should not render the empty state text', () => {
expect(findButton().exists()).toBe(false); expect(findEmptyStateText().exists()).toBe(false);
}); });
}); });
...@@ -70,13 +44,4 @@ describe('ClustersEmptyStateComponent', () => { ...@@ -70,13 +44,4 @@ describe('ClustersEmptyStateComponent', () => {
expect(findEmptyStateText().text()).toBe(emptyStateHelpText); expect(findEmptyStateText().text()).toBe(emptyStateHelpText);
}); });
}); });
describe('when the user cannot add clusters', () => {
beforeEach(() => {
createWrapper({ canAddCluster: false });
});
it('should disable the button', () => {
expect(findButton().props('disabled')).toBe(true);
});
});
}); });
import { GlCard, GlLoadingIcon, GlButton, GlSprintf, GlBadge } from '@gitlab/ui'; import { GlCard, GlLoadingIcon, GlSprintf, GlBadge } from '@gitlab/ui';
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ClustersViewAll from '~/clusters_list/components/clusters_view_all.vue'; import ClustersViewAll from '~/clusters_list/components/clusters_view_all.vue';
import Agents from '~/clusters_list/components/agents.vue'; import Agents from '~/clusters_list/components/agents.vue';
import Clusters from '~/clusters_list/components/clusters.vue'; import Clusters from '~/clusters_list/components/clusters.vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { import {
AGENT, AGENT,
CERTIFICATE_BASED, CERTIFICATE_BASED,
AGENT_CARD_INFO, AGENT_CARD_INFO,
CERTIFICATE_BASED_CARD_INFO, CERTIFICATE_BASED_CARD_INFO,
MAX_CLUSTERS_LIST, MAX_CLUSTERS_LIST,
INSTALL_AGENT_MODAL_ID,
} from '~/clusters_list/constants'; } from '~/clusters_list/constants';
import { sprintf } from '~/locale'; import { sprintf } from '~/locale';
Vue.use(Vuex); Vue.use(Vuex);
const addClusterPath = '/path/to/add/cluster';
const defaultBranchName = 'default-branch'; const defaultBranchName = 'default-branch';
describe('ClustersViewAllComponent', () => { describe('ClustersViewAllComponent', () => {
...@@ -32,11 +29,6 @@ describe('ClustersViewAllComponent', () => { ...@@ -32,11 +29,6 @@ describe('ClustersViewAllComponent', () => {
defaultBranchName, defaultBranchName,
}; };
const defaultProvide = {
addClusterPath,
canAddCluster: true,
};
const entryData = { const entryData = {
loadingClusters: false, loadingClusters: false,
totalClusters: 0, totalClusters: 0,
...@@ -46,37 +38,20 @@ describe('ClustersViewAllComponent', () => { ...@@ -46,37 +38,20 @@ describe('ClustersViewAllComponent', () => {
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon); const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findAgentsComponent = () => wrapper.findComponent(Agents); const findAgentsComponent = () => wrapper.findComponent(Agents);
const findClustersComponent = () => wrapper.findComponent(Clusters); const findClustersComponent = () => wrapper.findComponent(Clusters);
const findInstallAgentButtonTooltip = () => wrapper.findByTestId('install-agent-button-tooltip');
const findConnectExistingClusterButtonTooltip = () =>
wrapper.findByTestId('connect-existing-cluster-button-tooltip');
const findCardsContainer = () => wrapper.findByTestId('clusters-cards-container'); const findCardsContainer = () => wrapper.findByTestId('clusters-cards-container');
const findAgentCardTitle = () => wrapper.findByTestId('agent-card-title'); const findAgentCardTitle = () => wrapper.findByTestId('agent-card-title');
const findRecommendedBadge = () => wrapper.findComponent(GlBadge); const findRecommendedBadge = () => wrapper.findComponent(GlBadge);
const findClustersCardTitle = () => wrapper.findByTestId('clusters-card-title'); const findClustersCardTitle = () => wrapper.findByTestId('clusters-card-title');
const findFooterButton = (line) => findCards().at(line).findComponent(GlButton);
const getTooltipText = (el) => {
const binding = getBinding(el, 'gl-tooltip');
return binding.value;
};
const createStore = (initialState) => const createStore = (initialState) =>
new Vuex.Store({ new Vuex.Store({
state: initialState, state: initialState,
}); });
const createWrapper = ({ initialState = entryData, provideData } = {}) => { const createWrapper = ({ initialState = entryData } = {}) => {
wrapper = shallowMountExtended(ClustersViewAll, { wrapper = shallowMountExtended(ClustersViewAll, {
store: createStore(initialState), store: createStore(initialState),
propsData, propsData,
provide: {
...defaultProvide,
...provideData,
},
directives: {
GlModalDirective: createMockDirective(),
GlTooltip: createMockDirective(),
},
stubs: { GlCard, GlSprintf }, stubs: { GlCard, GlSprintf },
}); });
}; };
...@@ -138,25 +113,10 @@ describe('ClustersViewAllComponent', () => { ...@@ -138,25 +113,10 @@ describe('ClustersViewAllComponent', () => {
expect(findAgentsComponent().props('defaultBranchName')).toBe(defaultBranchName); expect(findAgentsComponent().props('defaultBranchName')).toBe(defaultBranchName);
}); });
it('should show install new Agent button in the footer', () => {
expect(findFooterButton(0).exists()).toBe(true);
expect(findFooterButton(0).props('disabled')).toBe(false);
});
it('does not show tooltip for install new Agent button', () => {
expect(getTooltipText(findInstallAgentButtonTooltip().element)).toBe('');
});
describe('when there are no agents', () => { describe('when there are no agents', () => {
it('should show the empty title', () => { it('should show the empty title', () => {
expect(findAgentCardTitle().text()).toBe(AGENT_CARD_INFO.emptyTitle); expect(findAgentCardTitle().text()).toBe(AGENT_CARD_INFO.emptyTitle);
}); });
it('should render correct modal id for the agent link', () => {
const binding = getBinding(findFooterButton(0).element, 'gl-modal-directive');
expect(binding.value).toBe(INSTALL_AGENT_MODAL_ID);
});
}); });
describe('when the agents are present', () => { describe('when the agents are present', () => {
...@@ -191,22 +151,6 @@ describe('ClustersViewAllComponent', () => { ...@@ -191,22 +151,6 @@ describe('ClustersViewAllComponent', () => {
}); });
}); });
}); });
describe('when the user cannot add clusters', () => {
beforeEach(() => {
createWrapper({ provideData: { canAddCluster: false } });
});
it('should disable the button', () => {
expect(findFooterButton(0).props('disabled')).toBe(true);
});
it('should show a tooltip explaining why the button is disabled', () => {
expect(getTooltipText(findInstallAgentButtonTooltip().element)).toBe(
AGENT_CARD_INFO.installAgentDisabledHint,
);
});
});
}); });
describe('clusters tab', () => { describe('clusters tab', () => {
...@@ -214,43 +158,10 @@ describe('ClustersViewAllComponent', () => { ...@@ -214,43 +158,10 @@ describe('ClustersViewAllComponent', () => {
expect(findClustersComponent().props('limit')).toBe(MAX_CLUSTERS_LIST); expect(findClustersComponent().props('limit')).toBe(MAX_CLUSTERS_LIST);
}); });
it('should pass the is-child-component prop', () => {
expect(findClustersComponent().props('isChildComponent')).toBe(true);
});
describe('when there are no clusters', () => { describe('when there are no clusters', () => {
it('should show the empty title', () => { it('should show the empty title', () => {
expect(findClustersCardTitle().text()).toBe(CERTIFICATE_BASED_CARD_INFO.emptyTitle); expect(findClustersCardTitle().text()).toBe(CERTIFICATE_BASED_CARD_INFO.emptyTitle);
}); });
it('should show install new cluster button in the footer', () => {
expect(findFooterButton(1).exists()).toBe(true);
expect(findFooterButton(1).props('disabled')).toBe(false);
});
it('should render correct href for the button in the footer', () => {
expect(findFooterButton(1).attributes('href')).toBe(addClusterPath);
});
it('does not show tooltip for install new cluster button', () => {
expect(getTooltipText(findConnectExistingClusterButtonTooltip().element)).toBe('');
});
});
describe('when the user cannot add clusters', () => {
beforeEach(() => {
createWrapper({ provideData: { canAddCluster: false } });
});
it('should disable the button', () => {
expect(findFooterButton(1).props('disabled')).toBe(true);
});
it('should show a tooltip explaining why the button is disabled', () => {
expect(getTooltipText(findConnectExistingClusterButtonTooltip().element)).toBe(
CERTIFICATE_BASED_CARD_INFO.connectExistingClusterDisabledHint,
);
});
}); });
describe('when the clusters are present', () => { describe('when the clusters are present', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment