Commit cd85baf5 authored by Annabel Dunstone Gray's avatar Annabel Dunstone Gray

Merge branch 'pipelines-graph-html-css' into 'master'

Pipelines graph HTML and CSS improvements  and bug fixing

Closes #26257

See merge request !8443
parents 3b8c81fe d1fc4ec0
...@@ -525,3 +525,4 @@ Pipeline Graph ...@@ -525,3 +525,4 @@ Pipeline Graph
*/ */
$stage-hover-bg: #eaf3fc; $stage-hover-bg: #eaf3fc;
$stage-hover-border: #d1e7fc; $stage-hover-border: #d1e7fc;
$action-icon-color: #d6d6d6;
...@@ -177,12 +177,13 @@ ...@@ -177,12 +177,13 @@
.stage-cell { .stage-cell {
font-size: 0; font-size: 0;
svg { > .stage-container > button > svg {
height: 18px; height: 22px;
width: 18px; width: 22px;
position: relative; position: absolute;
top: -1px;
left: -1px;
z-index: 2; z-index: 2;
vertical-align: middle;
overflow: visible; overflow: visible;
} }
...@@ -200,7 +201,7 @@ ...@@ -200,7 +201,7 @@
content: ''; content: '';
width: 8px; width: 8px;
position: absolute; position: absolute;
right: -7px; right: -8px;
top: 10px; top: 10px;
border-bottom: 2px solid $border-color; border-bottom: 2px solid $border-color;
} }
...@@ -338,7 +339,8 @@ ...@@ -338,7 +339,8 @@
white-space: nowrap; white-space: nowrap;
transition: max-height 0.3s, padding 0.3s; transition: max-height 0.3s, padding 0.3s;
ul { .stage-column-list,
.builds-container > ul {
padding: 0; padding: 0;
} }
...@@ -470,6 +472,47 @@ ...@@ -470,6 +472,47 @@
white-space: normal; white-space: normal;
color: $gl-text-color-secondary; color: $gl-text-color-secondary;
// Action Icons in big pipeline-graph nodes
> .ci-action-icon-container .ci-action-icon-wrapper {
i {
color: $border-color;
border-radius: 100%;
border: 1px solid $border-color;
padding: 5px 6px;
font-size: 13px;
background: $white-light;
height: 30px;
width: 30px;
&::before {
position: relative;
top: 3px;
left: 3px;
}
&:hover {
color: $gl-text-color;
background-color: $stage-hover-bg;
border: 1px solid $stage-hover-bg;
}
}
.ci-play-icon {
padding: 5px 5px 5px 7px;
}
}
> .ci-action-icon-container {
position: absolute;
right: 5px;
top: 5px;
}
.ci-status-icon svg {
height: 20px;
width: 20px;
}
.dropdown-menu-toggle { .dropdown-menu-toggle {
background-color: transparent; background-color: transparent;
border: none; border: none;
...@@ -504,16 +547,6 @@ ...@@ -504,16 +547,6 @@
} }
} }
> .ci-action-icon-container {
position: absolute;
right: 5px;
top: 5px;
}
.ci-status-icon svg {
height: 20px;
width: 20px;
}
.arrow { .arrow {
&::before, &::before,
...@@ -596,29 +629,9 @@ ...@@ -596,29 +629,9 @@
} }
} }
} }
.grouped-pipeline-dropdown {
.dropdown-build {
.build-content {
width: 100%;
&:hover {
background-color: $stage-hover-bg;
color: $gl-text-color;
}
}
.ci-action-icon-container {
padding: 0;
font-size: 11px;
position: absolute;
top: 1px;
right: 8px;
}
}
}
} }
// Triggers the dropdown in the big pipeline graph
.dropdown-counter-badge { .dropdown-counter-badge {
color: $border-color; color: $border-color;
font-weight: 100; font-weight: 100;
...@@ -628,66 +641,6 @@ ...@@ -628,66 +641,6 @@
top: 8px; top: 8px;
} }
.grouped-pipeline-dropdown {
padding: 0;
width: 195px;
min-width: 195px;
left: auto;
right: -195px;
top: -4px;
box-shadow: 0 1px 5px $black-transparent;
a {
display: inline-block;
}
.dropdown-build {
.build-content {
width: 100%;
&:hover {
background-color: $stage-hover-bg;
color: $gl-text-color;
}
}
.ci-action-icon-container {
padding: 0;
font-size: 11px;
position: absolute;
margin-top: 3px;
right: 7px;
}
}
ul {
max-height: 245px;
overflow: auto;
margin: 3px 0;
li {
margin: 4px 8px 4px 9px;
padding: 0;
line-height: 1.1;
position: relative;
.ci-action-icon-container:hover {
background-color: transparent;
}
.ci-status-icon {
position: relative;
top: 2px;
}
}
}
}
.pipeline-graph .dropdown-build .ci-status-icon svg {
width: 18px;
height: 18px;
}
.ci-status-text { .ci-status-text {
max-width: 110px; max-width: 110px;
white-space: nowrap; white-space: nowrap;
...@@ -699,177 +652,233 @@ ...@@ -699,177 +652,233 @@
font-weight: 200; font-weight: 200;
} }
// Action Icons // Dropdown button in mini pipeline graph
.ci-action-icon-container .ci-action-icon-wrapper { .mini-pipeline-graph-dropdown-toggle {
i { border-radius: 100px;
color: $border-color; background-color: $white-light;
border-radius: 100%; border-width: 1px;
border: 1px solid $border-color; border-style: solid;
padding: 5px 6px; width: 22px;
font-size: 13px; height: 22px;
background: $white-light; margin: 0;
height: 30px; padding: 0;
width: 30px; transition: all 0.2s linear;
&::before {
position: relative; position: relative;
top: 3px;
left: 3px; > .fa.fa-caret-down {
position: absolute;
left: 20px;
top: 5px;
display: inline-block;
visibility: hidden;
opacity: 0;
color: inherit;
font-size: 12px;
transition: visibility 0.1s, opacity 0.1s linear;
} }
&:active,
&:focus,
&:hover { &:hover {
color: $gl-text-color; outline: none;
background-color: $stage-hover-bg; width: 35px;
border: 1px solid $stage-hover-bg;
}
}
.ci-play-icon { .fa.fa-caret-down {
padding: 5px 5px 5px 7px; visibility: visible;
opacity: 1;
} }
}
.dropdown-build {
color: $gl-text-color-secondary;
.build-content {
padding: 4px 7px 8px;
} }
.ci-action-icon-container { // Dropdown button animation in mini pipeline graph
padding: 0; &.ci-status-icon-success {
font-size: 11px; border-color: $gl-success;
float: right; color: $gl-success;
margin-top: 3px;
display: inline-block;
position: relative;
i { &:hover,
font-size: 11px; &:focus,
margin-top: 0; &:active {
background-color: rgba($gl-success, 0.1);
border-color: $gl-success;
} }
} }
.ci-action-icon-container { &.ci-status-icon-failed {
i { border-color: $gl-danger;
width: 24px; color: $gl-danger;
height: 24px;
&::before { &:hover,
top: 1px; &:focus,
left: 1px; &:active {
} background-color: rgba($gl-danger, 0.1);
border-color: $gl-danger;
} }
} }
.stage { &.ci-status-icon-pending,
max-width: 100px; &.ci-status-icon-success_with_warnings {
width: 100px; border-color: $gl-warning;
} color: $gl-warning;
.ci-status-icon svg { &:hover,
height: 18px; &:focus,
width: 18px; &:active {
background-color: rgba($gl-warning, 0.1);
border-color: $gl-warning;
} }
.ci-status-text {
max-width: 95px;
} }
}
/** &.ci-status-icon-running {
* Builds dropdown in mini pipeline border-color: $blue-normal;
*/ color: $blue-normal;
.mini-pipeline-graph {
.builds-dropdown {
background-color: transparent;
padding: 0;
color: $gl-text-color-secondary;
border: none;
margin: 0;
&:hover,
&:focus, &:focus,
&:hover { &:active {
outline: none; background-color: rgba($blue-normal, 0.1);
margin-right: -8px; border-color: $blue-normal;
}
}
.ci-status-icon { &.ci-status-icon-canceled,
width: 32px; &.ci-status-icon-disabled,
padding: 0 8px 0 0; &.ci-status-icon-not-found,
transition: width 0.1s cubic-bezier(0.25, 0, 1, 1); &.ci-status-icon-manual {
border-color: $gl-text-color;
color: $gl-text-color;
+ .dropdown-caret { &:hover,
visibility: visible; &:focus,
opacity: 1; &:active {
} background-color: rgba($gl-text-color, 0.1);
border-color: $gl-text-color;
} }
} }
&.ci-status-icon-created,
&.ci-status-icon-skipped {
border-color: $gray-darkest;
color: $gray-darkest;
&:hover,
&:focus, &:focus,
&:active { &:active {
.ci-status-icon-success { background-color: rgba($gray-darkest, 0.1);
background-color: rgba($gl-success, .1); border-color: $gray-darkest;
} }
.ci-status-icon-failed {
background-color: rgba($gl-danger, .1);
} }
}
.ci-status-icon-pending, // dropdown content for big and mini pipeline
.ci-status-icon-success_with_warnings { .big-pipeline-graph-dropdown-menu,
background-color: rgba($gl-warning, .1); .mini-pipeline-graph-dropdown-menu {
width: 195px;
max-width: 195px;
li {
padding: 2px 3px;
} }
.ci-status-icon-running { .scrollable-menu {
background-color: rgba($blue-normal, .1); max-height: 245px;
overflow: auto;
} }
.ci-status-icon-canceled, // Loading icon
.ci-status-icon-disabled, .builds-dropdown-loading {
.ci-status-icon-not-found { margin: 0 auto;
background-color: rgba($gl-text-color, .1); width: 20px;
} }
.ci-status-icon-created, // Action icon on the right
.ci-status-icon-skipped { a.ci-action-icon-wrapper {
background-color: rgba($gray-darkest, .1); color: $action-icon-color;
border: 1px solid $action-icon-color;
border-radius: 20px;
width: 22px;
height: 22px;
padding: 2px 0 0 5px;
cursor: pointer;
float: right;
margin: -26px 9px 0 0;
font-size: 12px;
background-color: $white-light;
&:hover,
&:focus {
text-decoration: none;
color: $gl-text-color;
background-color: $stage-hover-bg;
border: 1px solid transparent;
} }
} }
.mini-pipeline-graph-icon-container { // link to the build
.dropdown-caret { .mini-pipeline-graph-dropdown-item {
font-size: 11px; padding: 3px 7px 4px;
position: absolute; clear: both;
top: 6px; font-weight: normal;
left: 20px; line-height: 1.428571429;
margin-right: -6px; white-space: nowrap;
z-index: 2; margin: 0 5px;
visibility: hidden; border-radius: 3px;
opacity: 0;
transition: visibility 0.1s, opacity 0.1s linear; // build name
.ci-build-text {
font-weight: 200;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 90px;
color: $gl-text-color-secondary;
margin-left: 2px;
display: inline-block;
top: 1px;
vertical-align: text-bottom;
position: relative;
} }
// status icon on the left
.ci-status-icon {
top: 3px;
position: relative;
> svg {
overflow: visible;
width: 18px;
height: 18px;
} }
} }
.dropdown-build .build-content { &:hover,
padding: 3px 7px 7px; &:focus {
outline: none;
text-decoration: none;
color: $gl-text-color;
background-color: $stage-hover-bg;
} }
.builds-dropdown-loading {
margin: 10px auto;
width: 18px;
} }
}
.grouped-pipeline-dropdown { // Dropdown in the big pipeline graph
right: -172px; .big-pipeline-graph-dropdown-menu {
top: 23px; width: 195px;
min-height: 50px; min-width: 195px;
left: auto;
right: -195px;
top: -4px;
box-shadow: 0 1px 5px $black-transparent;
a { .mini-pipeline-graph-dropdown-item {
color: $gl-text-color-secondary; .ci-status-icon {
top: -1px;
} }
} }
}
/**
* Top arrow in the dropdown in the mini pipeline graph
*/
.mini-pipeline-graph-dropdown-menu {
.arrow-up { .arrow-up {
&::before, &::before,
&::after { &::after {
...@@ -898,31 +907,8 @@ ...@@ -898,31 +907,8 @@
} }
/** /**
* Icons in mini pipeline graph * Terminal
*/ */
.mini-pipeline-graph-icon-container .ci-status-icon {
display: inline-block;
border: 1px solid;
border-radius: 22px;
margin-right: 1px;
width: 22px;
height: 22px;
position: relative;
z-index: 2;
transition: all 0.1s cubic-bezier(0.25, 0, 1, 1);
svg {
top: -1px;
left: -1px;
}
}
.stage-cell .mini-pipeline-graph-icon-container .ci-status-icon svg {
width: 22px;
height: 22px;
}
.terminal-icon { .terminal-icon {
margin-left: 3px; margin-left: 3px;
} }
......
-# Renders the content of each li in the dropdown
- subject = local_assigns.fetch(:subject)
- status = subject.detailed_status(current_user)
- klass = "ci-status-icon ci-status-icon-#{status.group}"
- tooltip = "#{subject.name} - #{status.label}"
- if status.has_details?
= link_to status.details_path, class: 'mini-pipeline-graph-dropdown-item', data: { toggle: 'tooltip', title: tooltip } do
%span{ class: klass }= custom_icon(status.icon)
%span.ci-build-text= subject.name
- else
.mini-pipeline-graph-dropdown-item{ data: { toggle: 'tooltip', title: tooltip } }
%span{ class: klass }= custom_icon(status.icon)
%span.ci-build-text= subject.name
- if status.has_action?
= link_to status.action_path, class: 'ci-action-icon-wrapper js-ci-action-icon', method: status.action_method, data: { toggle: 'tooltip', title: status.action_title } do
= icon(status.action_icon, class: status.action_class)
...@@ -47,22 +47,19 @@ ...@@ -47,22 +47,19 @@
- icon_status = "#{detailed_status.icon}_borderless" - icon_status = "#{detailed_status.icon}_borderless"
- status_klass = "ci-status-icon ci-status-icon-#{detailed_status.group}" - status_klass = "ci-status-icon ci-status-icon-#{detailed_status.group}"
.stage-container.mini-pipeline-graph .stage-container.dropdown.js-mini-pipeline-graph
.dropdown.inline.build-content %button.mini-pipeline-graph-dropdown-toggle.has-tooltip.js-builds-dropdown-button{ class: "ci-status-icon-#{detailed_status.group}", type: 'button', data: { toggle: 'dropdown', title: "#{stage.name}: #{detailed_status.label}", placement: 'top', "stage-endpoint" => stage_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline, stage: stage.name) } }
%button.has-tooltip.builds-dropdown.js-builds-dropdown-button{ type: 'button', data: { toggle: 'dropdown', title: "#{stage.name}: #{detailed_status.label}", placement: 'top', "stage-endpoint" => stage_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline, stage: stage.name) } } = custom_icon(icon_status)
%span.has-tooltip{ class: status_klass } = icon('caret-down')
%span.mini-pipeline-graph-icon-container
%span{ class: status_klass }= custom_icon(icon_status)
= icon('caret-down', class: 'dropdown-caret')
.js-builds-dropdown-container %ul.dropdown-menu.mini-pipeline-graph-dropdown-menu.js-builds-dropdown-container
.dropdown-menu.grouped-pipeline-dropdown
.arrow-up .arrow-up
.js-builds-dropdown-list .js-builds-dropdown-list.scrollable-menu
.js-builds-dropdown-loading.builds-dropdown-loading.hidden .js-builds-dropdown-loading.builds-dropdown-loading.hidden
%span.fa.fa-spinner.fa-spin %span.fa.fa-spinner.fa-spin
%td %td
- if pipeline.duration - if pipeline.duration
%p.duration %p.duration
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
%div %div
.nothing-here-block No pipelines to show .nothing-here-block No pipelines to show
- else - else
.table-holder .table-holder.pipelines
%table.table.ci-table.js-pipeline-table %table.table.ci-table.js-pipeline-table
%thead %thead
%th.pipeline-status Status %th.pipeline-status Status
......
%ul - @stage.statuses.latest.each do |status|
- @stage.statuses.latest.each do |status| %li
%li.dropdown-build = render 'ci/status/dropdown_graph_badge', subject: status
= render 'ci/status/graph_badge', subject: status
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
%span.ci-status-text %span.ci-status-text
= name = name
%span.dropdown-counter-badge= subject.size %span.dropdown-counter-badge= subject.size
.dropdown-menu.grouped-pipeline-dropdown
%ul.dropdown-menu.big-pipeline-graph-dropdown-menu.js-grouped-pipeline-dropdown
.arrow .arrow
%ul .scrollable-menu
- subject.each do |status| - subject.each do |status|
%li.dropdown-build %li
= render 'ci/status/graph_badge', subject: status = render 'ci/status/dropdown_graph_badge', subject: status
---
title: Fixes and Improves CSS and HTML problems in mini pipeline graph and builds dropdown
merge_request: 8443
author:
...@@ -183,7 +183,7 @@ describe 'Pipelines', :feature, :js do ...@@ -183,7 +183,7 @@ describe 'Pipelines', :feature, :js do
it 'should render a mini pipeline graph' do it 'should render a mini pipeline graph' do
endpoint = stage_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline, stage: build.name) endpoint = stage_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline, stage: build.name)
expect(page).to have_selector('.mini-pipeline-graph') expect(page).to have_selector('.js-mini-pipeline-graph')
expect(page).to have_selector(".js-builds-dropdown-button[data-stage-endpoint='#{endpoint}']") expect(page).to have_selector(".js-builds-dropdown-button[data-stage-endpoint='#{endpoint}']")
end end
...@@ -201,7 +201,7 @@ describe 'Pipelines', :feature, :js do ...@@ -201,7 +201,7 @@ describe 'Pipelines', :feature, :js do
wait_for_ajax wait_for_ajax
find('a.ci-action-icon-container').trigger('click') find('a.js-ci-action-icon').trigger('click')
expect(page).not_to have_content('Cancel running') expect(page).not_to have_content('Cancel running')
end end
end end
......
...@@ -29,7 +29,7 @@ describe 'projects/pipelines/show' do ...@@ -29,7 +29,7 @@ describe 'projects/pipelines/show' do
render render
expect(rendered).to have_css('.js-pipeline-graph') expect(rendered).to have_css('.js-pipeline-graph')
expect(rendered).to have_css('.grouped-pipeline-dropdown') expect(rendered).to have_css('.js-grouped-pipeline-dropdown')
# stages # stages
expect(rendered).to have_text('Build') expect(rendered).to have_text('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