diff options
Diffstat (limited to 'app/assets/javascripts/commit/pipelines/pipelines_table.js')
-rw-r--r-- | app/assets/javascripts/commit/pipelines/pipelines_table.js | 143 |
1 files changed, 105 insertions, 38 deletions
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js b/app/assets/javascripts/commit/pipelines/pipelines_table.js index 4d5a857d705..98698143d22 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_table.js +++ b/app/assets/javascripts/commit/pipelines/pipelines_table.js @@ -1,12 +1,15 @@ import Vue from 'vue'; -import PipelinesTableComponent from '../../vue_shared/components/pipelines_table'; -import PipelinesService from '../../vue_pipelines_index/services/pipelines_service'; -import PipelineStore from '../../vue_pipelines_index/stores/pipelines_store'; -import eventHub from '../../vue_pipelines_index/event_hub'; -import EmptyState from '../../vue_pipelines_index/components/empty_state'; -import ErrorState from '../../vue_pipelines_index/components/error_state'; +import Visibility from 'visibilityjs'; +import pipelinesTableComponent from '../../vue_shared/components/pipelines_table'; +import PipelinesService from '../../pipelines/services/pipelines_service'; +import PipelineStore from '../../pipelines/stores/pipelines_store'; +import eventHub from '../../pipelines/event_hub'; +import emptyState from '../../pipelines/components/empty_state.vue'; +import errorState from '../../pipelines/components/error_state.vue'; +import loadingIcon from '../../vue_shared/components/loading_icon.vue'; import '../../lib/utils/common_utils'; import '../../vue_shared/vue_resource_interceptor'; +import Poll from '../../lib/utils/poll'; /** * @@ -15,15 +18,15 @@ import '../../vue_shared/vue_resource_interceptor'; * We need a store to store the received environemnts. * We need a service to communicate with the server. * - * Necessary SVG in the table are provided as props. This should be refactored - * as soon as we have Webpack and can load them directly into JS files. */ export default Vue.component('pipelines-table', { + components: { - 'pipelines-table-component': PipelinesTableComponent, - 'error-state': ErrorState, - 'empty-state': EmptyState, + pipelinesTableComponent, + errorState, + emptyState, + loadingIcon, }, /** @@ -42,6 +45,9 @@ export default Vue.component('pipelines-table', { state: store.state, isLoading: false, hasError: false, + isMakingRequest: false, + updateGraphDropdown: false, + hasMadeRequest: false, }; }, @@ -50,8 +56,22 @@ export default Vue.component('pipelines-table', { return this.hasError && !this.isLoading; }, + /** + * Empty state is only rendered if after the first request we receive no pipelines. + * + * @return {Boolean} + */ shouldRenderEmptyState() { - return !this.state.pipelines.length && !this.isLoading; + return !this.state.pipelines.length && + !this.isLoading && + this.hasMadeRequest && + !this.hasError; + }, + + shouldRenderTable() { + return !this.isLoading && + this.state.pipelines.length > 0 && + !this.hasError; }, }, @@ -64,48 +84,92 @@ export default Vue.component('pipelines-table', { * */ beforeMount() { - this.endpoint = this.$el.dataset.endpoint; - this.helpPagePath = this.$el.dataset.helpPagePath; - this.service = new PipelinesService(this.endpoint); + const element = document.querySelector('#commit-pipeline-table-view'); - this.fetchPipelines(); + this.endpoint = element.dataset.endpoint; + this.helpPagePath = element.dataset.helpPagePath; + this.service = new PipelinesService(this.endpoint); - eventHub.$on('refreshPipelines', this.fetchPipelines); - }, + this.poll = new Poll({ + resource: this.service, + method: 'getPipelines', + successCallback: this.successCallback, + errorCallback: this.errorCallback, + notificationCallback: this.setIsMakingRequest, + }); - beforeUpdate() { - if (this.state.pipelines.length && this.$children) { - this.store.startTimeAgoLoops.call(this, Vue); + if (!Visibility.hidden()) { + this.isLoading = true; + this.poll.makeRequest(); + } else { + // If tab is not visible we need to make the first request so we don't show the empty + // state without knowing if there are any pipelines + this.fetchPipelines(); } + + Visibility.change(() => { + if (!Visibility.hidden()) { + this.poll.restart(); + } else { + this.poll.stop(); + } + }); + + eventHub.$on('refreshPipelines', this.fetchPipelines); }, beforeDestroyed() { eventHub.$off('refreshPipelines'); }, + destroyed() { + this.poll.stop(); + }, + methods: { fetchPipelines() { this.isLoading = true; + return this.service.getPipelines() - .then(response => response.json()) - .then((json) => { - // depending of the endpoint the response can either bring a `pipelines` key or not. - const pipelines = json.pipelines || json; - this.store.storePipelines(pipelines); - this.isLoading = false; - }) - .catch(() => { - this.hasError = true; - this.isLoading = false; - }); + .then(response => this.successCallback(response)) + .catch(() => this.errorCallback()); + }, + + successCallback(resp) { + const response = resp.json(); + + this.hasMadeRequest = true; + + // depending of the endpoint the response can either bring a `pipelines` key or not. + const pipelines = response.pipelines || response; + this.store.storePipelines(pipelines); + this.isLoading = false; + this.updateGraphDropdown = true; + }, + + errorCallback() { + this.hasError = true; + this.isLoading = false; + this.updateGraphDropdown = false; + }, + + setIsMakingRequest(isMakingRequest) { + this.isMakingRequest = isMakingRequest; + + if (isMakingRequest) { + this.updateGraphDropdown = false; + } }, }, template: ` <div class="content-list pipelines"> - <div class="realtime-loading" v-if="isLoading"> - <i class="fa fa-spinner fa-spin"></i> - </div> + + <loading-icon + label="Loading pipelines" + size="3" + v-if="isLoading" + /> <empty-state v-if="shouldRenderEmptyState" @@ -113,11 +177,14 @@ export default Vue.component('pipelines-table', { <error-state v-if="shouldRenderErrorState" /> - <div class="table-holder" - v-if="!isLoading && state.pipelines.length > 0"> + <div + class="table-holder" + v-if="shouldRenderTable"> <pipelines-table-component :pipelines="state.pipelines" - :service="service" /> + :service="service" + :update-graph-dropdown="updateGraphDropdown" + /> </div> </div> `, |