diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2017-11-28 13:16:44 +0000 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2017-11-28 13:33:52 +0000 |
commit | 18967d689402d6c3c2a36c844fb90aa051a69cc1 (patch) | |
tree | 332a059d12969af3515b9f8e6351530305f9cc7a /app/assets/javascripts | |
parent | 8796e7278ecaf5e225b586499ac856957b5fad8b (diff) | |
download | gitlab-ce-18967d689402d6c3c2a36c844fb90aa051a69cc1.tar.gz |
Changes after Frontend and UX review:
- Moves toggle button to a shared location
- Adds tests for toggle button
- Transforms Clusters class into function
- Improves UX
Diffstat (limited to 'app/assets/javascripts')
6 files changed, 121 insertions, 104 deletions
diff --git a/app/assets/javascripts/clusters/clusters_index.js b/app/assets/javascripts/clusters/clusters_index.js index 6249943da43..879212aad70 100644 --- a/app/assets/javascripts/clusters/clusters_index.js +++ b/app/assets/javascripts/clusters/clusters_index.js @@ -3,6 +3,29 @@ import { s__ } from '../locale'; import ClustersService from './services/clusters_service'; /** + * Toggles loading and disabled classes. + * @param {HTMLElement} button + */ +const toggleLoadingButton = (button) => { + if (button.getAttribute('disabled')) { + button.removeAttribute('disabled'); + } else { + button.setAttribute('disabled', true); + } + + button.classList.toggle('is-disabled'); + button.classList.toggle('is-loading'); +}; + +/** + * Toggles checked class for the given button + * @param {HTMLElement} button + */ +const toggleValue = (button) => { + button.classList.toggle('is-checked'); +}; + +/** * Handles toggle buttons in the cluster's table. * * When the user clicks the toggle button for each cluster, it: @@ -13,56 +36,24 @@ import ClustersService from './services/clusters_service'; * 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))); - } - /** - * When the toggle button is clicked, - * updates the status and makes a request to the API to update the cluster - * @param {Event} e - */ - 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.')); - }); - } +export default function setClusterTableToggles() { + document.querySelectorAll('.js-toggle-cluster-list') + .forEach(button => button.addEventListener('click', (e) => { + const toggleButton = e.currentTarget; + const value = toggleButton.classList.contains('checked').toString(); + const endpoint = toggleButton.getAttribute('data-endpoint'); - /** - * Toggles loading and disabled classes. - * @param {HTMLElement} button - */ - static toggleLoadingButton(button) { - if (button.getAttribute('disabled')) { - button.removeAttribute('disabled'); - } else { - button.setAttribute('disabled', true); - } + toggleValue(toggleButton); + toggleLoadingButton(toggleButton); - button.classList.toggle('disabled'); - button.classList.toggle('is-loading'); - button.querySelector('.loading-icon').classList.toggle('hidden'); - } - - /** - * Toggles checked class for the given button - * @param {HTMLElement} button - */ - static toggleValue(button) { - button.classList.toggle('checked'); - } + ClustersService.updateCluster(endpoint, { cluster: { enabled: value } }) + .then(() => { + toggleLoadingButton(toggleButton); + }) + .catch(() => { + toggleLoadingButton(toggleButton); + toggleValue(toggleButton); + Flash(s__('ClusterIntegration|Something went wrong on our end.')); + }); + })); } diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 49459f01bea..493d8726a13 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -556,7 +556,7 @@ import ProjectVariables from './project_variables'; break; case 'projects:clusters:index': import(/* webpackChunkName: "clusters_index" */ './clusters/clusters_index') - .then(clusterIndex => new clusterIndex.default()) // eslint-disable-line new-cap + .then(clusterIndex => clusterIndex.default()) .catch((err) => { Flash(s__('ClusterIntegration|Problem setting up the clusters list')); throw err; diff --git a/app/assets/javascripts/projects/permissions/components/project_feature_setting.vue b/app/assets/javascripts/projects/permissions/components/project_feature_setting.vue index 80c5d39f736..8fce4c63872 100644 --- a/app/assets/javascripts/projects/permissions/components/project_feature_setting.vue +++ b/app/assets/javascripts/projects/permissions/components/project_feature_setting.vue @@ -1,5 +1,5 @@ <script> -import projectFeatureToggle from './project_feature_toggle.vue'; +import projectFeatureToggle from '../../../vue_shared/components/toggle_button.vue'; export default { props: { diff --git a/app/assets/javascripts/projects/permissions/components/project_feature_toggle.vue b/app/assets/javascripts/projects/permissions/components/project_feature_toggle.vue deleted file mode 100644 index 2403c60186a..00000000000 --- a/app/assets/javascripts/projects/permissions/components/project_feature_toggle.vue +++ /dev/null @@ -1,51 +0,0 @@ -<script> -export default { - props: { - name: { - type: String, - required: false, - default: '', - }, - value: { - type: Boolean, - required: true, - }, - disabledInput: { - type: Boolean, - required: false, - default: false, - }, - }, - - model: { - prop: 'value', - event: 'change', - }, - - methods: { - toggleFeature() { - if (!this.disabledInput) this.$emit('change', !this.value); - }, - }, -}; -</script> - -<template> - <label class="toggle-wrapper"> - <input - v-if="name" - type="hidden" - :name="name" - :value="value" - /> - <button - type="button" - aria-label="Toggle" - class="project-feature-toggle" - data-enabled-text="Enabled" - data-disabled-text="Disabled" - :class="{ checked: value, disabled: disabledInput }" - @click="toggleFeature" - /> - </label> -</template> diff --git a/app/assets/javascripts/projects/permissions/components/settings_panel.vue b/app/assets/javascripts/projects/permissions/components/settings_panel.vue index 326d9105666..639429baf26 100644 --- a/app/assets/javascripts/projects/permissions/components/settings_panel.vue +++ b/app/assets/javascripts/projects/permissions/components/settings_panel.vue @@ -1,6 +1,6 @@ <script> import projectFeatureSetting from './project_feature_setting.vue'; -import projectFeatureToggle from './project_feature_toggle.vue'; +import projectFeatureToggle from '../../../vue_shared/components/toggle_button.vue'; import projectSettingRow from './project_setting_row.vue'; import { visibilityOptions, visibilityLevelDescriptions } from '../constants'; import { toggleHiddenClassBySelector } from '../external'; diff --git a/app/assets/javascripts/vue_shared/components/toggle_button.vue b/app/assets/javascripts/vue_shared/components/toggle_button.vue new file mode 100644 index 00000000000..ddc9ddbc3a3 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/toggle_button.vue @@ -0,0 +1,77 @@ +<script> + import loadingIcon from './loading_icon.vue'; + + export default { + props: { + name: { + type: String, + required: false, + default: '', + }, + value: { + type: Boolean, + required: true, + }, + disabledInput: { + type: Boolean, + required: false, + default: false, + }, + isLoading: { + type: Boolean, + required: false, + default: false, + }, + enabledText: { + type: String, + required: false, + default: 'Enabled', + }, + disabledText: { + type: String, + required: false, + default: 'Disabled', + }, + }, + + components: { + loadingIcon, + }, + + model: { + prop: 'value', + event: 'change', + }, + + methods: { + toggleFeature() { + if (!this.disabledInput) this.$emit('change', !this.value); + }, + }, + }; +</script> + +<template> + <label class="toggle-wrapper"> + <input + type="hidden" + :name="name" + :value="value" + /> + <button + type="button" + aria-label="Toggle" + class="project-feature-toggle" + :data-enabled-text="enabledText" + :data-disabled-text="disabledText" + :class="{ + 'is-checked': value, + 'is-disabled': disabledInput, + 'is-loading': isLoading + }" + @click="toggleFeature" + > + <loadingIcon class="loading-icon" /> + </button> + </label> +</template> |