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
*/
$stage-hover-bg: #eaf3fc;
$stage-hover-border: #d1e7fc;
$action-icon-color: #d6d6d6;
......@@ -177,12 +177,13 @@
.stage-cell {
font-size: 0;
svg {
height: 18px;
width: 18px;
position: relative;
> .stage-container > button > svg {
height: 22px;
width: 22px;
position: absolute;
top: -1px;
left: -1px;
z-index: 2;
vertical-align: middle;
overflow: visible;
}
......@@ -200,7 +201,7 @@
content: '';
width: 8px;
position: absolute;
right: -7px;
right: -8px;
top: 10px;
border-bottom: 2px solid $border-color;
}
......@@ -338,7 +339,8 @@
white-space: nowrap;
transition: max-height 0.3s, padding 0.3s;
ul {
.stage-column-list,
.builds-container > ul {
padding: 0;
}
......@@ -470,6 +472,47 @@
white-space: normal;
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 {
background-color: transparent;
border: none;
......@@ -504,16 +547,6 @@
}
}
> .ci-action-icon-container {
position: absolute;
right: 5px;
top: 5px;
}
.ci-status-icon svg {
height: 20px;
width: 20px;
}
.arrow {
&::before,
......@@ -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 {
color: $border-color;
font-weight: 100;
......@@ -628,66 +641,6 @@
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 {
max-width: 110px;
white-space: nowrap;
......@@ -699,177 +652,233 @@
font-weight: 200;
}
// Action Icons
.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 {
// Dropdown button in mini pipeline graph
.mini-pipeline-graph-dropdown-toggle {
border-radius: 100px;
background-color: $white-light;
border-width: 1px;
border-style: solid;
width: 22px;
height: 22px;
margin: 0;
padding: 0;
transition: all 0.2s linear;
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 {
color: $gl-text-color;
background-color: $stage-hover-bg;
border: 1px solid $stage-hover-bg;
}
}
outline: none;
width: 35px;
.ci-play-icon {
padding: 5px 5px 5px 7px;
.fa.fa-caret-down {
visibility: visible;
opacity: 1;
}
}
.dropdown-build {
color: $gl-text-color-secondary;
.build-content {
padding: 4px 7px 8px;
}
.ci-action-icon-container {
padding: 0;
font-size: 11px;
float: right;
margin-top: 3px;
display: inline-block;
position: relative;
// Dropdown button animation in mini pipeline graph
&.ci-status-icon-success {
border-color: $gl-success;
color: $gl-success;
i {
font-size: 11px;
margin-top: 0;
&:hover,
&:focus,
&:active {
background-color: rgba($gl-success, 0.1);
border-color: $gl-success;
}
}
.ci-action-icon-container {
i {
width: 24px;
height: 24px;
&.ci-status-icon-failed {
border-color: $gl-danger;
color: $gl-danger;
&::before {
top: 1px;
left: 1px;
}
&:hover,
&:focus,
&:active {
background-color: rgba($gl-danger, 0.1);
border-color: $gl-danger;
}
}
.stage {
max-width: 100px;
width: 100px;
}
&.ci-status-icon-pending,
&.ci-status-icon-success_with_warnings {
border-color: $gl-warning;
color: $gl-warning;
.ci-status-icon svg {
height: 18px;
width: 18px;
&:hover,
&:focus,
&:active {
background-color: rgba($gl-warning, 0.1);
border-color: $gl-warning;
}
.ci-status-text {
max-width: 95px;
}
}
/**
* Builds dropdown in mini pipeline
*/
.mini-pipeline-graph {
.builds-dropdown {
background-color: transparent;
padding: 0;
color: $gl-text-color-secondary;
border: none;
margin: 0;
&.ci-status-icon-running {
border-color: $blue-normal;
color: $blue-normal;
&:hover,
&:focus,
&:hover {
outline: none;
margin-right: -8px;
&:active {
background-color: rgba($blue-normal, 0.1);
border-color: $blue-normal;
}
}
.ci-status-icon {
width: 32px;
padding: 0 8px 0 0;
transition: width 0.1s cubic-bezier(0.25, 0, 1, 1);
&.ci-status-icon-canceled,
&.ci-status-icon-disabled,
&.ci-status-icon-not-found,
&.ci-status-icon-manual {
border-color: $gl-text-color;
color: $gl-text-color;
+ .dropdown-caret {
visibility: visible;
opacity: 1;
}
&:hover,
&:focus,
&: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,
&:active {
.ci-status-icon-success {
background-color: rgba($gl-success, .1);
background-color: rgba($gray-darkest, 0.1);
border-color: $gray-darkest;
}
.ci-status-icon-failed {
background-color: rgba($gl-danger, .1);
}
}
.ci-status-icon-pending,
.ci-status-icon-success_with_warnings {
background-color: rgba($gl-warning, .1);
// dropdown content for big and mini pipeline
.big-pipeline-graph-dropdown-menu,
.mini-pipeline-graph-dropdown-menu {
width: 195px;
max-width: 195px;
li {
padding: 2px 3px;
}
.ci-status-icon-running {
background-color: rgba($blue-normal, .1);
.scrollable-menu {
max-height: 245px;
overflow: auto;
}
.ci-status-icon-canceled,
.ci-status-icon-disabled,
.ci-status-icon-not-found {
background-color: rgba($gl-text-color, .1);
// Loading icon
.builds-dropdown-loading {
margin: 0 auto;
width: 20px;
}
.ci-status-icon-created,
.ci-status-icon-skipped {
background-color: rgba($gray-darkest, .1);
// Action icon on the right
a.ci-action-icon-wrapper {
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 {
.dropdown-caret {
font-size: 11px;
position: absolute;
top: 6px;
left: 20px;
margin-right: -6px;
z-index: 2;
visibility: hidden;
opacity: 0;
transition: visibility 0.1s, opacity 0.1s linear;
// link to the build
.mini-pipeline-graph-dropdown-item {
padding: 3px 7px 4px;
clear: both;
font-weight: normal;
line-height: 1.428571429;
white-space: nowrap;
margin: 0 5px;
border-radius: 3px;
// 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 {
padding: 3px 7px 7px;
&:hover,
&: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 {
right: -172px;
top: 23px;
min-height: 50px;
// Dropdown in the big pipeline graph
.big-pipeline-graph-dropdown-menu {
width: 195px;
min-width: 195px;
left: auto;
right: -195px;
top: -4px;
box-shadow: 0 1px 5px $black-transparent;
a {
color: $gl-text-color-secondary;
.mini-pipeline-graph-dropdown-item {
.ci-status-icon {
top: -1px;
}
}
}
/**
* Top arrow in the dropdown in the mini pipeline graph
*/
.mini-pipeline-graph-dropdown-menu {
.arrow-up {
&::before,
&::after {
......@@ -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 {
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 @@
- icon_status = "#{detailed_status.icon}_borderless"
- status_klass = "ci-status-icon ci-status-icon-#{detailed_status.group}"
.stage-container.mini-pipeline-graph
.dropdown.inline.build-content
%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) } }
%span.has-tooltip{ class: status_klass }
%span.mini-pipeline-graph-icon-container
%span{ class: status_klass }= custom_icon(icon_status)
= icon('caret-down', class: 'dropdown-caret')
.stage-container.dropdown.js-mini-pipeline-graph
%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) } }
= custom_icon(icon_status)
= icon('caret-down')
.js-builds-dropdown-container
.dropdown-menu.grouped-pipeline-dropdown
%ul.dropdown-menu.mini-pipeline-graph-dropdown-menu.js-builds-dropdown-container
.arrow-up
.js-builds-dropdown-list
.js-builds-dropdown-list.scrollable-menu
.js-builds-dropdown-loading.builds-dropdown-loading.hidden
%span.fa.fa-spinner.fa-spin
%td
- if pipeline.duration
%p.duration
......
......@@ -3,7 +3,7 @@
%div
.nothing-here-block No pipelines to show
- else
.table-holder
.table-holder.pipelines
%table.table.ci-table.js-pipeline-table
%thead
%th.pipeline-status Status
......
%ul
- @stage.statuses.latest.each do |status|
%li.dropdown-build
= render 'ci/status/graph_badge', subject: status
- @stage.statuses.latest.each do |status|
%li
= render 'ci/status/dropdown_graph_badge', subject: status
......@@ -5,9 +5,10 @@
%span.ci-status-text
= name
%span.dropdown-counter-badge= subject.size
.dropdown-menu.grouped-pipeline-dropdown
%ul.dropdown-menu.big-pipeline-graph-dropdown-menu.js-grouped-pipeline-dropdown
.arrow
%ul
.scrollable-menu
- subject.each do |status|
%li.dropdown-build
= render 'ci/status/graph_badge', subject: status
%li
= 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
it 'should render a mini pipeline graph' do
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}']")
end
......@@ -201,7 +201,7 @@ describe 'Pipelines', :feature, :js do
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')
end
end
......
......@@ -29,7 +29,7 @@ describe 'projects/pipelines/show' do
render
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
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