diff options
Diffstat (limited to 'app/assets/javascripts/commit/pipelines')
3 files changed, 132 insertions, 187 deletions
diff --git a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js index 86d99dd87da..687f09882a7 100644 --- a/app/assets/javascripts/commit/pipelines/pipelines_bundle.js +++ b/app/assets/javascripts/commit/pipelines/pipelines_bundle.js @@ -1,29 +1,43 @@ -/* eslint-disable no-param-reassign */ - import Vue from 'vue'; -import VueResource from 'vue-resource'; -import CommitPipelinesTable from './pipelines_table'; - -Vue.use(VueResource); +import commitPipelinesTable from './pipelines_table.vue'; /** - * Commits View > Pipelines Tab > Pipelines Table. - * - * Renders Pipelines table in pipelines tab in the commits show view. + * Used in: + * - Commit details View > Pipelines Tab > Pipelines Table. + * - Merge Request details View > Pipelines Tab > Pipelines Table. + * - New Merge Request View > Pipelines Tab > Pipelines Table. */ -// export for use in merge_request_tabs.js (TODO: remove this hack) +const CommitPipelinesTable = Vue.extend(commitPipelinesTable); + +// export for use in merge_request_tabs.js (TODO: remove this hack when we understand how to load +// vue.js in merge_request_tabs.js) window.gl = window.gl || {}; window.gl.CommitPipelinesTable = CommitPipelinesTable; -$(() => { - gl.commits = gl.commits || {}; - gl.commits.pipelines = gl.commits.pipelines || {}; - +document.addEventListener('DOMContentLoaded', () => { const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view'); - if (pipelineTableViewEl && pipelineTableViewEl.dataset.disableInitialization === undefined) { - gl.commits.pipelines.PipelinesTableBundle = new CommitPipelinesTable().$mount(); - pipelineTableViewEl.appendChild(gl.commits.pipelines.PipelinesTableBundle.$el); + if (pipelineTableViewEl) { + // Update MR and Commits tabs + pipelineTableViewEl.addEventListener('update-pipelines-count', (event) => { + if (event.detail.pipelines && + event.detail.pipelines.count && + event.detail.pipelines.count.all) { + const badge = document.querySelector('.js-pipelines-mr-count'); + + badge.textContent = event.detail.pipelines.count.all; + } + }); + + if (pipelineTableViewEl.dataset.disableInitialization === undefined) { + const table = new CommitPipelinesTable({ + propsData: { + endpoint: pipelineTableViewEl.dataset.endpoint, + helpPagePath: pipelineTableViewEl.dataset.helpPagePath, + }, + }).$mount(); + pipelineTableViewEl.appendChild(table.$el); + } } }); diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.js b/app/assets/javascripts/commit/pipelines/pipelines_table.js deleted file mode 100644 index e704be8b53e..00000000000 --- a/app/assets/javascripts/commit/pipelines/pipelines_table.js +++ /dev/null @@ -1,170 +0,0 @@ -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 '../../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. - * - * 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, - }, - - /** - * 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, - }; - }, - - computed: { - shouldRenderErrorState() { - return this.hasError && !this.isLoading; - }, - - shouldRenderEmptyState() { - return !this.state.pipelines.length && - !this.isLoading && - !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(); - } - - 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(); - - // 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; - }, - - errorCallback() { - this.hasError = true; - this.isLoading = false; - }, - - setIsMakingRequest(isMakingRequest) { - this.isMakingRequest = isMakingRequest; - }, - }, - - template: ` - <div class="content-list pipelines"> - <div - class="realtime-loading" - v-if="isLoading"> - <i - class="fa fa-spinner fa-spin" - aria-hidden="true" /> - </div> - - <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" /> - </div> - </div> - `, -}); diff --git a/app/assets/javascripts/commit/pipelines/pipelines_table.vue b/app/assets/javascripts/commit/pipelines/pipelines_table.vue new file mode 100644 index 00000000000..dd751ec97a8 --- /dev/null +++ b/app/assets/javascripts/commit/pipelines/pipelines_table.vue @@ -0,0 +1,101 @@ +<script> + import PipelinesService from '../../pipelines/services/pipelines_service'; + import PipelineStore from '../../pipelines/stores/pipelines_store'; + import pipelinesMixin from '../../pipelines/mixins/pipelines'; + + export default { + props: { + endpoint: { + type: String, + required: true, + }, + helpPagePath: { + type: String, + required: true, + }, + }, + mixins: [ + pipelinesMixin, + ], + + data() { + const store = new PipelineStore(); + + return { + store, + state: store.state, + }; + }, + + computed: { + /** + * 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; + }, + }, + created() { + this.service = new PipelinesService(this.endpoint); + }, + methods: { + successCallback(resp) { + return resp.json().then((response) => { + // depending of the endpoint the response can either bring a `pipelines` key or not. + const pipelines = response.pipelines || response; + this.setCommonData(pipelines); + + const updatePipelinesEvent = new CustomEvent('update-pipelines-count', { + detail: { + pipelines: response, + }, + }); + + // notifiy to update the count in tabs + if (this.$el.parentElement) { + this.$el.parentElement.dispatchEvent(updatePipelinesEvent); + } + }); + }, + }, + }; +</script> +<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" + :update-graph-dropdown="updateGraphDropdown" + /> + </div> + </div> +</template> |