Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipa Lacerda <filipa@gitlab.com>2017-11-23 15:04:03 +0300
committerPhil Hughes <me@iamphill.com>2017-11-23 15:04:03 +0300
commit45631562565760add7a7c52a6137e891f3a0c8f4 (patch)
tree44915f7c46d05fb8c6197662a3341ea8fb610f06 /app/assets/javascripts/vue_shared
parent1d8ab59ebfa0d57e4015665c470c8339cd258a2c (diff)
Improve environments performance
Diffstat (limited to 'app/assets/javascripts/vue_shared')
-rw-r--r--app/assets/javascripts/vue_shared/components/navigation_tabs.vue76
-rw-r--r--app/assets/javascripts/vue_shared/mixins/ci_pagination_api_mixin.js42
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;
+ },
+ },
+};