diff options
Diffstat (limited to 'app/assets/javascripts/vue_pipelines_index')
-rw-r--r-- | app/assets/javascripts/vue_pipelines_index/components/async_button.vue (renamed from app/assets/javascripts/vue_pipelines_index/components/async_button.js) | 49 | ||||
-rw-r--r-- | app/assets/javascripts/vue_pipelines_index/components/empty_state.js | 33 | ||||
-rw-r--r-- | app/assets/javascripts/vue_pipelines_index/components/empty_state.vue | 34 | ||||
-rw-r--r-- | app/assets/javascripts/vue_pipelines_index/components/error_state.js | 19 | ||||
-rw-r--r-- | app/assets/javascripts/vue_pipelines_index/components/error_state.vue | 21 | ||||
-rw-r--r-- | app/assets/javascripts/vue_pipelines_index/pipelines.js | 90 | ||||
-rw-r--r-- | app/assets/javascripts/vue_pipelines_index/services/pipelines_service.js | 3 |
7 files changed, 149 insertions, 100 deletions
diff --git a/app/assets/javascripts/vue_pipelines_index/components/async_button.js b/app/assets/javascripts/vue_pipelines_index/components/async_button.vue index 58b8db4d519..11da6e908b7 100644 --- a/app/assets/javascripts/vue_pipelines_index/components/async_button.js +++ b/app/assets/javascripts/vue_pipelines_index/components/async_button.vue @@ -1,3 +1,4 @@ +<script> /* eslint-disable no-new, no-alert */ /* global Flash */ import '~/flash'; @@ -65,29 +66,31 @@ export default { this.isLoading = true; this.service.postAction(this.endpoint) - .then(() => { - this.isLoading = false; - eventHub.$emit('refreshPipelines'); - }) - .catch(() => { - this.isLoading = false; - new Flash('An error occured while making the request.'); - }); + .then(() => { + this.isLoading = false; + eventHub.$emit('refreshPipelines'); + }) + .catch(() => { + this.isLoading = false; + new Flash('An error occured while making the request.'); + }); }, }, - - template: ` - <button - type="button" - @click="onClick" - :class="buttonClass" - :title="title" - :aria-label="title" - data-container="body" - data-placement="top" - :disabled="isLoading"> - <i :class="iconClass" aria-hidden="true"/> - <i class="fa fa-spinner fa-spin" aria-hidden="true" v-if="isLoading" /> - </button> - `, }; +</script> + +<template> + <button + type="button" + @click="onClick" + :class="buttonClass" + :title="title" + :aria-label="title" + data-container="body" + data-placement="top" + :disabled="isLoading" + > + <i :class="iconClass" aria-hidden="true"></i> + <i class="fa fa-spinner fa-spin" aria-hidden="true" v-if="isLoading"></i> + </button> +</template> diff --git a/app/assets/javascripts/vue_pipelines_index/components/empty_state.js b/app/assets/javascripts/vue_pipelines_index/components/empty_state.js deleted file mode 100644 index 56b4858f4b4..00000000000 --- a/app/assets/javascripts/vue_pipelines_index/components/empty_state.js +++ /dev/null @@ -1,33 +0,0 @@ -import pipelinesEmptyStateSVG from 'empty_states/icons/_pipelines_empty.svg'; - -export default { - props: { - helpPagePath: { - type: String, - required: true, - }, - }, - - template: ` - <div class="row empty-state"> - <div class="col-xs-12"> - <div class="svg-content"> - ${pipelinesEmptyStateSVG} - </div> - </div> - - <div class="col-xs-12 text-center"> - <div class="text-content"> - <h4>Build with confidence</h4> - <p> - Continous Integration can help catch bugs by running your tests automatically, - while Continuous Deployment can help you deliver code to your product environment. - </p> - <a :href="helpPagePath" class="btn btn-info"> - Get started with Pipelines - </a> - </div> - </div> - </div> - `, -}; diff --git a/app/assets/javascripts/vue_pipelines_index/components/empty_state.vue b/app/assets/javascripts/vue_pipelines_index/components/empty_state.vue new file mode 100644 index 00000000000..ba158bc4a1e --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/components/empty_state.vue @@ -0,0 +1,34 @@ +<script> +import pipelinesEmptyStateSVG from 'empty_states/icons/_pipelines_empty.svg'; + +export default { + props: { + helpPagePath: { + type: String, + required: true, + }, + }, + data: () => ({ pipelinesEmptyStateSVG }), +}; +</script> + +<template> + <div class="row empty-state"> + <div class="col-xs-12"> + <div class="svg-content" v-html="pipelinesEmptyStateSVG" /> + </div> + + <div class="col-xs-12 text-center"> + <div class="text-content"> + <h4>Build with confidence</h4> + <p> + Continous Integration can help catch bugs by running your tests automatically, + while Continuous Deployment can help you deliver code to your product environment. + </p> + <a :href="helpPagePath" class="btn btn-info"> + Get started with Pipelines + </a> + </div> + </div> + </div> +</template> diff --git a/app/assets/javascripts/vue_pipelines_index/components/error_state.js b/app/assets/javascripts/vue_pipelines_index/components/error_state.js deleted file mode 100644 index e5d228bddf8..00000000000 --- a/app/assets/javascripts/vue_pipelines_index/components/error_state.js +++ /dev/null @@ -1,19 +0,0 @@ -import pipelinesErrorStateSVG from 'empty_states/icons/_pipelines_failed.svg'; - -export default { - template: ` - <div class="row empty-state js-pipelines-error-state"> - <div class="col-xs-12"> - <div class="svg-content"> - ${pipelinesErrorStateSVG} - </div> - </div> - - <div class="col-xs-12 text-center"> - <div class="text-content"> - <h4>The API failed to fetch the pipelines.</h4> - </div> - </div> - </div> - `, -}; diff --git a/app/assets/javascripts/vue_pipelines_index/components/error_state.vue b/app/assets/javascripts/vue_pipelines_index/components/error_state.vue new file mode 100644 index 00000000000..90cee68163e --- /dev/null +++ b/app/assets/javascripts/vue_pipelines_index/components/error_state.vue @@ -0,0 +1,21 @@ +<script> +import pipelinesErrorStateSVG from 'empty_states/icons/_pipelines_failed.svg'; + +export default { + data: () => ({ pipelinesErrorStateSVG }), +}; +</script> + +<template> + <div class="row empty-state js-pipelines-error-state"> + <div class="col-xs-12"> + <div class="svg-content" v-html="pipelinesErrorStateSVG" /> + </div> + + <div class="col-xs-12 text-center"> + <div class="text-content"> + <h4>The API failed to fetch the pipelines.</h4> + </div> + </div> + </div> +</template> diff --git a/app/assets/javascripts/vue_pipelines_index/pipelines.js b/app/assets/javascripts/vue_pipelines_index/pipelines.js index 9bdc232b7da..6eea4812f33 100644 --- a/app/assets/javascripts/vue_pipelines_index/pipelines.js +++ b/app/assets/javascripts/vue_pipelines_index/pipelines.js @@ -1,12 +1,14 @@ import Vue from 'vue'; +import Visibility from 'visibilityjs'; import PipelinesService from './services/pipelines_service'; import eventHub from './event_hub'; import PipelinesTableComponent from '../vue_shared/components/pipelines_table'; import TablePaginationComponent from '../vue_shared/components/table_pagination'; -import EmptyState from './components/empty_state'; -import ErrorState from './components/error_state'; +import EmptyState from './components/empty_state.vue'; +import ErrorState from './components/error_state.vue'; import NavigationTabs from './components/navigation_tabs'; import NavigationControls from './components/nav_controls'; +import Poll from '../lib/utils/poll'; export default { props: { @@ -47,6 +49,7 @@ export default { pagenum: 1, isLoading: false, hasError: false, + isMakingRequest: false, }; }, @@ -120,18 +123,49 @@ export default { tagsPath: this.tagsPath, }; }, + + pageParameter() { + return gl.utils.getParameterByName('page') || this.pagenum; + }, + + scopeParameter() { + return gl.utils.getParameterByName('scope') || this.apiScope; + }, }, created() { this.service = new PipelinesService(this.endpoint); - this.fetchPipelines(); + const poll = new Poll({ + resource: this.service, + method: 'getPipelines', + data: { page: this.pageParameter, scope: this.scopeParameter }, + successCallback: this.successCallback, + errorCallback: this.errorCallback, + notificationCallback: this.setIsMakingRequest, + }); + + if (!Visibility.hidden()) { + this.isLoading = true; + poll.makeRequest(); + } + + Visibility.change(() => { + if (!Visibility.hidden()) { + poll.restart(); + } else { + poll.stop(); + } + }); eventHub.$on('refreshPipelines', this.fetchPipelines); }, beforeUpdate() { - if (this.state.pipelines.length && this.$children) { + if (this.state.pipelines.length && + this.$children && + !this.isMakingRequest && + !this.isLoading) { this.store.startTimeAgoLoops.call(this, Vue); } }, @@ -154,27 +188,35 @@ export default { }, fetchPipelines() { - const pageNumber = gl.utils.getParameterByName('page') || this.pagenum; - const scope = gl.utils.getParameterByName('scope') || this.apiScope; + if (!this.isMakingRequest) { + this.isLoading = true; - this.isLoading = true; - return this.service.getPipelines(scope, pageNumber) - .then(resp => ({ - headers: resp.headers, - body: resp.json(), - })) - .then((response) => { - this.store.storeCount(response.body.count); - this.store.storePipelines(response.body.pipelines); - this.store.storePagination(response.headers); - }) - .then(() => { - this.isLoading = false; - }) - .catch(() => { - this.hasError = true; - this.isLoading = false; - }); + this.service.getPipelines({ scope: this.scopeParameter, page: this.pageParameter }) + .then(response => this.successCallback(response)) + .catch(() => this.errorCallback()); + } + }, + + successCallback(resp) { + const response = { + headers: resp.headers, + body: resp.json(), + }; + + this.store.storeCount(response.body.count); + this.store.storePipelines(response.body.pipelines); + this.store.storePagination(response.headers); + + this.isLoading = false; + }, + + errorCallback() { + this.hasError = true; + this.isLoading = false; + }, + + setIsMakingRequest(isMakingRequest) { + this.isMakingRequest = isMakingRequest; }, }, diff --git a/app/assets/javascripts/vue_pipelines_index/services/pipelines_service.js b/app/assets/javascripts/vue_pipelines_index/services/pipelines_service.js index 708f5068dd3..255cd513490 100644 --- a/app/assets/javascripts/vue_pipelines_index/services/pipelines_service.js +++ b/app/assets/javascripts/vue_pipelines_index/services/pipelines_service.js @@ -26,7 +26,8 @@ export default class PipelinesService { this.pipelines = Vue.resource(endpoint); } - getPipelines(scope, page) { + getPipelines(data = {}) { + const { scope, page } = data; return this.pipelines.get({ scope, page }); } |