Commit 0ed8c459 authored by Fatih Acet's avatar Fatih Acet

Merge branch 'pipelines-page-redesign' into 'master'

Pipelines page redesign

Closes #23637
![Screen_Shot_2016-11-15_at_1.36.34_PM](/uploads/edc6a58f00cca3e03ffd1689bd6eebd8/Screen_Shot_2016-11-15_at_1.36.34_PM.png)

See merge request !7487
parents 688ff26d abe35457
...@@ -3,26 +3,12 @@ ...@@ -3,26 +3,12 @@
class Pipelines { class Pipelines {
constructor() { constructor() {
this.initGraphToggle();
this.addMarginToBuildColumns(); this.addMarginToBuildColumns();
} }
initGraphToggle() {
this.pipelineGraph = document.querySelector('.pipeline-graph');
this.toggleButton = document.querySelector('.toggle-pipeline-btn');
this.toggleButtonText = this.toggleButton.querySelector('.toggle-btn-text');
this.toggleButton.addEventListener('click', this.toggleGraph.bind(this));
}
toggleGraph() {
const graphCollapsed = this.pipelineGraph.classList.contains('graph-collapsed');
this.toggleButton.classList.toggle('graph-collapsed');
this.pipelineGraph.classList.toggle('graph-collapsed');
this.toggleButtonText.textContent = graphCollapsed ? 'Hide' : 'Expand';
}
addMarginToBuildColumns() { addMarginToBuildColumns() {
const secondChildBuildNodes = this.pipelineGraph.querySelectorAll('.build:nth-child(2)'); this.pipelineGraph = document.querySelector('.pipeline-graph');
const secondChildBuildNodes = document.querySelector('.pipeline-graph').querySelectorAll('.build:nth-child(2)');
for (buildNodeIndex in secondChildBuildNodes) { for (buildNodeIndex in secondChildBuildNodes) {
const buildNode = secondChildBuildNodes[buildNodeIndex]; const buildNode = secondChildBuildNodes[buildNodeIndex];
const firstChildBuildNode = buildNode.previousElementSibling; const firstChildBuildNode = buildNode.previousElementSibling;
......
...@@ -39,3 +39,5 @@ ...@@ -39,3 +39,5 @@
@import "framework/typography.scss"; @import "framework/typography.scss";
@import "framework/zen.scss"; @import "framework/zen.scss";
@import "framework/blank"; @import "framework/blank";
@import "framework/wells.scss";
@import "framework/page-header.scss";
...@@ -349,6 +349,12 @@ ...@@ -349,6 +349,12 @@
} }
} }
.btn-inverted {
&-secondary {
@include btn-outline($white-light, $blue-normal, $blue-normal, $blue-light, $white-light, $blue-light);
}
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
.btn-wide-on-xs { .btn-wide-on-xs {
width: 100%; width: 100%;
......
.page-content-header {
line-height: 34px;
padding: 10px 0;
margin-bottom: 0;
@media (min-width: $screen-sm-min) {
display: flex;
align-items: center;
.header-main-content {
flex: 1;
}
}
.header-action-buttons {
i {
color: $gl-icon-color;
font-size: 13px;
margin-right: 3px;
}
@media (max-width: $screen-xs-max) {
.btn {
width: 100%;
margin-top: 10px;
}
.dropdown {
width: 100%;
}
}
}
.avatar {
@extend .avatar-inline;
margin-left: 0;
@media (min-width: $screen-sm-min) {
margin-left: 4px;
}
}
.commit-committer-link,
.commit-author-link {
color: $gl-gray;
font-weight: bold;
}
.fa-clipboard {
color: $dropdown-title-btn-color;
}
.commit-info {
&.branches {
margin-left: 8px;
}
}
.ci-status-link {
svg {
position: relative;
top: 2px;
margin: 0 2px 0 3px;
}
}
}
...@@ -90,8 +90,8 @@ $table-border-color: #f0f0f0; ...@@ -90,8 +90,8 @@ $table-border-color: #f0f0f0;
$background-color: $gray-light; $background-color: $gray-light;
$dark-background-color: #f5f5f5; $dark-background-color: #f5f5f5;
$table-text-gray: #8f8f8f; $table-text-gray: #8f8f8f;
$widget-expand-item: #e8f2f7; $well-expand-item: #e8f2f7;
$widget-inner-border: #eef0f2; $well-inner-border: #eef0f2;
/* /*
* Text * Text
......
.info-well {
background: $background-color;
color: $gl-gray;
border: 1px solid $border-color;
border-radius: $border-radius-default;
.well-segment {
padding: $gl-padding;
&:not(:last-of-type) {
border-bottom: 1px solid $well-inner-border;
}
&.branch-info {
.monospace,
.commit-info {
margin-left: 4px;
}
}
}
.icon-container {
display: inline-block;
margin-right: 8px;
svg {
position: relative;
top: 2px;
height: 16px;
width: 16px;
}
&.commit-icon {
svg {
path {
fill: $gl-text-color;
}
}
}
}
.label.label-gray {
background-color: $well-expand-item;
}
}
...@@ -49,10 +49,6 @@ ...@@ -49,10 +49,6 @@
min-height: 58px; min-height: 58px;
align-items: center; align-items: center;
.btn-inverted {
@include btn-outline($white-light, $blue-normal, $blue-normal, $blue-light, $white-light, $blue-light);
}
@media (max-width: $screen-sm-max) { @media (max-width: $screen-sm-max) {
padding-right: 40px; padding-right: 40px;
...@@ -63,7 +59,6 @@ ...@@ -63,7 +59,6 @@
.header-content { .header-content {
flex: 1; flex: 1;
}
a { a {
color: $gl-gray; color: $gl-gray;
...@@ -73,6 +68,7 @@ ...@@ -73,6 +68,7 @@
text-decoration: none; text-decoration: none;
} }
} }
}
code { code {
color: $code-color; color: $code-color;
......
...@@ -26,143 +26,12 @@ ...@@ -26,143 +26,12 @@
white-space: pre-wrap; white-space: pre-wrap;
} }
.commit-info-row {
margin-bottom: 10px;
line-height: 24px;
padding-top: 6px;
&.commit-info-row-header {
line-height: 34px;
padding: 10px 0;
margin-bottom: 0;
@media (min-width: $screen-sm-min) {
display: flex;
align-items: center;
.commit-meta {
flex: 1;
}
}
.commit-hash-full {
@media (max-width: $screen-sm-max) {
width: 80px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: bottom;
}
}
.commit-action-buttons {
i {
color: $gl-icon-color;
font-size: 13px;
margin-right: 3px;
}
@media (max-width: $screen-xs-max) {
.dropdown {
width: 100%;
margin-top: 10px;
}
.dropdown-toggle {
width: 100%;
}
}
}
}
.avatar {
@extend .avatar-inline;
margin-left: 0;
@media (min-width: $screen-sm-min) {
margin-left: 4px;
}
}
.commit-committer-link,
.commit-author-link {
color: $gl-gray;
font-weight: bold;
}
.fa-clipboard {
color: $dropdown-title-btn-color;
}
.commit-info {
&.branches {
margin-left: 8px;
}
}
.ci-status-link {
svg {
position: relative;
top: 2px;
margin: 0 2px 0 3px;
}
}
}
.js-details-expand { .js-details-expand {
&:hover { &:hover {
text-decoration: none; text-decoration: none;
} }
} }
.commit-info-widget {
background: $background-color;
color: $gl-gray;
border: 1px solid $border-color;
border-radius: $border-radius-default;
.widget-row {
padding: $gl-padding;
&:not(:last-of-type) {
border-bottom: 1px solid $widget-inner-border;
}
&.branch-info {
.monospace,
.commit-info {
margin-left: 4px;
}
}
}
.icon-container {
display: inline-block;
margin-right: 8px;
svg {
position: relative;
top: 2px;
height: 16px;
width: 16px;
}
&.commit-icon {
svg {
path {
fill: $gl-text-color;
}
}
}
}
.label.label-gray {
background-color: $widget-expand-item;
}
}
.ci-status-link { .ci-status-link {
svg { svg {
overflow: visible; overflow: visible;
...@@ -184,6 +53,17 @@ ...@@ -184,6 +53,17 @@
} }
} }
.commit-hash-full {
@media (max-width: $screen-sm-max) {
width: 80px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: bottom;
}
}
.file-stats { .file-stats {
ul { ul {
list-style: none; list-style: none;
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
} }
.ci_widget { .ci_widget {
border-bottom: 1px solid $widget-inner-border; border-bottom: 1px solid $well-inner-border;
svg { svg {
margin-right: 4px; margin-right: 4px;
......
...@@ -300,6 +300,8 @@ ...@@ -300,6 +300,8 @@
.pipeline-graph { .pipeline-graph {
width: 100%; width: 100%;
background-color: $background-color;
padding: $gl-padding;
overflow: auto; overflow: auto;
white-space: nowrap; white-space: nowrap;
transition: max-height 0.3s, padding 0.3s; transition: max-height 0.3s, padding 0.3s;
...@@ -363,6 +365,7 @@ ...@@ -363,6 +365,7 @@
.build { .build {
border: 1px solid $border-color; border: 1px solid $border-color;
background-color: $white-light;
position: relative; position: relative;
padding: 7px 10px 8px; padding: 7px 10px 8px;
border-radius: 30px; border-radius: 30px;
......
...@@ -17,6 +17,6 @@ ...@@ -17,6 +17,6 @@
= render "user" = render "user"
= time_ago_with_tooltip(@build.created_at) = time_ago_with_tooltip(@build.created_at)
- if can?(current_user, :update_build, @build) && @build.retryable? - if can?(current_user, :update_build, @build) && @build.retryable?
= link_to "Retry build", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-inverted pull-right', method: :post = link_to "Retry build", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-inverted-secondary pull-right', method: :post
%button.btn.btn-default.pull-right.visible-xs-block.visible-sm-block.build-gutter-toggle.js-sidebar-build-toggle{ role: "button", type: "button" } %button.btn.btn-default.pull-right.visible-xs-block.visible-sm-block.build-gutter-toggle.js-sidebar-build-toggle{ role: "button", type: "button" }
= icon('angle-double-left') = icon('angle-double-left')
.commit-info-row.commit-info-row-header .page-content-header
.commit-meta .header-main-content
%strong Commit %strong Commit
%strong.monospace.js-details-short= @commit.short_id %strong.monospace.js-details-short= @commit.short_id
= link_to("#", class: "js-details-expand hidden-xs hidden-sm") do = link_to("#", class: "js-details-expand hidden-xs hidden-sm") do
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
%strong %strong
= commit_committer_link(@commit, avatar: true, size: 24) = commit_committer_link(@commit, avatar: true, size: 24)
#{time_ago_with_tooltip(@commit.committed_date)} #{time_ago_with_tooltip(@commit.committed_date)}
.commit-action-buttons
.header-action-buttons
- if defined?(@notes_count) && @notes_count > 0 - if defined?(@notes_count) && @notes_count > 0
%span.btn.disabled.btn-grouped.hidden-xs.append-right-10 %span.btn.disabled.btn-grouped.hidden-xs.append-right-10
= icon('comment') = icon('comment')
...@@ -55,8 +56,8 @@ ...@@ -55,8 +56,8 @@
%pre.commit-description %pre.commit-description
= preserve(markdown(@commit.description, pipeline: :single_line, author: @commit.author)) = preserve(markdown(@commit.description, pipeline: :single_line, author: @commit.author))
.commit-info-widget .info-well
.widget-row.branch-info .well-segment.branch-info
.icon-container.commit-icon .icon-container.commit-icon
= custom_icon("icon_commit") = custom_icon("icon_commit")
%span.cgray= pluralize(@commit.parents.count, "parent") %span.cgray= pluralize(@commit.parents.count, "parent")
...@@ -66,7 +67,7 @@ ...@@ -66,7 +67,7 @@
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
- if @commit.status - if @commit.status
.widget-row.pipeline-info .well-segment.pipeline-info
.icon-container .icon-container
= ci_icon_for_status(@commit.status) = ci_icon_for_status(@commit.status)
Pipeline Pipeline
......
.pipeline-graph-container .pipeline-graph-container
.row-content-block.build-content.middle-block.pipeline-actions .row-content-block.build-content.middle-block.pipeline-actions
.pull-right .pull-right
%button.btn.btn-grouped.btn-white.toggle-pipeline-btn
%span.toggle-btn-text Hide
%span pipeline graph
%span.caret
- if can?(current_user, :update_pipeline, pipeline.project) - if can?(current_user, :update_pipeline, pipeline.project)
- if pipeline.builds.latest.failed.any?(&:retryable?) - if pipeline.builds.latest.failed.any?(&:retryable?)
= link_to "Retry failed", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'btn btn-grouped btn-primary', method: :post = link_to "Retry failed", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'btn btn-grouped btn-primary', method: :post
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
%pre.commit-row-description.js-toggle-content %pre.commit-row-description.js-toggle-content
= preserve(markdown(commit.description, pipeline: :single_line, author: commit.author)) = preserve(markdown(commit.description, pipeline: :single_line, author: commit.author))
.commit-row-info
= commit_author_link(commit, avatar: false, size: 24) = commit_author_link(commit, avatar: false, size: 24)
authored authored
#{time_ago_with_tooltip(commit.committed_date)} #{time_ago_with_tooltip(commit.committed_date)}
%p .page-content-header
.commit-info-row .header-main-content
Pipeline
= link_to "##{@pipeline.id}", namespace_project_pipeline_path(@project.namespace, @project, @pipeline.id), class: "monospace"
with
= pluralize @pipeline.statuses.count(:id), "build"
- if @pipeline.ref
for
= link_to @pipeline.ref, namespace_project_commits_path(@project.namespace, @project, @pipeline.ref), class: "monospace"
- if @pipeline.duration
in
= time_interval_in_words(@pipeline.duration)
- if @pipeline.queued_duration
= "(queued for #{time_interval_in_words(@pipeline.queued_duration)})"
.pull-right
= link_to namespace_project_pipeline_path(@project.namespace, @project, @pipeline), class: "ci-status ci-#{@pipeline.status}" do = link_to namespace_project_pipeline_path(@project.namespace, @project, @pipeline), class: "ci-status ci-#{@pipeline.status}" do
= ci_icon_for_status(@pipeline.status) = ci_icon_for_status(@pipeline.status)
= ci_label_for_status(@pipeline.status) = ci_label_for_status(@pipeline.status)
%strong Pipeline ##{@commit.pipelines.last.id}
triggered #{time_ago_with_tooltip(@commit.authored_date)} by
= author_avatar(@commit, size: 24)
= commit_author_link(@commit)
.header-action-buttons
- if can?(current_user, :update_pipeline, @pipeline.project)
- if @pipeline.builds.latest.failed.any?(&:retryable?)
= link_to "Retry failed", retry_namespace_project_pipeline_path(@pipeline.project.namespace, @pipeline.project, @pipeline.id), class: 'btn btn-inverted-secondary', method: :post
- if @pipeline.builds.running_or_pending.any?
= link_to "Cancel running", cancel_namespace_project_pipeline_path(@pipeline.project.namespace, @pipeline.project, @pipeline.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post
- if @commit - if @commit
.commit-info-row .commit-box
%span.light Authored by
%strong
= commit_author_link(@commit, avatar: true, size: 24)
#{time_ago_with_tooltip(@commit.authored_date)}
.commit-info-row
%span.light Commit
= link_to @pipeline.sha, namespace_project_commit_path(@project.namespace, @project, @pipeline.sha), class: "monospace"
= clipboard_button(clipboard_text: @pipeline.sha)
- if @commit
.commit-box.content-block
%h3.commit-title %h3.commit-title
= markdown(@commit.title, pipeline: :single_line) = markdown(@commit.title, pipeline: :single_line)
- if @commit.description.present? - if @commit.description.present?
%pre.commit-description %pre.commit-description
= preserve(markdown(@commit.description, pipeline: :single_line)) = preserve(markdown(@commit.description, pipeline: :single_line))
.info-well
- if @commit.status
.well-segment.pipeline-info
.icon-container
= ci_icon_for_status(@commit.status)
= pluralize @pipeline.statuses.count(:id), "build"
- if @pipeline.ref
from
= link_to @pipeline.ref, namespace_project_commits_path(@project.namespace, @project, @pipeline.ref), class: "monospace"
- if @pipeline.duration
in
= time_interval_in_words(@pipeline.duration)
- if @pipeline.queued_duration
= "(queued for #{time_interval_in_words(@pipeline.queued_duration)})"
.well-segment.branch-info
.icon-container.commit-icon
= custom_icon("icon_commit")
= link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @pipeline.sha), class: "monospace js-details-short"
= link_to("#", class: "js-details-expand hidden-xs hidden-sm") do
%span.text-expander
\...
%span.js-details-content.hide
= link_to @pipeline.sha, namespace_project_commit_path(@project.namespace, @project, @pipeline.sha), class: "monospace commit-hash-full"
= clipboard_button(clipboard_text: @pipeline.sha, title: "Copy commit SHA to clipboard")
.tabs-holder
%ul.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
= link_to "#js-tab-builds", data: { target: '#js-tab-builds', action: 'build', toggle: 'tab' }, class: 'builds-tab' do
Builds
%span.badge= pipeline.statuses.count
.tab-content
#js-tab-pipeline.tab-pane.active
.build-content.middle-block.pipeline-graph
.pipeline-visualization
%ul.stage-column-list
- stages = pipeline.stages_with_latest_statuses
- stages.each do |stage, statuses|
%li.stage-column
.stage-name
%a{name: stage}
- if stage
= stage.titleize
.builds-container
%ul
= render "projects/commit/pipeline_stage", statuses: statuses
#js-tab-builds.tab-pane
- if pipeline.yaml_errors.present?
.bs-callout.bs-callout-danger
%h4 Found errors in your .gitlab-ci.yml:
%ul
- pipeline.yaml_errors.split(",").each do |error|
%li= error
You can also test your .gitlab-ci.yml in the #{link_to "Lint", ci_lint_path}
- if pipeline.project.builds_enabled? && !pipeline.ci_yaml_file
.bs-callout.bs-callout-warning
\.gitlab-ci.yml not found in this commit
.table-holder.pipeline-holder
%table.table.ci-table.pipeline
%thead
%tr
%th Status
%th Build ID
%th Name
%th
- if pipeline.project.build_coverage_enabled?
%th Coverage
%th
- pipeline.statuses.relevant.stages.each do |stage|
= render 'projects/commit/ci_stage', stage: stage, statuses: pipeline.statuses.relevant.where(stage: stage)
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
= render "projects/pipelines/head" = render "projects/pipelines/head"
%div{ class: container_class } %div{ class: container_class }
.prepend-top-default
- if @commit - if @commit
= render "projects/pipelines/info" = render "projects/pipelines/info"
%div.block-connector
= render "projects/commit/pipeline", pipeline: @pipeline = render "projects/pipelines/with_tabs", pipeline: @pipeline
---
title: Redesign pipelines page
merge_request:
author:
...@@ -64,7 +64,7 @@ describe 'Cherry-pick Commits' do ...@@ -64,7 +64,7 @@ describe 'Cherry-pick Commits' do
context "I cherry-pick a commit from a different branch", js: true do context "I cherry-pick a commit from a different branch", js: true do
it do it do
find('.commit-action-buttons a.dropdown-toggle').click find('.header-action-buttons a.dropdown-toggle').click
find(:css, "a[href='#modal-cherry-pick-commit']").click find(:css, "a[href='#modal-cherry-pick-commit']").click
page.within('#modal-cherry-pick-commit') do page.within('#modal-cherry-pick-commit') do
......
...@@ -146,7 +146,8 @@ describe "Pipelines" do ...@@ -146,7 +146,8 @@ describe "Pipelines" do
end end
describe 'GET /:project/pipelines/:id' do describe 'GET /:project/pipelines/:id' do
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master') } let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) }
before do before do
@success = create(:ci_build, :success, pipeline: pipeline, stage: 'build', name: 'build') @success = create(:ci_build, :success, pipeline: pipeline, stage: 'build', name: 'build')
......
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