import Vue from 'vue'; 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'; /** * * Uses `pipelines-table-component` to render Pipelines table with an API call. * Endpoint is provided in HTML and passed as `endpoint`. * We need a store to store the received environemnts. * We need a service to communicate with the server. * */ export default Vue.component('pipelines-table', { components: { pipelinesTableComponent, errorState, emptyState, loadingIcon, }, /** * Accesses the DOM to provide the needed data. * Returns the necessary props to render `pipelines-table-component` component. * * @return {Object} */ data() { const store = new PipelineStore(); return { endpoint: null, helpPagePath: null, store, state: store.state, isLoading: false, hasError: false, isMakingRequest: false, updateGraphDropdown: false, hasMadeRequest: false, }; }, computed: { shouldRenderErrorState() { 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 && this.hasMadeRequest && !this.hasError; }, shouldRenderTable() { return !this.isLoading && this.state.pipelines.length > 0 && !this.hasError; }, }, /** * When the component is about to be mounted, tell the service to fetch the data * * A request to fetch the pipelines will be made. * In case of a successfull response we will store the data in the provided * store, in case of a failed response we need to warn the user. * */ beforeMount() { const element = document.querySelector('#commit-pipeline-table-view'); this.endpoint = element.dataset.endpoint; this.helpPagePath = element.dataset.helpPagePath; this.service = new PipelinesService(this.endpoint); this.poll = new Poll({ resource: this.service, method: 'getPipelines', successCallback: this.successCallback, errorCallback: this.errorCallback, notificationCallback: this.setIsMakingRequest, }); 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 => 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"> <loading-icon label="Loading pipelines" size="3" v-if="isLoading" /> <empty-state v-if="shouldRenderEmptyState" :help-page-path="helpPagePath" /> <error-state v-if="shouldRenderErrorState" /> <div class="table-holder" v-if="shouldRenderTable"> <pipelines-table-component :pipelines="state.pipelines" :service="service" :update-graph-dropdown="updateGraphDropdown" /> </div> </div> `, });