summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/pages/projects/tree/components/commit_pipeline_status_component.vue95
-rw-r--r--app/assets/javascripts/pages/projects/tree/services/commit_pipeline_service.js11
-rw-r--r--app/assets/javascripts/pages/projects/tree/show/index.js18
-rw-r--r--app/assets/stylesheets/pages/commits.scss9
-rw-r--r--app/helpers/ci_status_helper.rb11
-rw-r--r--app/views/projects/commits/_commit.html.haml7
-rw-r--r--spec/javascripts/commit/commit_pipeline_status_component_spec.js68
7 files changed, 202 insertions, 17 deletions
diff --git a/app/assets/javascripts/pages/projects/tree/components/commit_pipeline_status_component.vue b/app/assets/javascripts/pages/projects/tree/components/commit_pipeline_status_component.vue
new file mode 100644
index 00000000000..2bd1e8e3266
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/tree/components/commit_pipeline_status_component.vue
@@ -0,0 +1,95 @@
+<script>
+ import Visibility from 'visibilityjs';
+ import ciIcon from '~/vue_shared/components/ci_icon.vue';
+ import Poll from '~/lib/utils/poll';
+ import Flash from '~/flash';
+ import tooltip from '~/vue_shared/directives/tooltip';
+ import CommitPipelineService from '../services/commit_pipeline_service';
+
+ export default {
+ directives: {
+ tooltip,
+ },
+ components: {
+ ciIcon,
+ },
+ props: {
+ endpoint: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ ciStatus: {},
+ isLoading: true,
+ service: {},
+ };
+ },
+ mounted() {
+ this.service = new CommitPipelineService(this.endpoint);
+ this.initPolling();
+ },
+ methods: {
+ successCallback(res) {
+ if (res.data.pipelines.length > 0) {
+ this.ciStatus = res.data.pipelines[0].details.status;
+ this.isLoading = false;
+ } else {
+ this.isLoading = true;
+ }
+ },
+ errorCallback(err) {
+ Flash(err);
+ },
+ initPolling() {
+ this.poll = new Poll({
+ resource: this.service,
+ method: 'fetchData',
+ successCallback: response => this.successCallback(response),
+ errorCallback: this.errorCallback,
+ });
+
+ if (!Visibility.hidden()) {
+ this.isLoading = true;
+ this.poll.makeRequest();
+ } else {
+ this.fetchPipelineCommitData();
+ }
+
+ Visibility.change(() => {
+ if (!Visibility.hidden()) {
+ this.poll.restart();
+ } else {
+ this.poll.stop();
+ }
+ });
+ },
+ fetchPipelineCommitData() {
+ this.service.fetchData()
+ .then(this.successCallback)
+ .catch(this.errorCallback);
+ },
+ },
+ destroy() {
+ this.poll.stop();
+ },
+ };
+</script>
+<template>
+ <div
+ v-if="isLoading">
+ </div>
+ <a
+ v-else
+ :href="ciStatus.details_path"
+ >
+ <ci-icon
+ v-tooltip
+ :title="ciStatus.text"
+ :aria-label="ciStatus.text"
+ data-container="body"
+ :status="ciStatus"
+ />
+ </a>
+</template>
diff --git a/app/assets/javascripts/pages/projects/tree/services/commit_pipeline_service.js b/app/assets/javascripts/pages/projects/tree/services/commit_pipeline_service.js
new file mode 100644
index 00000000000..4b4189bc2de
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/tree/services/commit_pipeline_service.js
@@ -0,0 +1,11 @@
+import axios from '~/lib/utils/axios_utils';
+
+export default class CommitPipelineService {
+ constructor(endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ fetchData() {
+ return axios.get(this.endpoint);
+ }
+}
diff --git a/app/assets/javascripts/pages/projects/tree/show/index.js b/app/assets/javascripts/pages/projects/tree/show/index.js
index 28a0160f47d..7181d4dfd47 100644
--- a/app/assets/javascripts/pages/projects/tree/show/index.js
+++ b/app/assets/javascripts/pages/projects/tree/show/index.js
@@ -1,8 +1,10 @@
+import Vue from 'vue';
import TreeView from '../../../../tree';
import ShortcutsNavigation from '../../../../shortcuts_navigation';
import BlobViewer from '../../../../blob/viewer';
import NewCommitForm from '../../../../new_commit_form';
import { ajaxGet } from '../../../../lib/utils/common_utils';
+import commitPipelineStatus from '../components/commit_pipeline_status_component.vue';
export default () => {
new ShortcutsNavigation(); // eslint-disable-line no-new
@@ -11,5 +13,21 @@ export default () => {
new NewCommitForm($('.js-create-dir-form')); // eslint-disable-line no-new
$('#tree-slider').waitForImages(() =>
ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath));
+
+ const commitPipelineStatusEl = document.getElementById('commit-pipeline-status');
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: '#commit-pipeline-status',
+ components: {
+ commitPipelineStatus,
+ },
+ render(createElement) {
+ return createElement('commit-pipeline-status', {
+ props: {
+ endpoint: commitPipelineStatusEl.dataset.endpoint,
+ },
+ });
+ },
+ });
};
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index aeaa33bd3bd..adfd72556b8 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -195,6 +195,10 @@
.commit-actions {
@media (min-width: $screen-sm-min) {
font-size: 0;
+
+ span {
+ font-size: 6px;
+ }
}
.ci-status-link {
@@ -219,6 +223,11 @@
font-size: 14px;
font-weight: $gl-font-weight-bold;
}
+
+ .ci-status-icon {
+ position: relative;
+ top: 3px;
+ }
}
.commit,
diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb
index 636316da80a..e8365f1da1e 100644
--- a/app/helpers/ci_status_helper.rb
+++ b/app/helpers/ci_status_helper.rb
@@ -103,17 +103,6 @@ module CiStatusHelper
tooltip_placement: tooltip_placement)
end
- def render_commit_status(commit, ref: nil, tooltip_placement: 'auto left')
- project = commit.project
- path = pipelines_project_commit_path(project, commit)
-
- render_status_with_link(
- 'commit',
- commit.status(ref),
- path,
- tooltip_placement: tooltip_placement)
- end
-
def render_pipeline_status(pipeline, tooltip_placement: 'auto left')
project = pipeline.project
path = project_pipeline_path(project, pipeline)
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index d66066a6d0b..436e1739180 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -26,9 +26,6 @@
%span.commit-row-message.visible-xs-inline
&middot;
= commit.short_id
- - if commit.status(ref)
- .visible-xs-inline
- = render_commit_status(commit, ref: ref)
- if commit.description?
%button.text-expander.hidden-xs.js-toggle-button{ type: "button" } ...
@@ -48,9 +45,7 @@
- else
= render partial: 'projects/commit/ajax_signature', locals: { commit: commit }
- - if commit.status(ref)
- = render_commit_status(commit, ref: ref)
-
+ #commit-pipeline-status{ data: { endpoint: pipelines_project_commit_path(project, commit.id) } }
= link_to commit.short_id, link, class: "commit-sha btn btn-transparent btn-link"
= clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard"))
= link_to_browse_code(project, commit)
diff --git a/spec/javascripts/commit/commit_pipeline_status_component_spec.js b/spec/javascripts/commit/commit_pipeline_status_component_spec.js
new file mode 100644
index 00000000000..f6fca9e97e5
--- /dev/null
+++ b/spec/javascripts/commit/commit_pipeline_status_component_spec.js
@@ -0,0 +1,68 @@
+import Vue from 'vue';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import commitPipelineStatus from '~/pages/projects/tree/components/commit_pipeline_status_component.vue';
+import mountComponent from '../helpers/vue_mount_component_helper';
+
+describe('Commit pipeline status component', () => {
+ let vm;
+ let component;
+ let mock;
+ const mockCiStatus = {
+ details_path: '/root/hello-world/pipelines/1',
+ favicon: 'canceled.ico',
+ group: 'canceled',
+ has_details: true,
+ icon: 'status_canceled',
+ label: 'canceled',
+ text: 'canceled',
+ };
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onGet('/dummy/endpoint').reply(() => {
+ const res = Promise.resolve([200, {
+ pipelines: [
+ {
+ details: {
+ status: mockCiStatus,
+ },
+ },
+ ],
+ }]);
+ return res;
+ });
+ component = Vue.extend(commitPipelineStatus);
+ });
+
+ afterEach(() => {
+ mock.reset();
+ });
+
+ describe('While polling pipeline data', () => {
+ beforeEach(() => {
+ vm = mountComponent(component, {
+ endpoint: '/dummy/endpoint',
+ });
+ });
+
+ afterEach(() => {
+ vm.poll.stop();
+ vm.$destroy();
+ });
+
+ it('contains a ciStatus when the polling is succesful ', (done) => {
+ setTimeout(() => {
+ expect(vm.ciStatus).toEqual(mockCiStatus);
+ done();
+ }, 1000);
+ });
+
+ it('contains a ci-status icon when polling is succesful', (done) => {
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.ci-status-icon')).not.toBe(null);
+ done();
+ });
+ });
+ });
+});