diff options
author | Jacob Schatz <jschatz@gitlab.com> | 2016-08-17 20:47:41 +0000 |
---|---|---|
committer | Jacob Schatz <jschatz@gitlab.com> | 2016-08-17 20:47:41 +0000 |
commit | 30091edfb4d2d96d8b9a141619fc661d81356b41 (patch) | |
tree | 440a0a1543d503e6666466ed4e499fdeedb3b04c | |
parent | 2c6c23a430f56d9b9ec3d76576dffe71456befef (diff) | |
parent | cc7b3db5a2d9a04d976c3db95059e3163a01ec70 (diff) | |
download | gitlab-ce-30091edfb4d2d96d8b9a141619fc661d81356b41.tar.gz |
Merge branch '18516-collapse-build-tabs' into 'master'
Collapse build tabs that don't fit
## What does this MR do?
* Orders tests from `failed` > `pending` > `running` > `canceled` > `skipped` > `success`
* Put stages in one dropdown
* Once stage is selected, second dropdown shows all builds/jobs for that stage
## Are there points in the code the reviewer needs to double check?
## Why was this MR needed?
So many tests!
<img src="/uploads/d581b2670588121c6d64823f61906a1a/Screen_Shot_2016-08-01_at_9.52.50_AM.png" width="600px">
## What are the relevant issue numbers?
Closes #18516
Part of #19982
## Screenshots (if relevant)


See merge request !5595
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | app/assets/javascripts/build.js | 35 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/sidebar.scss | 4 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/builds.scss | 88 | ||||
-rw-r--r-- | app/views/projects/builds/_sidebar.html.haml | 197 | ||||
-rw-r--r-- | app/views/projects/builds/show.html.haml | 28 |
6 files changed, 234 insertions, 119 deletions
diff --git a/CHANGELOG b/CHANGELOG index 6000b3e9414..f528f8f633a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -106,6 +106,7 @@ v 8.11.0 (unreleased) - Make error pages responsive (Takuya Noguchi) - The performance of the project dropdown used for moving issues has been improved - Fix skip_repo parameter being ignored when destroying a namespace + - Add all builds into stage/job dropdowns on builds page - Change requests_profiles resource constraint to catch virtually any file - Bump gitlab_git to lazy load compare commits - Reduce number of queries made for merge_requests/:id/diffs diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 3d9b824d406..0d7d29bb0d0 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -6,19 +6,26 @@ Build.state = null; - function Build(page_url, build_url, build_status, state1) { - this.page_url = page_url; - this.build_url = build_url; - this.build_status = build_status; - this.state = state1; + function Build(options) { + this.page_url = options.page_url; + this.build_url = options.build_url; + this.build_status = options.build_status; + this.state = options.state1; + this.build_stage = options.build_stage; this.hideSidebar = bind(this.hideSidebar, this); this.toggleSidebar = bind(this.toggleSidebar, this); + this.updateDropdown = bind(this.updateDropdown, this); clearInterval(Build.interval); this.bp = Breakpoints.get(); - this.hideSidebar(); $('.js-build-sidebar').niceScroll(); + + this.populateJobs(this.build_stage); + this.updateStageDropdownText(this.build_stage); + this.hideSidebar(); + $(document).off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar); $(window).off('resize.build').on('resize.build', this.hideSidebar); + $(document).off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown); this.updateArtifactRemoveDate(); if ($('#build-trace').length) { this.getInitialBuildTrace(); @@ -132,6 +139,22 @@ } }; + Build.prototype.populateJobs = function(stage) { + $('.build-job').hide(); + $('.build-job[data-stage="' + stage + '"]').show(); + }; + + Build.prototype.updateStageDropdownText = function(stage) { + $('.stage-selection').text(stage); + }; + + Build.prototype.updateDropdown = function(e) { + e.preventDefault(); + var stage = e.currentTarget.text; + this.updateStageDropdownText(stage); + this.populateJobs(stage); + }; + return Build; })(); diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss index 3fa4a22258d..015fe3debf9 100644 --- a/app/assets/stylesheets/framework/sidebar.scss +++ b/app/assets/stylesheets/framework/sidebar.scss @@ -222,3 +222,7 @@ header.header-pinned-nav { padding-right: $sidebar_collapsed_width; } } + +.right-sidebar { + border-left: 1px solid $border-color; +} diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index e26f8f7080d..81fce55853c 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -53,14 +53,6 @@ left: 70px; } } - - .nav-links { - svg { - position: relative; - top: 2px; - margin-right: 3px; - } - } } .build-header { @@ -108,24 +100,98 @@ } .right-sidebar.build-sidebar { - padding-top: $gl-padding; - padding-bottom: $gl-padding; + padding: $gl-padding 0; &.right-sidebar-collapsed { display: none; } + .blocks-container { + padding: $gl-padding; + } + .block { width: 100%; } .build-sidebar-header { - padding-top: 0; + padding: 0 $gl-padding $gl-padding; .gutter-toggle { margin-top: 0; } } + + .stage-item { + cursor: pointer; + + &:hover { + color: $gl-text-color; + } + } + + .build-dropdown { + padding: 0 $gl-padding; + + .dropdown-menu-toggle { + margin-top: 8px; + } + + .dropdown-menu { + right: $gl-padding; + left: $gl-padding; + width: auto; + } + } + + .builds-container { + margin-top: $gl-padding; + background-color: $white-light; + border-top: 1px solid $border-color; + border-bottom: 1px solid $border-color; + max-height: 300px; + overflow: scroll; + + svg { + position: relative; + top: 2px; + margin-right: 3px; + height: 13px; + } + + a { + display: block; + padding: $gl-padding 10px $gl-padding 40px; + width: 270px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + &:hover { + background-color: $row-hover; + color: $gl-text-color; + } + } + + .build-job { + position: relative; + + .fa { + position: absolute; + left: 15px; + top: 20px; + display: none; + } + + &.active { + font-weight: bold; + + .fa { + display: block; + } + } + } + } } .build-detail-row { diff --git a/app/views/projects/builds/_sidebar.html.haml b/app/views/projects/builds/_sidebar.html.haml index a8bc53c2849..5b0b58e087b 100644 --- a/app/views/projects/builds/_sidebar.html.haml +++ b/app/views/projects/builds/_sidebar.html.haml @@ -11,98 +11,133 @@ %p.build-detail-row #{@build.coverage}% - - if can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?) - .block{ class: ("block-first" if !@build.coverage) } - .title - Build artifacts - - if @build.artifacts_expired? - %p.build-detail-row - The artifacts were removed - #{time_ago_with_tooltip(@build.artifacts_expire_at)} - - elsif @build.artifacts_expire_at - %p.build-detail-row - The artifacts will be removed in - %span.js-artifacts-remove= @build.artifacts_expire_at + - builds = @build.pipeline.builds.latest.to_a + - statuses = ["failed", "pending", "running", "canceled", "success", "skipped"] + - if builds.size > 1 + .dropdown.build-dropdown + .build-light-text Stage + %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} + %span.stage-selection More + = icon('caret-down') + %ul.dropdown-menu + - builds.map(&:stage).uniq.each do |stage| + %li + %a.stage-item= stage - - if @build.artifacts? - .btn-group.btn-group-justified{ role: :group } - - if @build.artifacts_expire_at - = link_to keep_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default', method: :post do - Keep + .builds-container + - statuses.each do |build_status| + - builds.select{|build| build.status == build_status}.each do |build| + .build-job{class: ('active' if build == @build), data: {stage: build.stage}} + = link_to namespace_project_build_path(@project.namespace, @project, build) do + = icon('check') + = ci_icon_for_status(build.status) + %span + - if build.name + = build.name + - else + = build.id - = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do - Download + - if @build.retried? + %li.active + %a + Build ##{@build.id} + · + %i.fa.fa-warning + This build was retried. - - if @build.artifacts_metadata? - = link_to browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do - Browse + .blocks-container + - if can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?) + .block{ class: ("block-first" if !@build.coverage) } + .title + Build artifacts + - if @build.artifacts_expired? + %p.build-detail-row + The artifacts were removed + #{time_ago_with_tooltip(@build.artifacts_expire_at)} + - elsif @build.artifacts_expire_at + %p.build-detail-row + The artifacts will be removed in + %span.js-artifacts-remove= @build.artifacts_expire_at - .block{ class: ("block-first" if !@build.coverage && !(can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?))) } - .title - Build details - - if can?(current_user, :update_build, @build) && @build.retryable? - = link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'pull-right', method: :post - - if @build.merge_request - %p.build-detail-row - %span.build-light-text Merge Request: - = link_to "#{@build.merge_request.to_reference}", merge_request_path(@build.merge_request) - - if @build.duration - %p.build-detail-row - %span.build-light-text Duration: - = time_interval_in_words(@build.duration) - - if @build.finished_at - %p.build-detail-row - %span.build-light-text Finished: - #{time_ago_with_tooltip(@build.finished_at)} - - if @build.erased_at - %p.build-detail-row - %span.build-light-text Erased: - #{time_ago_with_tooltip(@build.erased_at)} - %p.build-detail-row - %span.build-light-text Runner: - - if @build.runner && current_user && current_user.admin - = link_to "##{@build.runner.id}", admin_runner_path(@build.runner.id) - - elsif @build.runner - \##{@build.runner.id} - .btn-group.btn-group-justified{ role: :group } - - if @build.has_trace? - = link_to 'Raw', raw_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' - - if @build.active? - = link_to "Cancel", cancel_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default', method: :post - - if can?(current_user, :update_build, @project) && @build.erasable? - = link_to erase_namespace_project_build_path(@project.namespace, @project, @build), - class: "btn btn-sm btn-default", method: :post, - data: { confirm: "Are you sure you want to erase this build?" } do - Erase + - if @build.artifacts? + .btn-group.btn-group-justified{ role: :group } + - if @build.artifacts_expire_at + = link_to keep_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default', method: :post do + Keep + + = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do + Download - - if @build.trigger_request - .build-widget - %h4.title - Trigger + - if @build.artifacts_metadata? + = link_to browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do + Browse - %p - %span.build-light-text Token: - #{@build.trigger_request.trigger.short_token} + .block{ class: ("block-first" if !@build.coverage && !(can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?))) } + .title + Build details + - if can?(current_user, :update_build, @build) && @build.retryable? + = link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'pull-right', method: :post + - if @build.merge_request + %p.build-detail-row + %span.build-light-text Merge Request: + = link_to "#{@build.merge_request.to_reference}", merge_request_path(@build.merge_request) + - if @build.duration + %p.build-detail-row + %span.build-light-text Duration: + = time_interval_in_words(@build.duration) + - if @build.finished_at + %p.build-detail-row + %span.build-light-text Finished: + #{time_ago_with_tooltip(@build.finished_at)} + - if @build.erased_at + %p.build-detail-row + %span.build-light-text Erased: + #{time_ago_with_tooltip(@build.erased_at)} + %p.build-detail-row + %span.build-light-text Runner: + - if @build.runner && current_user && current_user.admin + = link_to "##{@build.runner.id}", admin_runner_path(@build.runner.id) + - elsif @build.runner + \##{@build.runner.id} + .btn-group.btn-group-justified{ role: :group } + - if @build.has_trace? + = link_to 'Raw', raw_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' + - if @build.active? + = link_to "Cancel", cancel_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default', method: :post + - if can?(current_user, :update_build, @project) && @build.erasable? + = link_to erase_namespace_project_build_path(@project.namespace, @project, @build), + class: "btn btn-sm btn-default", method: :post, + data: { confirm: "Are you sure you want to erase this build?" } do + Erase + + - if @build.trigger_request + .build-widget + %h4.title + Trigger - - if @build.trigger_request.variables %p - %span.build-light-text Variables: + %span.build-light-text Token: + #{@build.trigger_request.trigger.short_token} + - if @build.trigger_request.variables + %p + %span.build-light-text Variables: - - @build.trigger_request.variables.each do |key, value| - %code - #{key}=#{value} - .block - .title - Commit title - %p.build-light-text.append-bottom-0 - #{@build.pipeline.git_commit_title} + - @build.trigger_request.variables.each do |key, value| + %code + #{key}=#{value} - - if @build.tags.any? .block .title - Tags - - @build.tag_list.each do |tag| - %span.label.label-primary - = tag + Commit title + %p.build-light-text.append-bottom-0 + #{@build.pipeline.git_commit_title} + + - if @build.tags.any? + .block + .title + Tags + - @build.tag_list.each do |tag| + %span.label.label-primary + = tag diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 4421f3b9562..e4d41288aa6 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -5,26 +5,6 @@ .build-page = render "header" - - builds = @build.pipeline.builds.latest.to_a - - if builds.size > 1 - %ul.nav-links.no-top.no-bottom - - builds.each do |build| - %li{class: ('active' if build == @build) } - = link_to namespace_project_build_path(@project.namespace, @project, build) do - = ci_icon_for_status(build.status) - %span - - if build.name - = build.name - - else - = build.id - - - if @build.retried? - %li.active - %a - Build ##{@build.id} - · - %i.fa.fa-warning - This build was retried. - if @build.stuck? - unless @build.any_runners_online? .bs-callout.bs-callout-warning @@ -67,4 +47,10 @@ = render "sidebar" :javascript - new Build("#{namespace_project_build_url(@project.namespace, @project, @build)}", "#{namespace_project_build_url(@project.namespace, @project, @build, :json)}", "#{@build.status}", "#{trace_with_state[:state]}") + new Build({ + page_url: "#{namespace_project_build_url(@project.namespace, @project, @build)}", + build_url: "#{namespace_project_build_url(@project.namespace, @project, @build, :json)}", + build_status: "#{@build.status}", + build_stage: "#{@build.stage}", + state1: "#{trace_with_state[:state]}" + }) |