Commit 43e5009a authored by Filipa Lacerda's avatar Filipa Lacerda

Pipelines tabs

parent 77337a82
/**
* Linked Tabs
*
* Handles persisting and restores the current tab selection and content.
* Reusable component for static content.
*
* ### Example Markup
*
* <ul class="nav-links tab-links">
* <li class="active">
* <a data-action="tab1" data-target="#tab1" data-toggle="tab" href="/path/tab1">
* Tab 1
* </a>
* </li>
* <li class="groups-tab">
* <a data-action="tab2" data-target="#tab2" data-toggle="tab" href="/path/tab2">
* Tab 2
* </a>
* </li>
*
*
* <div class="tab-content">
* <div class="tab-pane" id="tab1">
* Tab 1 Content
* </div>
* <div class="tab-pane" id="tab2">
* Tab 2 Content
* </div>
* </div>
*
*
* ### How to use
*
* new window.gl.LinkedTabs({
* action: "#{controller.action_name}",
* defaultAction: 'tab1',
* parentEl: '.tab-links'
* });
*/
(() => {
window.gl = window.gl || {};
window.gl.LinkedTabs = class LinkedTabs {
/**
* Binds the events and activates de default tab.
*
* @param {Object} options
*/
constructor(options) {
this.options = options || {};
this.defaultAction = this.options.defaultAction;
this.action = this.options.action || this.defaultAction;
this.currentLocation = window.location;
if (this.action === 'show') {
this.action = this.defaultAction;
}
// since this is a custom event we need jQuery :(
$(document).on('shown.bs.tab', `${this.options.parentEl} a[data-toggle="tab"]`, evt => this.tabShown(evt));
this.activateTab(this.action);
}
/**
* Handles the `shown.bs.tab` event to set the currect url action.
*
* @param {type} evt
* @return {Function}
*/
tabShown(evt) {
const source = evt.target.getAttribute('href');
return this.setCurrentAction(source);
}
/**
* Updates the URL with the path that matched the given action.
*
* @param {String} source
* @return {String}
*/
setCurrentAction(source) {
const copySource = source;
copySource.replace(/\/+$/, '');
const newState = copySource + this.currentLocation.search + this.currentLocation.hash;
history.replaceState({
turbolinks: true,
url: newState,
}, document.title, newState);
return newState;
}
/**
* Given the current action activates the correct tab.
* http://getbootstrap.com/javascript/#tab-show
* Note: Will trigger `shown.bs.tab`
*/
activateTab() {
return $(`.pipelines-tabs a[data-action='${this.action}']`).tab('show');
}
};
})();
...@@ -32,6 +32,10 @@ class Projects::PipelinesController < Projects::ApplicationController ...@@ -32,6 +32,10 @@ class Projects::PipelinesController < Projects::ApplicationController
def show def show
end end
def builds
render 'show'
end
def retry def retry
pipeline.retry_failed(current_user) pipeline.retry_failed(current_user)
......
.tabs-holder .tabs-holder
%ul.nav-links.no-top.no-bottom %ul.pipelines-tabs.nav-links.no-top.no-bottom
%li.active
= link_to "Pipeline", "#js-tab-pipeline", data: { target: '#js-tab-pipeline', action: 'pipeline', toggle: 'tab' }, class: 'pipeline-tab'
%li %li
= link_to "#js-tab-builds", data: { target: '#js-tab-builds', action: 'build', toggle: 'tab' }, class: 'builds-tab' do = link_to namespace_project_pipeline_path(@project.namespace, @project, @pipeline), data: { target: 'div#js-tab-pipeline', action: 'pipelines', toggle: 'tab' } do
Pipeline
%li
= link_to builds_namespace_project_pipeline_path(@project.namespace, @project, @pipeline), data: {target: 'div#js-tab-builds', action: 'builds', toggle: 'tab' } do
Builds Builds
%span.badge= pipeline.statuses.count %span.badge= pipeline.statuses.count
.tab-content .tab-content
#js-tab-pipeline.tab-pane.active #js-tab-pipeline.tab-pane
.build-content.middle-block.pipeline-graph .build-content.middle-block.pipeline-graph
.pipeline-visualization .pipeline-visualization
%ul.stage-column-list %ul.stage-column-list
...@@ -49,3 +52,13 @@ ...@@ -49,3 +52,13 @@
%th %th
- pipeline.statuses.relevant.stages.each do |stage| - pipeline.statuses.relevant.stages.each do |stage|
= render 'projects/commit/ci_stage', stage: stage, statuses: pipeline.statuses.relevant.where(stage: stage) = render 'projects/commit/ci_stage', stage: stage, statuses: pipeline.statuses.relevant.where(stage: stage)
:javascript
var pipelines_tab;
pipelines_tab = new window.gl.LinkedTabs({
action: "#{controller.action_name}",
defaultAction: 'pipelines',
parentEl: '.pipelines-tabs'
});
...@@ -129,6 +129,7 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -129,6 +129,7 @@ constraints(ProjectUrlConstrainer.new) do
member do member do
post :cancel post :cancel
post :retry post :retry
get :builds
end end
end end
......
...@@ -178,6 +178,13 @@ describe "Pipelines" do ...@@ -178,6 +178,13 @@ describe "Pipelines" do
expect(page).to have_link('Play') expect(page).to have_link('Play')
end end
context 'page tabs' do
it 'should have two tabs' do
expect(page).to have_link('Pipeline')
expect(page).to have_link('Builds')
end
end
context 'retrying builds' do context 'retrying builds' do
it { expect(page).not_to have_content('retried') } it { expect(page).not_to have_content('retried') }
......
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