Commit 27bb0bed authored by Mike Greiling's avatar Mike Greiling

Merge branch 'gitlab-integration-form-toggle' into 'master'

Gitlab integration form toggle

Closes #219612

See merge request gitlab-org/gitlab!35453
parents b6d32b0c 73d4dc46
......@@ -20,7 +20,6 @@ import ClustersService from './services/clusters_service';
import ClustersStore from './stores/clusters_store';
import Applications from './components/applications.vue';
import RemoveClusterConfirmation from './components/remove_cluster_confirmation.vue';
import setupToggleButtons from '../toggle_buttons';
import initProjectSelectDropdown from '~/project_select';
import initServerlessSurveyBanner from '~/serverless/survey_banner';
......@@ -128,10 +127,6 @@ export default class Clusters {
Clusters.initDismissableCallout();
initSettingsPanels();
const toggleButtonsContainer = document.querySelector('.js-cluster-enable-toggle-area');
if (toggleButtonsContainer) {
setupToggleButtons(toggleButtonsContainer);
}
this.initApplications(clusterType);
this.initEnvironments();
......
......@@ -118,7 +118,7 @@ export default {
</script>
<template>
<div>
<div class="gl-display-flex gl-justify-content-end">
<split-button
v-if="canCleanupResources"
:action-items="$options.splitButtonActionItems"
......
<script>
import { GlFormGroup, GlToggle, GlTooltipDirective } from '@gitlab/ui';
import { mapState } from 'vuex';
export default {
components: {
GlFormGroup,
GlToggle,
},
directives: {
GlTooltip: GlTooltipDirective,
},
data() {
return {
toggleEnabled: true,
};
},
computed: {
...mapState(['enabled', 'editable']),
},
mounted() {
this.toggleEnabled = this.enabled;
},
};
</script>
<template>
<div class="d-flex align-items-center">
<gl-form-group>
<div class="gl-display-flex gl-align-items-center">
<h4 class="gl-pr-3 gl-m-0 ">{{ s__('ClusterIntegration|GitLab Integration') }}</h4>
<input
id="cluster_enabled"
class="js-project-feature-toggle-input"
type="hidden"
:value="toggleEnabled"
name="cluster[enabled]"
/>
<div id="tooltipcontainer" class="js-cluster-enable-toggle-area">
<gl-toggle
v-model="toggleEnabled"
v-gl-tooltip:tooltipcontainer
class="gl-mb-0 js-project-feature-toggle"
data-qa-selector="integration_status_toggle"
:aria-describedby="__('Toggle Kubernetes cluster')"
:disabled="!editable"
:is_checked="toggleEnabled"
:title="
s__(
'ClusterIntegration|Enable or disable GitLab\'s connection to your Kubernetes cluster.',
)
"
/>
</div>
</div>
</gl-form-group>
</div>
</template>
import Vue from 'vue';
import IntegrationForm from '../components/integration_form.vue';
import { createStore } from '../stores';
export default () => {
const entryPoint = document.querySelector('#js-cluster-integration-form');
if (!entryPoint) {
return;
}
// eslint-disable-next-line no-new
new Vue({
el: entryPoint,
store: createStore(entryPoint.dataset),
render(createElement) {
return createElement(IntegrationForm);
},
});
};
import Vue from 'vue';
import Vuex from 'vuex';
import state from './state';
Vue.use(Vuex);
export const createStore = initialState =>
new Vuex.Store({
state: state(initialState),
});
export default createStore;
import { parseBoolean } from '../../../lib/utils/common_utils';
export default (initialState = {}) => {
return {
enabled: parseBoolean(initialState.enabled),
editable: parseBoolean(initialState.editable),
};
};
import ClustersBundle from '~/clusters/clusters_bundle';
import initClusterHealth from '~/pages/projects/clusters/show/cluster_health';
import initIntegrationForm from '~/clusters/forms/show';
document.addEventListener('DOMContentLoaded', () => {
new ClustersBundle(); // eslint-disable-line no-new
initClusterHealth();
initIntegrationForm();
});
import initCreateCluster from '~/create_cluster/init_create_cluster';
import initIntegrationForm from '~/clusters/forms/show/index';
document.addEventListener('DOMContentLoaded', () => {
initCreateCluster(document, gon);
initIntegrationForm();
});
import ClustersBundle from '~/clusters/clusters_bundle';
import initGkeNamespace from '~/create_cluster/gke_cluster_namespace';
import initClusterHealth from './cluster_health';
import initIntegrationForm from '~/clusters/forms/show';
document.addEventListener('DOMContentLoaded', () => {
new ClustersBundle(); // eslint-disable-line no-new
initGkeNamespace();
initClusterHealth();
initIntegrationForm();
});
# frozen_string_literal: true
module ClustersHelper
def has_multiple_clusters?
true
end
def create_new_cluster_label(provider: nil)
case provider
when 'aws'
......@@ -24,6 +28,13 @@ module ClustersHelper
}
end
def js_cluster_form_data(cluster, can_edit)
{
enabled: cluster.enabled?.to_s,
editable: can_edit.to_s
}
end
# This method is depreciated and will be removed when associated HAML files are moved to JavaScript
def provider_icon(provider = nil)
img_data = js_clusters_list_data.dig(:img_tags, provider&.to_sym) ||
......
......@@ -24,6 +24,7 @@
.text-muted
= s_('ClusterIntegration|A cluster management project can be used to run deployment jobs with Kubernetes <code>cluster-admin</code> privileges.').html_safe
= link_to _('More information'), help_page_path('user/clusters/management_project.md'), target: '_blank'
.gl-display-flex.gl-justify-content-end
= field.submit _('Save changes'), class: 'btn btn-success'
- if @cluster.managed?
......@@ -32,6 +33,7 @@
= s_('ClusterIntegration|Clear cluster cache')
%p
= s_("ClusterIntegration|Clear the local cache of namespace and service accounts. This is necessary if your integration has become out of sync. The cache is repopulated during the next CI job that requires namespace and service accounts.")
.gl-display-flex.gl-justify-content-end
= link_to(s_('ClusterIntegration|Clear cluster cache'), clusterable.clear_cluster_cache_path(@cluster), method: :delete, class: 'btn btn-primary')
.sub-section.form-group
......
= form_for @cluster, url: clusterable.cluster_path(@cluster), as: :cluster, html: { class: 'js-cluster-integration-form' } do |field|
= form_errors(@cluster)
.form-group
.d-flex.align-items-center
%h4.pr-2.m-0
= s_('ClusterIntegration|GitLab Integration')
%label.gl-mb-0.js-cluster-enable-toggle-area{ title: s_('ClusterIntegration|Enable or disable GitLab\'s connection to your Kubernetes cluster.'), data: { toggle: 'tooltip', container: 'body' } }
= render "shared/buttons/project_feature_toggle", is_checked: @cluster.enabled?, label: s_("ClusterIntegration|Toggle Kubernetes cluster"), disabled: !can?(current_user, :update_cluster, @cluster), data: { qa_selector: 'integration_status_toggle' } do
= field.hidden_field :enabled, { class: 'js-project-feature-toggle-input'}
#js-cluster-integration-form{ data: js_cluster_form_data(@cluster, can?(current_user, :update_cluster, @cluster)) }
.form-group
%h5= s_('ClusterIntegration|Environment scope')
= field.text_field :environment_scope, class: 'col-md-6 form-control js-select-on-focus', placeholder: s_('ClusterIntegration|Environment scope')
......@@ -32,5 +25,5 @@
= s_('ClusterIntegration| %{custom_domain_start}More information%{custom_domain_end}.').html_safe % { custom_domain_start: custom_domain_start, custom_domain_end: '</a>'.html_safe }
- if can?(current_user, :update_cluster, @cluster)
.form-group
= field.submit _('Save changes'), class: 'btn btn-success', data: { qa_selector: 'save_changes_button' }
.form-group.gl-display-flex.gl-justify-content-end
= field.submit _('Save changes'), class: 'btn btn-success', data: { qa_selector: 'save_changes_button'}
......@@ -48,5 +48,5 @@
- if cluster.allow_user_defined_namespace?
= render('clusters/clusters/namespace', platform_field: platform_field)
.form-group
.form-group.gl-display-flex.gl-justify-content-end
= field.submit s_('ClusterIntegration|Save changes'), class: 'btn btn-success'
---
title: Rewrite integration form in Vue
merge_request: 35453
author:
type: changed
......@@ -5790,9 +5790,6 @@ msgstr ""
msgid "ClusterIntegration|To remove your integration, type %{clusterName} to confirm:"
msgstr ""
msgid "ClusterIntegration|Toggle Kubernetes cluster"
msgstr ""
msgid "ClusterIntegration|Uninstall %{appTitle}"
msgstr ""
......@@ -24948,6 +24945,9 @@ msgstr ""
msgid "Today"
msgstr ""
msgid "Toggle Kubernetes cluster"
msgstr ""
msgid "Toggle Markdown preview"
msgstr ""
......
......@@ -10,8 +10,11 @@ module QA
element :ingress_ip_address, 'id="ingress-endpoint"' # rubocop:disable QA/ElementWithPattern
end
view 'app/views/clusters/clusters/_gitlab_integration_form.html.haml' do
view 'app/assets/javascripts/clusters/forms/components/integration_form.vue' do
element :integration_status_toggle, required: true
end
view 'app/views/clusters/clusters/_gitlab_integration_form.html.haml' do
element :base_domain_field, required: true
element :save_changes_button, required: true
end
......
......@@ -73,6 +73,7 @@ RSpec.describe 'User Cluster', :js do
end
it 'user sees a cluster details page' do
expect(page).to have_content('GitLab Integration')
expect(page).to have_button('Save changes')
end
......
import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
import { loadHTMLFixture } from 'helpers/fixtures';
import { setTestTimeout } from 'helpers/timeout';
import Clusters from '~/clusters/clusters_bundle';
......@@ -63,25 +62,6 @@ describe('Clusters', () => {
});
});
describe('toggle', () => {
it('should update the button and the input field on click', done => {
const toggleButton = document.querySelector(
'.js-cluster-enable-toggle-area .js-project-feature-toggle',
);
const toggleInput = document.querySelector(
'.js-cluster-enable-toggle-area .js-project-feature-toggle-input',
);
$(toggleInput).one('trigger-change', () => {
expect(toggleButton.classList).not.toContain('is-checked');
expect(toggleInput.getAttribute('value')).toEqual('false');
done();
});
toggleButton.click();
});
});
describe('checkForNewInstalls', () => {
const INITIAL_APP_MAP = {
helm: { status: null, title: 'Helm Tiller' },
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Remove cluster confirmation modal renders splitbutton with modal included 1`] = `
<div>
<div
class="gl-display-flex gl-justify-content-end"
>
<div
class="dropdown b-dropdown gl-dropdown btn-group"
>
......
import IntegrationForm from '~/clusters/forms/components/integration_form.vue';
import { createStore } from '~/clusters/forms/stores/index';
import { mount } from '@vue/test-utils';
import { GlToggle } from '@gitlab/ui';
describe('ClusterIntegrationForm', () => {
let wrapper;
let store;
const glToggle = () => wrapper.find(GlToggle);
const toggleButton = () => glToggle().find('button');
const toggleInput = () => wrapper.find('input');
const createWrapper = () => {
store = createStore({
enabled: 'true',
editable: 'true',
});
wrapper = mount(IntegrationForm, { store });
return wrapper.vm.$nextTick();
};
beforeEach(() => {
return createWrapper();
});
afterEach(() => {
wrapper.destroy();
});
it('creates the toggle and label', () => {
expect(wrapper.text()).toContain('GitLab Integration');
expect(wrapper.contains(GlToggle)).toBe(true);
});
it('initializes toggle with store value', () => {
expect(toggleButton().classes()).toContain('is-checked');
expect(toggleInput().attributes('value')).toBe('true');
});
it('switches the toggle value on click', () => {
toggleButton().trigger('click');
wrapper.vm.$nextTick(() => {
expect(toggleButton().classes()).not.toContain('is-checked');
expect(toggleInput().attributes('value')).toBe('false');
});
});
});
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