diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2017-11-23 15:04:03 +0300 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2017-11-23 15:04:03 +0300 |
commit | 45631562565760add7a7c52a6137e891f3a0c8f4 (patch) | |
tree | 44915f7c46d05fb8c6197662a3341ea8fb610f06 /app/assets/javascripts/vue_shared | |
parent | 1d8ab59ebfa0d57e4015665c470c8339cd258a2c (diff) |
Improve environments performance
Diffstat (limited to 'app/assets/javascripts/vue_shared')
-rw-r--r-- | app/assets/javascripts/vue_shared/components/navigation_tabs.vue | 76 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js | 42 |
2 files changed, 118 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/navigation_tabs.vue b/app/assets/javascripts/vue_shared/components/navigation_tabs.vue new file mode 100644 index 00000000000..a2ddd565170 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/navigation_tabs.vue @@ -0,0 +1,76 @@ +<script> + /** + * Given an array of tabs, renders non linked bootstrap tabs. + * When a tab is clicked it will trigger an event and provide the clicked scope. + * + * This component is used in apps that handle the API call. + * If you only need to change the URL this component should not be used. + * + * @example + * <navigation-tabs + * :tabs="[ + * { + * name: String, + * scope: String, + * count: Number || Undefined, + * isActive: Boolean, + * }, + * ]" + * @onChangeTab="onChangeTab" + * /> + */ + export default { + name: 'NavigationTabs', + props: { + tabs: { + type: Array, + required: true, + }, + scope: { + type: String, + required: false, + default: '', + }, + }, + mounted() { + $(document).trigger('init.scrolling-tabs'); + }, + methods: { + shouldRenderBadge(count) { + // 0 is valid in a badge, but evaluates to false, we need to check for undefined + return count !== undefined; + }, + + onTabClick(tab) { + this.$emit('onChangeTab', tab.scope); + }, + }, +}; +</script> +<template> + <ul class="nav-links scrolling-tabs"> + <li + v-for="(tab, i) in tabs" + :key="i" + :class="{ + active: tab.isActive, + }" + > + <a + role="button" + @click="onTabClick(tab)" + :class="`js-${scope}-tab-${tab.scope}`" + > + {{ tab.name }} + + <span + v-if="shouldRenderBadge(tab.count)" + class="badge" + > + {{tab.count}} + </span> + + </a> + </li> + </ul> +</template> diff --git a/app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js b/app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js new file mode 100644 index 00000000000..f94cc670edf --- /dev/null +++ b/app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js @@ -0,0 +1,42 @@ +/** + * API callbacks for pagination and tabs + * shared between Pipelines and Environments table. + * + * Components need to have `scope`, `page` and `requestData` + */ +import { + historyPushState, + buildUrlWithCurrentLocation, +} from '../../lib/utils/common_utils'; + +export default { + methods: { + onChangeTab(scope) { + this.updateContent({ scope, page: '1' }); + }, + + onChangePage(page) { + /* URLS parameters are strings, we need to parse to match types */ + this.updateContent({ scope: this.scope, page: Number(page).toString() }); + }, + + updateInternalState(parameters) { + // stop polling + this.poll.stop(); + + const queryString = Object.keys(parameters).map((parameter) => { + const value = parameters[parameter]; + // update internal state for UI + this[parameter] = value; + return `${parameter}=${encodeURIComponent(value)}`; + }).join('&'); + + // update polling parameters + this.requestData = parameters; + + historyPushState(buildUrlWithCurrentLocation(`?${queryString}`)); + + this.isLoading = true; + }, + }, +}; |