Skip to content
Snippets Groups Projects
Verified Commit 0bee0186 authored by Filipa Lacerda's avatar Filipa Lacerda
Browse files

Adds JS to toggle buttons [ci skip]

parent 5413bf04
No related branches found
No related tags found
No related merge requests found
import Flash from '../flash';
import { s__ } from '../locale';
import ClustersService from './services/clusters_service';
/**
* Handles toggle buttons in the cluster's table.
*
* When the user clicks the toggle button for each cluster, it:
* - toggles the button
* - shows a loding and disabled state
* - Makes a put request to the given endpoint
* Once we receive the response, either:
* 1) Show updated status in case of successfull response
* 2) Show initial status in case of failed response
*/
export default class ClusterTable {
constructor() {
this.container = '.js-clusters-list';
document.querySelectorAll(`${this.container} .js-toggle-cluster-list`).forEach(button => button.addEventListener('click', e => ClusterTable.updateCluster(e)));
}
removeListeners() {
document.querySelectorAll(`${this.container} .js-toggle-cluster-list`).forEach(button => button.removeEventListener('click'));
}
static updateCluster(e) {
const toggleButton = e.currentTarget;
const value = toggleButton.classList.contains('checked').toString();
const endpoint = toggleButton.getAttribute('data-endpoint');
ClusterTable.toggleValue(toggleButton);
ClusterTable.toggleLoadingButton(toggleButton);
ClustersService.updateCluster(endpoint, { cluster: { enabled: value } })
.then(() => {
ClusterTable.toggleLoadingButton(toggleButton);
})
.catch(() => {
ClusterTable.toggleLoadingButton(toggleButton);
ClusterTable.toggleValue(toggleButton);
Flash(s__('ClusterIntegration|Something went wrong on our end.'));
});
}
/**
* Toggles loading and disabled classes.
* @param {HTMLElement} button
*/
static toggleLoadingButton(button) {
button.setAttribute('disabled', button.getAttribute('disabled'));
button.classList.toggle('disabled');
button.classList.toggle('loading');
}
/**
* Toggles checked class for the given button
* @param {HTMLElement} button
*/
static toggleValue(button) {
button.classList.toggle('checked');
}
}
Loading
Loading
@@ -17,4 +17,8 @@ export default class ClusterService {
installApplication(appId) {
return axios.post(this.appInstallEndpointMap[appId]);
}
static updateCluster(endpoint, data) {
return axios.put(endpoint, data);
}
}
Loading
Loading
@@ -550,7 +550,15 @@ import ProjectVariables from './project_variables';
import(/* webpackChunkName: "clusters" */ './clusters/clusters_bundle')
.then(cluster => new cluster.default()) // eslint-disable-line new-cap
.catch((err) => {
Flash(s__('ClusterIntegration|Problem setting up the cluster JavaScript'));
Flash(s__('ClusterIntegration|Problem setting up the cluster'));
throw err;
});
break;
case 'projects:clusters:index':
import(/* webpackChunkName: "clusters_index" */ './clusters/clusters_index')
.then(clusterIndex => new clusterIndex.default()) // eslint-disable-line new-cap
.catch((err) => {
Flash(s__('ClusterIntegration|Problem setting up the clusters list'));
throw err;
});
break;
Loading
Loading
Loading
Loading
@@ -7,7 +7,7 @@ class Projects::ClustersController < Projects::ApplicationController
before_action :authorize_admin_cluster!, only: [:destroy]
 
def index
@clusters ||= project.clusters.map { |cluster| cluster.present(current_user: current_user) }
@clusters ||= project.clusters.page(params[:page]).per(20).map { |cluster| cluster.present(current_user: current_user) }
end
 
def login
Loading
Loading
@@ -64,10 +64,20 @@ class Projects::ClustersController < Projects::ApplicationController
.execute(cluster)
 
if cluster.valid?
flash[:notice] = "Cluster was successfully updated."
redirect_to project_cluster_path(project, project.cluster)
respond_to do |format|
format.json do
head :no_content
end
format.html do
flash[:notice] = "Cluster was successfully updated."
redirect_to project_cluster_path(project, project.cluster)
end
end
else
render :show
respond_to do |format|
format.json { head :bad_request }
format.html { render :show }
end
end
end
 
Loading
Loading
Loading
Loading
@@ -5,6 +5,6 @@
%p= s_('ClusterIntegration|Clusters allow you to use review apps, deploy your applications, run your pipelines, and much more in an easy way. %{link_to_help_page}').html_safe % { link_to_help_page: link_to_help_page}
 
%p
= link_to s_('ClusterIntegration|Add cluster'), '', class: 'btn btn-success', title: 'Add cluster'
= link_to s_('ClusterIntegration|Add cluster'), new_project_cluster_path(@project), class: 'btn btn-success', title: 'Add cluster'
.svg-content
= image_tag 'illustrations/labels.svg'
Loading
Loading
@@ -21,8 +21,8 @@
%span.badge
0
.nav-controls
= link_to s_('ClusterIntegration|Add cluster'), '', class: 'btn btn-success', title: 'Add cluster'
.ci-table
= link_to s_('ClusterIntegration|Add cluster'), new_project_cluster_path(@project), class: 'btn btn-success', title: 'Add cluster'
.ci-table.js-clusters-list
.gl-responsive-table-row.table-row-header{ role: 'row' }
.table-section.section-30{ role: 'rowheader' }
= s_('ClusterIntegration|Cluster')
Loading
Loading
@@ -31,27 +31,30 @@
.table-section.section-30{ role: 'rowheader' }
= s_('ClusterIntegration|Project namespace')
.table-section.section-10{ role: 'rowheader' }
.gl-responsive-table-row
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }
= s_('ClusterIntegration|Cluster')
.table-mobile-content
Content goes here
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }
= s_('ClusterIntegration|Environment pattern')
.table-mobile-content
Content goes here
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }
= s_('ClusterIntegration|Project namespace')
.table-mobile-content
Content goes here
.table-section.section-10
.table-mobile-header{ role: 'rowheader' }
.table-mobile-content
%button{ type: 'button',
class: "js-toggle-cluster project-feature-toggle",
'aria-label': s_('ClusterIntegration|Toggle Cluster'),
data: { 'enabled-text': 'Enabled', 'disabled-text': 'Disabled' } }
- @clusters.each do |cluster|
.gl-responsive-table-row
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }= s_('ClusterIntegration|Cluster')
.table-mobile-content= cluster.name
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }
= s_('ClusterIntegration|Environment pattern')
.table-mobile-content
Content goes here
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }
= s_('ClusterIntegration|Project namespace')
.table-mobile-content
Content goes here
.table-section.section-10
.table-mobile-header{ role: 'rowheader' }
.table-mobile-content
%button{ type: 'button',
class: "js-toggle-cluster-list project-feature-toggle #{'checked' unless !cluster.enabled?} #{'disabled' unless can?(current_user, :update_cluster, cluster)}",
'aria-label': s_('ClusterIntegration|Toggle Cluster'),
disabled: !can?(current_user, :update_cluster, cluster),
data: { 'enabled-text': 'Enabled',
'disabled-text': 'Disabled',
endpoint: namespace_project_cluster_path(@project.namespace, @project, cluster, format: :json) } }
= icon('loading', class: 'hidden')
 
Loading
Loading
@@ -94,6 +94,33 @@ feature 'Clusters', :js do
visit project_clusters_path(project)
end
 
it 'user sees a table with one cluster' do
end
it 'user sees a disabled add cluster button ' do
end
it 'user sees navigation tabs' do
end
context 'update cluster' do
it 'user can update cluster' do
end
context 'with sucessfull request' do
it 'user sees updated cluster' do
end
end
context 'with failed request' do
it 'user sees not update cluster and error message' do
end
end
end
context 'when user clicks on a cluster' do
before do
# TODO: Replace with Click on cluster after frontend implements list
Loading
Loading
@@ -216,4 +243,6 @@ feature 'Clusters', :js do
expect(page).to have_css('.signin-with-google')
end
end
context
end
import ClusterTable from '~/clusters/clusters_index';
describe('Clusters table', () => {
let ClustersClass;
beforeEach(() => {
ClustersClass = new ClusterTable();
});
afterEach(() => {
ClustersClass.removeListeners();
});
describe('update cluster', () => {
it('renders a toggle button', () => {
});
it('renders loading state while request is made', () => {
});
it('shows updated state after sucessfull request', () => {
});
it('shows inital state after failed request', () => {
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment