Commit 2c2da2c0 authored by Filipa Lacerda's avatar Filipa Lacerda

Use new vue js pipelines table to render in merge request view

Remove duplicate data-toggle attributes.

Reuse the same pipeline table

Remove unneeded required resources

Remove unused file; Fix mr pipelines loading

Updates documentation
parent 7ef21460
/* eslint-disable no-new */
/* eslint-disable no-new, no-param-reassign */
/* global Vue, CommitsPipelineStore, PipelinesService, Flash */
//= require vue
......@@ -10,8 +10,10 @@
/**
* Commits View > Pipelines Tab > Pipelines Table.
* Merge Request View > Pipelines Tab > Pipelines Table.
*
* Renders Pipelines table in pipelines tab in the commits show view.
* Renders Pipelines table in pipelines tab in the merge request show view.
*
* Uses `pipelines-table-component` to render Pipelines table with an API call.
* Endpoint is provided in HTML and passed as scope.
......@@ -20,6 +22,7 @@
* 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.
*/
$(() => {
window.gl = window.gl || {};
gl.commits = gl.commits || {};
......@@ -55,11 +58,12 @@ $(() => {
}, {});
return {
endpoint: pipelinesTableData.pipelinesData,
endpoint: pipelinesTableData.endpoint,
svgs: svgsObject,
store,
state: store.state,
isLoading: false,
error: false,
};
},
......@@ -82,7 +86,9 @@ $(() => {
.then((json) => {
this.store.store(json);
this.isLoading = false;
this.error = false;
}).catch(() => {
this.error = true;
this.isLoading = false;
new Flash('An error occurred while fetching the pipelines.', 'alert');
});
......@@ -95,14 +101,15 @@ $(() => {
</div>
<div class="blank-state blank-state-no-icon"
v-if="!isLoading && state.pipelines.length === 0">
v-if="!isLoading && !error && state.pipelines.length === 0">
<h2 class="blank-state-title js-blank-state-title">
You don't have any pipelines.
</h2>
Put get started with pipelines button here!!!
</div>
<div class="table-holder" v-if='!isLoading && state.pipelines.length > 0'>
<div
class="table-holder pipelines"
v-if='!isLoading && state.pipelines.length > 0'>
<pipelines-table-component
:pipelines='state.pipelines'
:svgs='svgs'>
......
/* global gl, Flash */
/* eslint-disable no-param-reassign, no-underscore-dangle */
/*= require vue_realtime_listener/index.js */
/**
* Pipelines' Store for commits view.
*
......
......@@ -159,11 +159,6 @@
new ZenMode();
shortcut_handler = new ShortcutsNavigation();
break;
case 'projects:commit:pipelines':
new gl.MiniPipelineGraph({
container: '.js-pipeline-table',
});
break;
case 'projects:commits:show':
case 'projects:activity':
shortcut_handler = new ShortcutsNavigation();
......
......@@ -61,7 +61,6 @@
constructor({ action, setUrl, stubLocation } = {}) {
this.diffsLoaded = false;
this.pipelinesLoaded = false;
this.commitsLoaded = false;
this.fixedLayoutPref = null;
......@@ -116,10 +115,6 @@
$.scrollTo('.merge-request-details .merge-request-tabs', {
offset: -navBarHeight,
});
} else if (action === 'pipelines') {
this.loadPipelines($target.attr('href'));
this.expandView();
this.resetViewContainer();
} else {
this.expandView();
this.resetViewContainer();
......@@ -243,25 +238,6 @@
});
}
loadPipelines(source) {
if (this.pipelinesLoaded) {
return;
}
this.ajaxGet({
url: `${source}.json`,
success: (data) => {
$('#pipelines').html(data.html);
gl.utils.localTimeAgo($('.js-timeago', '#pipelines'));
this.pipelinesLoaded = true;
this.scrollToElement('#pipelines');
new gl.MiniPipelineGraph({
container: '.js-pipeline-table',
});
},
});
}
// Show or hide the loading spinner
//
// status - Boolean, true to show, false to hide
......
/* eslint-disable no-param-reassign */
/* global Vue, VueResource, gl */
/*= require vue_shared/components/commit */
/*= require vue_pagination/index */
//= require vue
/*= require vue-resource
/*= require vue_shared/vue_resource_interceptor */
/*= require ./status.js.es6 */
/*= require ./store.js.es6 */
/*= require ./pipeline_url.js.es6 */
/*= require ./stage.js.es6 */
/*= require ./stages.js.es6 */
/*= require ./pipeline_actions.js.es6 */
/*= require ./time_ago.js.es6 */
/*= require ./pipelines.js.es6 */
(() => {
const project = document.querySelector('.pipelines');
const entry = document.querySelector('.vue-pipelines-index');
const svgs = document.querySelector('.pipeline-svgs');
$(() => {
Vue.use(VueResource);
if (!entry) return null;
return new Vue({
el: entry,
data: {
scope: project.dataset.url,
store: new gl.PipelineStore(),
svgs: svgs.dataset,
el: document.querySelector('.vue-pipelines-index'),
data() {
const project = document.querySelector('.pipelines');
const svgs = document.querySelector('.pipeline-svgs').dataset;
// Transform svgs DOMStringMap to a plain Object.
const svgsObject = Object.keys(svgs).reduce((acc, element) => {
acc[element] = svgs[element];
return acc;
}, {});
return {
scope: project.dataset.url,
store: new gl.PipelineStore(),
svgs: svgsObject,
};
},
components: {
'vue-pipelines': gl.VuePipelines,
......@@ -39,4 +40,4 @@
</vue-pipelines>
`,
});
})();
});
......@@ -25,7 +25,6 @@
<button
v-if='actions'
class="dropdown-toggle btn btn-default has-tooltip js-pipeline-dropdown-manual-actions"
data-toggle="dropdown"
title="Manual build"
data-placement="top"
aria-label="Manual build"
......@@ -50,7 +49,6 @@
<button
v-if='artifacts'
class="dropdown-toggle btn btn-default build-artifacts has-tooltip js-pipeline-dropdown-download"
data-toggle="dropdown"
title="Artifacts"
data-placement="top"
aria-label="Artifacts"
......@@ -72,7 +70,7 @@
</div>
</div>
<div class="cancel-retry-btns inline">
<a
<button
v-if='pipeline.flags.retryable'
class="btn has-tooltip"
title="Retry"
......@@ -81,11 +79,10 @@
data-placement="top"
data-toggle="dropdown"
:href='pipeline.retry_path'
aria-label="Retry"
>
aria-label="Retry">
<i class="fa fa-repeat" aria-hidden="true"></i>
</a>
<a
<button
v-if='pipeline.flags.cancelable'
class="btn btn-remove has-tooltip"
title="Cancel"
......@@ -94,8 +91,7 @@
data-placement="top"
data-toggle="dropdown"
:href='pipeline.cancel_path'
aria-label="Cancel"
>
aria-label="Cancel">
<i class="fa fa-remove" aria-hidden="true"></i>
</a>
</div>
......
/* global Vue, Turbolinks, gl */
/* eslint-disable no-param-reassign */
//= require vue_pagination/index
//= require ./store.js.es6
//= require vue_shared/components/pipelines_table
((gl) => {
gl.VuePipelines = Vue.extend({
components: {
runningPipeline: gl.VueRunningPipeline,
pipelineActions: gl.VuePipelineActions,
stages: gl.VueStages,
commit: gl.CommitComponent,
pipelineUrl: gl.VuePipelineUrl,
pipelineHead: gl.VuePipelineHead,
glPagination: gl.VueGlPagination,
statusScope: gl.VueStatusScope,
timeAgo: gl.VueTimeAgo,
'pipelines-table-component': gl.pipelines.PipelinesTableComponent,
},
data() {
return {
pipelines: [],
......@@ -38,31 +37,6 @@
change(pagenum, apiScope) {
Turbolinks.visit(`?scope=${apiScope}&p=${pagenum}`);
},
author(pipeline) {
if (!pipeline.commit) return { avatar_url: '', web_url: '', username: '' };
if (pipeline.commit.author) return pipeline.commit.author;
return {
avatar_url: pipeline.commit.author_gravatar_url,
web_url: `mailto:${pipeline.commit.author_email}`,
username: pipeline.commit.author_name,
};
},
ref(pipeline) {
const { ref } = pipeline;
return { name: ref.name, tag: ref.tag, ref_url: ref.path };
},
commitTitle(pipeline) {
return pipeline.commit ? pipeline.commit.title : '';
},
commitSha(pipeline) {
return pipeline.commit ? pipeline.commit.short_id : '';
},
commitUrl(pipeline) {
return pipeline.commit ? pipeline.commit.commit_path : '';
},
match(string) {
return string.replace(/_([a-z])/g, (m, w) => w.toUpperCase());
},
},
template: `
<div>
......@@ -70,49 +44,10 @@
<i class="fa fa-spinner fa-spin"></i>
</div>
<div class="table-holder" v-if='pipelines.length'>
<table class="table ci-table">
<thead>
<tr>
<th class="pipeline-status">Status</th>
<th class="pipeline-info">Pipeline</th>
<th class="pipeline-commit">Commit</th>
<th class="pipeline-stages">Stages</th>
<th class="pipeline-date"></th>
<th class="pipeline-actions hidden-xs"></th>
</tr>
</thead>
<tbody>
<tr class="commit" v-for='pipeline in pipelines'>
<status-scope
:pipeline='pipeline'
:match='match'
:svgs='svgs'
>
</status-scope>
<pipeline-url :pipeline='pipeline'></pipeline-url>
<td>
<commit
:commit-icon-svg='svgs.commitIconSvg'
:author='author(pipeline)'
:tag="pipeline.ref.tag"
:title='commitTitle(pipeline)'
:commit-ref='ref(pipeline)'
:short-sha='commitSha(pipeline)'
:commit-url='commitUrl(pipeline)'
>
</commit>
</td>
<stages
:pipeline='pipeline'
:svgs='svgs'
:match='match'
>
</stages>
<time-ago :pipeline='pipeline' :svgs='svgs'></time-ago>
<pipeline-actions :pipeline='pipeline' :svgs='svgs'></pipeline-actions>
</tr>
</tbody>
</table>
<pipelines-table-component
:pipelines='pipelines'
:svgs='svgs'>
</pipelines-table-component>
</div>
<div class="pipelines realtime-loading" v-if='pageRequest'>
<i class="fa fa-spinner fa-spin"></i>
......
......@@ -14,9 +14,8 @@
type: Object,
required: true,
},
//FIXME: DOMStringMap is non standard, let's use a plain object.
svgs: {
type: DOMStringMap,
type: Object,
required: true,
},
match: {
......
/* global Vue, gl */
/* eslint-disable no-param-reassign */
((gl) => {
gl.VueStages = Vue.extend({
components: {
'vue-stage': gl.VueStage,
},
props: ['pipeline', 'svgs', 'match'],
template: `
<td class="stage-cell">
<div
class="stage-container dropdown js-mini-pipeline-graph"
v-for='stage in pipeline.details.stages'
>
<vue-stage :stage='stage' :svgs='svgs' :match='match'></vue-stage>
</div>
</td>
`,
});
})(window.gl || (window.gl = {}));
/* eslint-disable no-param-reassign */
/* global Vue */
//=require ./pipelines_table_row
//= require ./pipelines_table_row
/**
* Pipelines Table Component
......
......@@ -38,6 +38,7 @@
pipelineUrl: gl.VuePipelineUrl,
pipelineHead: gl.VuePipelineHead,
statusScope: gl.VueStatusScope,
'time-ago': gl.VueTimeAgo,
},
computed: {
......@@ -45,18 +46,50 @@
* If provided, returns the commit tag.
* Needed to render the commit component column.
*
* TODO: Document this logic, need to ask @grzesiek and @selfup
*
* @returns {Object|Undefined}
*/
commitAuthor() {
if (!this.pipeline.commit) {
return { avatar_url: '', web_url: '', username: '' };
}
if (this.pipeline &&
this.pipeline.commit &&
this.pipeline.commit.author) {
return this.pipeline.commit.author;
}
if (this.pipeline &&
this.pipeline.commit &&
this.pipeline.commit.author_gravatar_url &&
this.pipeline.commit.author_name &&
this.pipeline.commit.author_email) {
return {
avatar_url: this.pipeline.commit.author_gravatar_url,
web_url: `mailto:${this.pipeline.commit.author_email}`,
username: this.pipeline.commit.author_name,
};
}
return undefined;
},
/**
* Figure this out!
* Needed to render the commit component column.
*/
author(pipeline) {
if (!pipeline.commit) return { avatar_url: '', web_url: '', username: '' };
if (pipeline.commit.author) return pipeline.commit.author;
return {
avatar_url: pipeline.commit.author_gravatar_url,
web_url: `mailto:${pipeline.commit.author_email}`,
username: pipeline.commit.author_name,
};
},
/**
* If provided, returns the commit tag.
* Needed to render the commit component column.
......@@ -64,10 +97,10 @@
* @returns {String|Undefined}
*/
commitTag() {
// if (this.model.last_deployment &&
// this.model.last_deployment.tag) {
// return this.model.last_deployment.tag;
// }
if (this.pipeline.ref &&
this.pipeline.ref.tag) {
return this.pipeline.ref.tag;
}
return undefined;
},
......@@ -133,20 +166,6 @@
}
return undefined;
},
/**
* Figure this out!
* Needed to render the commit component column.
*/
author(pipeline) {
if (!pipeline.commit) return { avatar_url: '', web_url: '', username: '' };
if (pipeline.commit.author) return pipeline.commit.author;
return {
avatar_url: pipeline.commit.author_gravatar_url,
web_url: `mailto:${pipeline.commit.author_email}`,
username: pipeline.commit.author_name,
};
},
},
methods: {
......
......@@ -216,13 +216,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
format.json do
render json: {
html: view_to_html_string('projects/merge_requests/show/_pipelines'),
pipelines: PipelineSerializer
.new(project: @project, user: @current_user)
.with_pagination(request, response)
.represent(@pipelines)
}
render json: PipelineSerializer
.new(project: @project, user: @current_user)
.with_pagination(request, response)
.represent(@pipelines)
end
end
end
......
#commit-pipeline-table-view{ data: { endpoint: endpoint } }
.pipeline-svgs{ data: { "commit_icon_svg" => custom_icon("icon_commit"),
"icon_status_canceled" => custom_icon("icon_status_canceled"),
"icon_status_running" => custom_icon("icon_status_running"),
"icon_status_skipped" => custom_icon("icon_status_skipped"),
"icon_status_created" => custom_icon("icon_status_created"),
"icon_status_pending" => custom_icon("icon_status_pending"),
"icon_status_success" => custom_icon("icon_status_success"),
"icon_status_failed" => custom_icon("icon_status_failed"),
"icon_status_warning" => custom_icon("icon_status_warning"),
"stage_icon_status_canceled" => custom_icon("icon_status_canceled_borderless"),
"stage_icon_status_running" => custom_icon("icon_status_running_borderless"),
"stage_icon_status_skipped" => custom_icon("icon_status_skipped_borderless"),
"stage_icon_status_created" => custom_icon("icon_status_created_borderless"),
"stage_icon_status_pending" => custom_icon("icon_status_pending_borderless"),
"stage_icon_status_success" => custom_icon("icon_status_success_borderless"),
"stage_icon_status_failed" => custom_icon("icon_status_failed_borderless"),
"stage_icon_status_warning" => custom_icon("icon_status_warning_borderless"),
"icon_play" => custom_icon("icon_play"),
"icon_timer" => custom_icon("icon_timer"),
"icon_status_manual" => custom_icon("icon_status_manual"),
} }
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('commit/pipelines/pipelines_bundle.js')
......@@ -2,29 +2,4 @@
= render 'commit_box'
= render 'ci_menu'
#commit-pipeline-table-view{ data: { pipelines_data: pipelines_namespace_project_commit_path(@project.namespace, @project, @commit.id)}}
.pipeline-svgs{ data: { "commit_icon_svg" => custom_icon("icon_commit"),
"icon_status_canceled" => custom_icon("icon_status_canceled"),
"icon_status_running" => custom_icon("icon_status_running"),
"icon_status_skipped" => custom_icon("icon_status_skipped"),
"icon_status_created" => custom_icon("icon_status_created"),
"icon_status_pending" => custom_icon("icon_status_pending"),
"icon_status_success" => custom_icon("icon_status_success"),
"icon_status_failed" => custom_icon("icon_status_failed"),
"icon_status_warning" => custom_icon("icon_status_warning"),
"stage_icon_status_canceled" => custom_icon("icon_status_canceled_borderless"),
"stage_icon_status_running" => custom_icon("icon_status_running_borderless"),
"stage_icon_status_skipped" => custom_icon("icon_status_skipped_borderless"),
"stage_icon_status_created" => custom_icon("icon_status_created_borderless"),
"stage_icon_status_pending" => custom_icon("icon_status_pending_borderless"),
"stage_icon_status_success" => custom_icon("icon_status_success_borderless"),
"stage_icon_status_failed" => custom_icon("icon_status_failed_borderless"),
"stage_icon_status_warning" => custom_icon("icon_status_warning_borderless"),
"icon_play" => custom_icon("icon_play"),
"icon_timer" => custom_icon("icon_timer"),
"icon_status_manual" => custom_icon("icon_status_manual"),
} }
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('commit/pipelines/pipelines_bundle.js')
= render 'projects/commit/pipelines_list', endpoint: pipelines_namespace_project_commit_path(@project.namespace, @project, @commit.id)
......@@ -44,9 +44,9 @@
= render "projects/merge_requests/show/commits"
#diffs.diffs.tab-pane
-# This tab is always loaded via AJAX
- if @pipelines.any?
#pipelines.pipelines.tab-pane
= render "projects/merge_requests/show/pipelines"
#pipelines.pipelines.tab-pane
//TODO: This needs to make a new request every time is opened!
= render "projects/merge_requests/show/pipelines", endpoint: link_to url_for(params)
.mr-loading-status
= spinner
......
......@@ -94,7 +94,8 @@
#commits.commits.tab-pane
-# This tab is always loaded via AJAX
#pipelines.pipelines.tab-pane
-# This tab is always loaded via AJAX
//TODO: This needs to make a new request every time is opened!
= render 'projects/commit/pipelines_list', endpoint: pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
#diffs.diffs.tab-pane
-# This tab is always loaded via AJAX
......
= render "projects/commit/pipelines_list", pipelines: @pipelines, link_to_commit: true
= render 'projects/commit/pipelines_list', endpoint: pipelines_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment