From 84ee2857975ed2da991604d9f93a151b66032991 Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Tue, 9 Aug 2016 13:24:16 -0500 Subject: Add delimiter to project stars and forks count --- CHANGELOG | 1 + app/views/shared/projects/_project.html.haml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7bfeff2a4ec..eb43b656f11 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. v 8.11.0 (unreleased) - Fix don't pass a local variable called `i` to a partial. !20510 (herminiotorres) + - Add delimiter to project stars and forks count (ClemMakesApps) - Fix rename `add_users_into_project` and `projects_ids`. !20512 (herminiotorres) - Fix the title of the toggle dropdown button. !5515 (herminiotorres) - Improve diff performance by eliminating redundant checks for text blobs diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml index b8b66d08db8..2cf958e9879 100644 --- a/app/views/shared/projects/_project.html.haml +++ b/app/views/shared/projects/_project.html.haml @@ -18,11 +18,11 @@ - if forks %span = icon('code-fork') - = project.forks_count + = number_with_delimiter(project.forks_count) - if stars %span = icon('star') - = project.star_count + = number_with_delimiter(project.star_count) %span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(project)} = visibility_level_icon(project.visibility_level, fw: false) -- cgit v1.2.1 From 3b4fb0bbdc13f5b52d1a4d30128d0d2d99b97e72 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 8 Aug 2016 16:26:33 -0500 Subject: Add build data to top of pipeline page --- app/assets/stylesheets/pages/pipelines.scss | 6 ++++++ app/views/projects/commit/_pipeline.html.haml | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 21919fe4d73..5bc8c3a7e6c 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -229,3 +229,9 @@ box-shadow: none; } } + +// Pipeline visualization +.stage-column { + display: inline-block; + vertical-align: top; +} diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 540689f4a61..a52bfa0ea55 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,4 +1,16 @@ .row-content-block.build-content.middle-block + .pipeline-visualization + - pipeline.statuses.stages.each do |stage| + - statuses = pipeline.statuses.where(stage: stage) + .stage-column + %strong + %a{name: stage} + - if stage + = stage.titleize + - statuses.each do |status| + %div= status.name + + .pull-right - if can?(current_user, :update_pipeline, pipeline.project) - if pipeline.builds.latest.failed.any?(&:retryable?) -- cgit v1.2.1 From dcb7d4148efe86ba07e9a00cb43818846d61f9d0 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 8 Aug 2016 17:42:28 -0500 Subject: Connect top level tests to each other --- app/assets/stylesheets/pages/pipelines.scss | 50 +++++++++++++++++++++++++++ app/views/projects/commit/_pipeline.html.haml | 44 +++++++++++++---------- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 5bc8c3a7e6c..e79c7e59720 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -231,7 +231,57 @@ } // Pipeline visualization + +.pipeline-visualization { + position: relative; +} + .stage-column { display: inline-block; vertical-align: top; + margin-right: 40px; + + .stage-name { + margin-bottom: 15px; + font-weight: bold; + } + + .builds-container { + + } + + .build { + border: 1px solid $border-color; + position: relative; + padding: 6px 10px; + border-radius: 30px; + width: 150px; + // TODO truncate text within .build div; not on build div itself + // white-space: nowrap; + // overflow: hidden; + // text-overflow: ellipsis; + margin-bottom: 10px; + + svg { + position: relative; + top: 2px; + margin-right: 5px; + } + + &:first-child { + &::after, &::before { + content: ''; + position: absolute; + top: 50%; + right: -44px; + border-top: 1px solid $border-color; + width: 44px; + height: 1px; + } + } + &:first-child::before, &:last-child::after{ + border: 0 none; + } + + } } diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index a52bfa0ea55..72259cd0756 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,16 +1,22 @@ -.row-content-block.build-content.middle-block +.row-content-block.white + .pipeline-visualization - pipeline.statuses.stages.each do |stage| - statuses = pipeline.statuses.where(stage: stage) + - status = statuses.latest.status .stage-column - %strong + .stage-name %a{name: stage} - if stage = stage.titleize - - statuses.each do |status| - %div= status.name - + .builds-container + - statuses.each do |build| + .build + %span{class: "ci-status-link ci-status-icon-#{status}"} + = ci_icon_for_status(status) + = build.name +.row-content-block.build-content.middle-block .pull-right - if can?(current_user, :update_pipeline, pipeline.project) - if pipeline.builds.latest.failed.any?(&:retryable?) @@ -46,17 +52,17 @@ - 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.builds.pipeline - %thead - %tr - %th Status - %th Build ID - %th Name - %th - - if pipeline.project.build_coverage_enabled? - %th Coverage - %th - - pipeline.statuses.stages.each do |stage| - = render 'projects/commit/ci_stage', stage: stage, statuses: pipeline.statuses.where(stage: stage) +-# +-# .table-holder.pipeline-holder +-# %table.table.builds.pipeline +-# %thead +-# %tr +-# %th Status +-# %th Build ID +-# %th Name +-# %th +-# - if pipeline.project.build_coverage_enabled? +-# %th Coverage +-# %th +-# - pipeline.statuses.stages.each do |stage| +-# = render 'projects/commit/ci_stage', stage: stage, statuses: pipeline.statuses.where(stage: stage) -- cgit v1.2.1 From 83c1ce74e01dcf95ac8f545d7584259615e8834f Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 14:26:25 -0500 Subject: Connect all builds in visual pipeline --- app/assets/stylesheets/pages/pipelines.scss | 81 ++++++++++++++++++++++++--- app/views/projects/commit/_pipeline.html.haml | 32 ++++++----- 2 files changed, 90 insertions(+), 23 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index e79c7e59720..fa422f4f3c5 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -234,6 +234,10 @@ .pipeline-visualization { position: relative; + + ul { + padding: 0; + } } .stage-column { @@ -241,15 +245,15 @@ vertical-align: top; margin-right: 40px; + li { + list-style: none; + } + .stage-name { margin-bottom: 15px; font-weight: bold; } - .builds-container { - - } - .build { border: 1px solid $border-color; position: relative; @@ -268,20 +272,81 @@ margin-right: 5px; } + // Connect first build in each stage with right horizontal line &:first-child { - &::after, &::before { + &::after { content: ''; position: absolute; top: 50%; right: -44px; - border-top: 1px solid $border-color; + border-top: 2px solid $border-color; width: 44px; height: 1px; } } - &:first-child::before, &:last-child::after{ - border: 0 none; + + // Connect each build (except for first) with curved lines + &:not(:first-child) { + &::after, &::before { + content: ''; + top: -47px; + position: absolute; + border-bottom: 2px solid $border-color; + width: 20px; + height: 65px; + } + + // Right connecting curves + &::after { + right: -21px; + border-right: 2px solid $border-color; + border-radius: 0 0 50px 0; + -webkit-border-radius: 0 0 50px 0; + } + + // Left connecting curves + &::before { + left: -21px; + border-left: 2px solid $border-color; + border-radius: 0 0 0 50px; + -webkit-border-radius: 0 0 0 50px; + } + } + + // Connect second build to first build with smaller curved line + &:nth-child(2) { + &::after, &::before { + height: 40px; + top: -26px; + } + } + } + + &:last-child { + .build { + // Remove right connecting horizontal line from first build in last stage + &:first-child { + &::after, &::before { + border: none; + } + } + // Remove right curved connectors from all builds in last stage + &:not(:first-child) { + &::after { + border: none; + } + } } + } + &:first-child { + .build { + // Remove left curved connectors from all builds in first stage + &:not(:first-child) { + &::before { + border: none; + } + } + } } } diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 72259cd0756..06a63839107 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,20 +1,22 @@ .row-content-block.white .pipeline-visualization - - pipeline.statuses.stages.each do |stage| - - statuses = pipeline.statuses.where(stage: stage) - - status = statuses.latest.status - .stage-column - .stage-name - %a{name: stage} - - if stage - = stage.titleize - .builds-container - - statuses.each do |build| - .build - %span{class: "ci-status-link ci-status-icon-#{status}"} - = ci_icon_for_status(status) - = build.name + %ul.stage-column-list + - pipeline.statuses.stages.each do |stage| + - statuses = pipeline.statuses.where(stage: stage) + - status = statuses.latest.status + %li.stage-column + .stage-name + %a{name: stage} + - if stage + = stage.titleize + .builds-container + %ul + - statuses.each do |build| + %li.build + %span{class: "ci-status-link ci-status-icon-#{status}"} + = ci_icon_for_status(status) + = build.name .row-content-block.build-content.middle-block .pull-right @@ -52,7 +54,7 @@ - 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.builds.pipeline -# %thead -- cgit v1.2.1 From a76864cc92241ef9b759fbe63282a45dea7d5e03 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 15:00:09 -0500 Subject: Add min width and horizontally scroll pipeline graph when overflow --- app/assets/stylesheets/pages/pipelines.scss | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index fa422f4f3c5..a9ffda00278 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -234,16 +234,22 @@ .pipeline-visualization { position: relative; + width: 100%; + overflow: auto; ul { padding: 0; } } +.stage-column-list { + min-width: 1220px; +} + .stage-column { display: inline-block; vertical-align: top; - margin-right: 40px; + margin-right: 50px; li { list-style: none; @@ -278,9 +284,9 @@ content: ''; position: absolute; top: 50%; - right: -44px; + right: -54px; border-top: 2px solid $border-color; - width: 44px; + width: 54px; height: 1px; } } @@ -298,7 +304,7 @@ // Right connecting curves &::after { - right: -21px; + right: -20px; border-right: 2px solid $border-color; border-radius: 0 0 50px 0; -webkit-border-radius: 0 0 50px 0; @@ -306,7 +312,7 @@ // Left connecting curves &::before { - left: -21px; + left: -20px; border-left: 2px solid $border-color; border-radius: 0 0 0 50px; -webkit-border-radius: 0 0 0 50px; @@ -316,9 +322,14 @@ // Connect second build to first build with smaller curved line &:nth-child(2) { &::after, &::before { - height: 40px; + height: 45px; top: -26px; } + &::after { + // border-left: 2px solid $border-color; + border-top-right-radius: -50px; + -webkit-border-top-right-radius: -50px; + } } } -- cgit v1.2.1 From aeacadb3e32156a33060fea81243a4cef8fc1c3e Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 15:08:04 -0500 Subject: Truncate build and stage names --- CHANGELOG | 1 + app/assets/stylesheets/pages/pipelines.scss | 15 ++++++++---- app/views/projects/commit/_pipeline.html.haml | 33 ++++++++++++++------------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 58751448d4a..31ed0e01095 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -81,6 +81,7 @@ v 8.11.0 (unreleased) - Speed up and reduce memory usage of Commit#repo_changes, Repository#expire_avatar_cache and IrkerWorker - Add unfold links for Side-by-Side view. !5415 (Tim Masliuchenko) - Adds support for pending invitation project members importing projects + - Add pipeline visualization/graph on pipeline page - Update devise initializer to turn on changed password notification emails. !5648 (tombell) - Avoid to show the original password field when password is automatically set. !5712 (duduribeiro) - Fix importing GitLab projects with an invalid MR source project diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index a9ffda00278..49225d7d0d4 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -258,6 +258,10 @@ .stage-name { margin-bottom: 15px; font-weight: bold; + width: 150px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .build { @@ -266,12 +270,15 @@ padding: 6px 10px; border-radius: 30px; width: 150px; - // TODO truncate text within .build div; not on build div itself - // white-space: nowrap; - // overflow: hidden; - // text-overflow: ellipsis; margin-bottom: 10px; + .build-content { + width: 130px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + svg { position: relative; top: 2px; diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 06a63839107..2edf660db71 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -14,9 +14,10 @@ %ul - statuses.each do |build| %li.build - %span{class: "ci-status-link ci-status-icon-#{status}"} - = ci_icon_for_status(status) - = build.name + .build-content + %span{class: "ci-status-link ci-status-icon-#{status}"} + = ci_icon_for_status(status) + = build.name .row-content-block.build-content.middle-block .pull-right @@ -55,16 +56,16 @@ .bs-callout.bs-callout-warning \.gitlab-ci.yml not found in this commit --# .table-holder.pipeline-holder --# %table.table.builds.pipeline --# %thead --# %tr --# %th Status --# %th Build ID --# %th Name --# %th --# - if pipeline.project.build_coverage_enabled? --# %th Coverage --# %th --# - pipeline.statuses.stages.each do |stage| --# = render 'projects/commit/ci_stage', stage: stage, statuses: pipeline.statuses.where(stage: stage) +.table-holder.pipeline-holder + %table.table.builds.pipeline + %thead + %tr + %th Status + %th Build ID + %th Name + %th + - if pipeline.project.build_coverage_enabled? + %th Coverage + %th + - pipeline.statuses.stages.each do |stage| + = render 'projects/commit/ci_stage', stage: stage, statuses: pipeline.statuses.where(stage: stage) -- cgit v1.2.1 From 94ca1e3edea8fa8e70e828cc4127e0cb8ec8a9d1 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 15:39:01 -0500 Subject: Fix graph scrolling bug --- app/assets/stylesheets/pages/pipelines.scss | 13 +++++++------ app/views/projects/commit/_pipeline.html.haml | 5 ++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 49225d7d0d4..01bd131940a 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -232,20 +232,21 @@ // Pipeline visualization -.pipeline-visualization { - position: relative; +.pipeline-graph { width: 100%; overflow: auto; + white-space: nowrap; +} + +.pipeline-visualization { + position: relative; + min-width: 1220px; ul { padding: 0; } } -.stage-column-list { - min-width: 1220px; -} - .stage-column { display: inline-block; vertical-align: top; diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 2edf660db71..0c006656d1d 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,5 +1,4 @@ -.row-content-block.white - +.row-content-block.build-content.middle-block.pipeline-graph .pipeline-visualization %ul.stage-column-list - pipeline.statuses.stages.each do |stage| @@ -19,7 +18,7 @@ = ci_icon_for_status(status) = build.name -.row-content-block.build-content.middle-block +.row-content-block.build-content.middle-block.pipeline-graph .pull-right - if can?(current_user, :update_pipeline, pipeline.project) - if pipeline.builds.latest.failed.any?(&:retryable?) -- cgit v1.2.1 From ef767268645e8f60b7111eb9f6b6c3aa1b615661 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 16:15:09 -0500 Subject: Fix scss lint error --- app/assets/stylesheets/pages/pipelines.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 01bd131940a..ad256e2a728 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -314,8 +314,8 @@ &::after { right: -20px; border-right: 2px solid $border-color; - border-radius: 0 0 50px 0; - -webkit-border-radius: 0 0 50px 0; + border-radius: 0 0 50px; + -webkit-border-radius: 0 0 50px; } // Left connecting curves -- cgit v1.2.1 From bbb019094b4b5999f96407b20a3c9da469dcf985 Mon Sep 17 00:00:00 2001 From: Paco Guzman Date: Thu, 11 Aug 2016 10:02:27 +0200 Subject: Fix merge request new view not changing code view rendering style --- CHANGELOG | 1 + app/controllers/projects/merge_requests_controller.rb | 2 ++ spec/features/merge_requests/create_new_mr_spec.rb | 19 ++++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 56ab89abaf9..504e1421002 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -75,6 +75,7 @@ v 8.11.0 (unreleased) - Speedup DiffNote#active? on discussions, preloading noteables and avoid touching git repository to return diff_refs when possible - Add commit stats in commit api. !5517 (dixpac) - Add CI configuration button on project page + - Fix merge request new view not changing code view rendering style - Make error pages responsive (Takuya Noguchi) - Fix skip_repo parameter being ignored when destroying a namespace - Change requests_profiles resource constraint to catch virtually any file diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 2cf6a2dd1b3..358c6ebe4ef 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -142,6 +142,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController end def new + apply_diff_view_cookie! + build_merge_request @noteable = @merge_request diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index e296078bad8..a5a3f8b8239 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -8,10 +8,11 @@ feature 'Create New Merge Request', feature: true, js: true do project.team << [user, :master] login_as user - visit namespace_project_merge_requests_path(project.namespace, project) end it 'generates a diff for an orphaned branch' do + visit namespace_project_merge_requests_path(project.namespace, project) + click_link 'New Merge Request' first('.js-source-branch').click @@ -40,4 +41,20 @@ feature 'Create New Merge Request', feature: true, js: true do expect(page).not_to have_content private_project.to_reference end end + + it 'allows to change the diff view' do + visit new_namespace_project_merge_request_path(project.namespace, project, merge_request: { target_branch: 'master', source_branch: 'fix' }) + + click_link 'Changes' + + expect(page.find_link('Inline')[:class]).to match(/\bactive\b/) + expect(page.find_link('Side-by-side')[:class]).not_to match(/\bactive\b/) + + click_link 'Side-by-side' + + click_link 'Changes' + + expect(page.find_link('Inline')[:class]).not_to match(/\bactive\b/) + expect(page.find_link('Side-by-side')[:class]).to match(/\bactive\b/) + end end -- cgit v1.2.1 From 59bfa0809822c3dd257748197223809922ab5f80 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Fri, 12 Aug 2016 22:54:32 +0100 Subject: Send notification emails when users are newly mentioned in issue edits --- app/mailers/emails/issues.rb | 5 ++++ app/services/issuable_base_service.rb | 3 +- app/services/issues/update_service.rb | 7 ++++- app/services/notification_service.rb | 24 +++++++++++++++- .../notify/new_mention_in_issue_email.html.haml | 9 ++++++ .../notify/new_mention_in_issue_email.text.erb | 7 +++++ spec/services/issues/update_service_spec.rb | 33 ++++++++++++++++++++++ spec/services/notification_service_spec.rb | 26 +++++++++++++++++ 8 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 app/views/notify/new_mention_in_issue_email.html.haml create mode 100644 app/views/notify/new_mention_in_issue_email.text.erb diff --git a/app/mailers/emails/issues.rb b/app/mailers/emails/issues.rb index 6f54c42146c..d64e48f774b 100644 --- a/app/mailers/emails/issues.rb +++ b/app/mailers/emails/issues.rb @@ -6,6 +6,11 @@ module Emails mail_new_thread(@issue, issue_thread_options(@issue.author_id, recipient_id)) end + def new_mention_in_issue_email(recipient_id, issue_id, updated_by_user_id) + setup_issue_mail(issue_id, recipient_id) + mail_answer_thread(@issue, issue_thread_options(updated_by_user_id, recipient_id)) + end + def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id, updated_by_user_id) setup_issue_mail(issue_id, recipient_id) diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 2d96efe1042..b0ea7c905f8 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -104,11 +104,12 @@ class IssuableBaseService < BaseService change_subscription(issuable) filter_params old_labels = issuable.labels.to_a + old_mentioned_users = issuable.mentioned_users.to_a if params.present? && update_issuable(issuable, params) issuable.reset_events_cache handle_common_system_notes(issuable, old_labels: old_labels) - handle_changes(issuable, old_labels: old_labels) + handle_changes(issuable, old_labels: old_labels, old_mentioned_users: old_mentioned_users) issuable.create_new_cross_references!(current_user) execute_hooks(issuable, 'update') end diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index c7d406cc331..a2111b3806b 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -4,7 +4,7 @@ module Issues update(issue) end - def handle_changes(issue, old_labels: []) + def handle_changes(issue, old_labels: [], old_mentioned_users: []) if has_changes?(issue, old_labels: old_labels) todo_service.mark_pending_todos_as_done(issue, current_user) end @@ -32,6 +32,11 @@ module Issues if added_labels.present? notification_service.relabeled_issue(issue, added_labels, current_user) end + + added_mentions = issue.mentioned_users - old_mentioned_users + if added_mentions.present? + notification_service.new_mentions_in_issue(issue, added_mentions, current_user) + end end def reopen_service diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index ab6e51209ee..73df572514f 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -35,6 +35,20 @@ class NotificationService new_resource_email(issue, issue.project, :new_issue_email) end + # When issue text is updated, we should send an email to: + # + # * newly mentioned project team members with notification level higher than Participating + # + def new_mentions_in_issue(issue, new_mentioned_users, current_user) + new_mentions_in_resource_email( + issue, + issue.project, + new_mentioned_users, + current_user, + :new_mention_in_issue_email + ) + end + # When we close an issue we should send an email to: # # * issue author if their notification level is not Disabled @@ -177,7 +191,7 @@ class NotificationService # build notify method like 'note_commit_email' notify_method = "note_#{note.noteable_type.underscore}_email".to_sym - + recipients.each do |recipient| mailer.send(notify_method, recipient.id, note.id).deliver_later end @@ -471,6 +485,14 @@ class NotificationService end end + def new_mentions_in_resource_email(target, project, new_mentioned_users, current_user, method) + recipients = build_recipients(target, project, current_user) & new_mentioned_users + + recipients.each do |recipient| + mailer.send(method, recipient.id, target.id, current_user.id).deliver_later + end + end + def close_resource_email(target, project, current_user, method) action = method == :merged_merge_request_email ? "merge" : "close" recipients = build_recipients(target, project, current_user, action: action) diff --git a/app/views/notify/new_mention_in_issue_email.html.haml b/app/views/notify/new_mention_in_issue_email.html.haml new file mode 100644 index 00000000000..f42b150c0d6 --- /dev/null +++ b/app/views/notify/new_mention_in_issue_email.html.haml @@ -0,0 +1,9 @@ +- if current_application_settings.email_author_in_body + %div + #{link_to @issue.author_name, user_url(@issue.author)} wrote: +-if @issue.description + = markdown(@issue.description, pipeline: :email, author: @issue.author) + +- if @issue.assignee_id.present? + %p + Assignee: #{@issue.assignee_name} diff --git a/app/views/notify/new_mention_in_issue_email.text.erb b/app/views/notify/new_mention_in_issue_email.text.erb new file mode 100644 index 00000000000..457e94b4800 --- /dev/null +++ b/app/views/notify/new_mention_in_issue_email.text.erb @@ -0,0 +1,7 @@ +You have been mentioned in an issue. + +Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> +Author: <%= @issue.author_name %> +Assignee: <%= @issue.assignee_name %> + +<%= @issue.description %> diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 088c3d48bf7..a5e375578ec 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -319,5 +319,38 @@ describe Issues::UpdateService, services: true do end end end + + context 'updated user mentions' do + let(:user4) { create(:user) } + before do + project.team << [user4, :developer] + end + + context "in title" do + before do + perform_enqueued_jobs { update_issue(title: user4.to_reference) } + end + + it "should email only the newly-mentioned user" do + should_not_email(user) + should_not_email(user2) + should_not_email(user3) + should_email(user4) + end + end + + context "in description" do + before do + perform_enqueued_jobs { update_issue(description: user4.to_reference) } + end + + it "should email only the newly-mentioned user" do + should_not_email(user) + should_not_email(user2) + should_not_email(user3) + should_email(user4) + end + end + end end end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 92b441c28ca..1935451ff12 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -399,6 +399,32 @@ describe NotificationService, services: true do end end + describe '#new_mentions_in_issue' do + def send_notifications(*new_mentions) + ActionMailer::Base.deliveries.clear + notification.new_mentions_in_issue(issue, new_mentions, @u_disabled) + end + + it "should not email anyone unless they are newly mentioned" do + send_notifications() + expect(ActionMailer::Base.deliveries).to eq [] + end + + it "should email new mentions with a watch level higher than participant" do + send_notifications(@u_watcher, @u_participant_mentioned) + + should_email(@u_watcher) + should_email(@u_participant_mentioned) + + expect(ActionMailer::Base.deliveries.count).to eq 2 + end + + it "should not email new mentions with a watch level equal to or less than participant" do + send_notifications(@u_participating, @u_mentioned) + expect(ActionMailer::Base.deliveries).to eq [] + end + end + describe '#reassigned_issue' do before do update_custom_notification(:reassign_issue, @u_guest_custom, project) -- cgit v1.2.1 From e6f519c4a7efa6a865c7e8d2a62ed5c3db12b453 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 15 Aug 2016 12:05:08 +0100 Subject: Fix a 'missing keyword' error introduced in the last commit --- app/services/merge_requests/update_service.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index 026a37997d4..0ad42b83fe2 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -16,7 +16,7 @@ module MergeRequests update(merge_request) end - def handle_changes(merge_request, old_labels: []) + def handle_changes(merge_request, old_labels: [], old_mentioned_users: []) if has_changes?(merge_request, old_labels: old_labels) todo_service.mark_pending_todos_as_done(merge_request, current_user) end @@ -55,6 +55,8 @@ module MergeRequests current_user ) end + + # TODO(nick): use old_mentioned_users to send notify for changed mentions end def reopen_service -- cgit v1.2.1 From b450aab8501076740cd7140b47488b9dfa5f58f9 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 15 Aug 2016 14:38:22 +0100 Subject: Remove superfluous parens on a method call --- spec/services/notification_service_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 1935451ff12..d61de6c15d1 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -406,7 +406,7 @@ describe NotificationService, services: true do end it "should not email anyone unless they are newly mentioned" do - send_notifications() + send_notifications expect(ActionMailer::Base.deliveries).to eq [] end -- cgit v1.2.1 From 6642ae4579d6ceed6b26014aee4a22adb39fc43c Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 15 Aug 2016 14:47:16 +0100 Subject: Add notifications for new user mentions in merge requests --- app/mailers/emails/merge_requests.rb | 5 ++++ app/services/merge_requests/update_service.rb | 9 +++++- app/services/notification_service.rb | 14 +++++++++ .../new_mention_in_merge_request_email.html.haml | 12 ++++++++ .../new_mention_in_merge_request_email.text.erb | 9 ++++++ .../services/merge_requests/update_service_spec.rb | 33 ++++++++++++++++++++++ spec/services/notification_service_spec.rb | 26 +++++++++++++++++ 7 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 app/views/notify/new_mention_in_merge_request_email.html.haml create mode 100644 app/views/notify/new_mention_in_merge_request_email.text.erb diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb index 9dd11d20ea6..95810b0ac6e 100644 --- a/app/mailers/emails/merge_requests.rb +++ b/app/mailers/emails/merge_requests.rb @@ -6,6 +6,11 @@ module Emails mail_new_thread(@merge_request, merge_request_thread_options(@merge_request.author_id, recipient_id)) end + def new_mention_in_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) + setup_merge_request_mail(merge_request_id, recipient_id) + mail_answer_thread(@merge_request, merge_request_thread_options(updated_by_user_id, recipient_id)) + end + def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id, updated_by_user_id) setup_merge_request_mail(merge_request_id, recipient_id) diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index 0ad42b83fe2..30c5f24988c 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -56,7 +56,14 @@ module MergeRequests ) end - # TODO(nick): use old_mentioned_users to send notify for changed mentions + added_mentions = merge_request.mentioned_users - old_mentioned_users + if added_mentions.present? + notification_service.new_mentions_in_merge_request( + merge_request, + added_mentions, + current_user + ) + end end def reopen_service diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 73df572514f..01f95281170 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -89,6 +89,20 @@ class NotificationService new_resource_email(merge_request, merge_request.target_project, :new_merge_request_email) end + # When merge request text is updated, we should send an email to: + # + # * newly mentioned project team members with notification level higher than Participating + # + def new_mentions_in_merge_request(merge_request, new_mentioned_users, current_user) + new_mentions_in_resource_email( + merge_request, + merge_request.target_project, + new_mentioned_users, + current_user, + :new_mention_in_merge_request_email + ) + end + # When we reassign a merge_request we should send an email to: # # * merge_request old assignee if their notification level is not Disabled diff --git a/app/views/notify/new_mention_in_merge_request_email.html.haml b/app/views/notify/new_mention_in_merge_request_email.html.haml new file mode 100644 index 00000000000..158404de396 --- /dev/null +++ b/app/views/notify/new_mention_in_merge_request_email.html.haml @@ -0,0 +1,12 @@ +- if current_application_settings.email_author_in_body + %div + #{link_to @merge_request.author_name, user_url(@merge_request.author)} wrote: +%p.details + != merge_path_description(@merge_request, '→') + +- if @merge_request.assignee_id.present? + %p + Assignee: #{@merge_request.author_name} → #{@merge_request.assignee_name} + +-if @merge_request.description + = markdown(@merge_request.description, pipeline: :email, author: @merge_request.author) diff --git a/app/views/notify/new_mention_in_merge_request_email.text.erb b/app/views/notify/new_mention_in_merge_request_email.text.erb new file mode 100644 index 00000000000..5bf0282e097 --- /dev/null +++ b/app/views/notify/new_mention_in_merge_request_email.text.erb @@ -0,0 +1,9 @@ +You have been mentioned in Merge Request <%= @merge_request.to_reference %> + +<%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)) %> + +<%= merge_path_description(@merge_request, 'to') %> +Author: <%= @merge_request.author_name %> +Assignee: <%= @merge_request.assignee_name %> + +<%= @merge_request.description %> diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index 283a336afd9..e26e925cd81 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -226,6 +226,39 @@ describe MergeRequests::UpdateService, services: true do end end + context 'updated user mentions' do + let(:user4) { create(:user) } + before do + project.team << [user4, :developer] + end + + context "in title" do + before do + perform_enqueued_jobs { update_merge_request(title: user4.to_reference) } + end + + it "should email only the newly-mentioned user" do + should_not_email(user) + should_not_email(user2) + should_not_email(user3) + should_email(user4) + end + end + + context "in description" do + before do + perform_enqueued_jobs { update_merge_request(description: user4.to_reference) } + end + + it "should email only the newly-mentioned user" do + should_not_email(user) + should_not_email(user2) + should_not_email(user3) + should_email(user4) + end + end + end + context 'when MergeRequest has tasks' do before { update_merge_request({ description: "- [ ] Task 1\n- [ ] Task 2" }) } diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index d61de6c15d1..2fa0d9f1ac2 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -789,6 +789,32 @@ describe NotificationService, services: true do end end + describe '#new_mentions_in_merge_request' do + def send_notifications(*new_mentions) + ActionMailer::Base.deliveries.clear + notification.new_mentions_in_merge_request(merge_request, new_mentions, @u_disabled) + end + + it "should not email anyone unless they are newly mentioned" do + send_notifications + expect(ActionMailer::Base.deliveries).to eq [] + end + + it "should email new mentions with a watch level higher than participant" do + send_notifications(@u_watcher, @u_participant_mentioned) + + should_email(@u_watcher) + should_email(@u_participant_mentioned) + + expect(ActionMailer::Base.deliveries.count).to eq 2 + end + + it "should not email new mentions with a watch level equal to or less than participant" do + send_notifications(@u_participating, @u_mentioned) + expect(ActionMailer::Base.deliveries).to eq [] + end + end + describe '#reassigned_merge_request' do before do update_custom_notification(:reassign_merge_request, @u_guest_custom, project) -- cgit v1.2.1 From 10af11f4fe71e46d4decd2ab428e9b2b38e2d463 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 15 Aug 2016 15:15:20 +0100 Subject: Allow people to subscribe to mentions in updated MRs and Issues This slightly changes the semantics of the 'New Issue' and 'New MR' events to include new mentions in edited Mentionables. An alternative would be to introduce 'Issue updated' and 'MR updated' events, but that would lead to questions about why those events were only available to new mentions, and not existing mentions as well, so hold off for now. --- app/services/notification_service.rb | 3 ++- doc/workflow/notifications.md | 7 ++++++- spec/services/notification_service_spec.rb | 12 ++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 01f95281170..2291bc0f127 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -500,7 +500,8 @@ class NotificationService end def new_mentions_in_resource_email(target, project, new_mentioned_users, current_user, method) - recipients = build_recipients(target, project, current_user) & new_mentioned_users + recipients = build_recipients(target, project, current_user, action: "new") + recipients = recipients & new_mentioned_users recipients.each do |recipient| mailer.send(method, recipient.id, target.id, current_user.id).deliver_later diff --git a/doc/workflow/notifications.md b/doc/workflow/notifications.md index b4a9c2f3d3e..1b49a5c385f 100644 --- a/doc/workflow/notifications.md +++ b/doc/workflow/notifications.md @@ -67,7 +67,7 @@ In all of the below cases, the notification will be sent to: - Participants: - the author and assignee of the issue/merge request - authors of comments on the issue/merge request - - anyone mentioned by `@username` in the issue/merge request description + - anyone mentioned by `@username` in the issue/merge request title or description - anyone mentioned by `@username` in any of the comments on the issue/merge request ...with notification level "Participating" or higher @@ -89,6 +89,11 @@ In all of the below cases, the notification will be sent to: | Merge merge request | | | New comment | The above, plus anyone mentioned by `@username` in the comment, with notification level "Mention" or higher | + +In addition, if the title or description of an Issue or Merge Request is +changed, notifications will be sent to any **new** mentions by `@username` as +if they had been mentioned in the original text. + You won't receive notifications for Issues, Merge Requests or Milestones created by yourself. You will only receive automatic notifications when somebody else comments or adds changes to the ones that you've created or diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 2fa0d9f1ac2..fbca28bbb17 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -411,12 +411,13 @@ describe NotificationService, services: true do end it "should email new mentions with a watch level higher than participant" do - send_notifications(@u_watcher, @u_participant_mentioned) + send_notifications(@u_watcher, @u_participant_mentioned, @u_custom_global) should_email(@u_watcher) should_email(@u_participant_mentioned) + should_email(@u_custom_global) - expect(ActionMailer::Base.deliveries.count).to eq 2 + expect(ActionMailer::Base.deliveries.count).to eq 3 end it "should not email new mentions with a watch level equal to or less than participant" do @@ -726,6 +727,8 @@ describe NotificationService, services: true do before do build_team(merge_request.target_project) add_users_with_subscription(merge_request.target_project, merge_request) + update_custom_notification(:new_merge_request, @u_guest_custom, project) + update_custom_notification(:new_merge_request, @u_custom_global) ActionMailer::Base.deliveries.clear end @@ -801,12 +804,13 @@ describe NotificationService, services: true do end it "should email new mentions with a watch level higher than participant" do - send_notifications(@u_watcher, @u_participant_mentioned) + send_notifications(@u_watcher, @u_participant_mentioned, @u_custom_global) should_email(@u_watcher) should_email(@u_participant_mentioned) + should_email(@u_custom_global) - expect(ActionMailer::Base.deliveries.count).to eq 2 + expect(ActionMailer::Base.deliveries.count).to eq 3 end it "should not email new mentions with a watch level equal to or less than participant" do -- cgit v1.2.1 From 6bf7b627d11e4719f60b109a5379e7975411f611 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Mon, 15 Aug 2016 16:08:00 +0100 Subject: Add new mention notifications to changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 008c5c64284..836bb0b9fce 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -30,6 +30,7 @@ v 8.11.0 (unreleased) - Fix awardable button mutuality loading spinners (ClemMakesApps) - Add support for using RequestStore within Sidekiq tasks via SIDEKIQ_REQUEST_STORE env variable - Optimize maximum user access level lookup in loading of notes + - Send notification emails to users newly mentioned in issue and MR edits !5800 - Add "No one can push" as an option for protected branches. !5081 - Improve performance of AutolinkFilter#text_parse by using XPath - Add experimental Redis Sentinel support !1877 -- cgit v1.2.1 From 8a6e9b934e6e25023437ff8a2dd2271d67a12e40 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 16 Aug 2016 13:40:55 +0100 Subject: Address minor review comments for tests --- spec/services/issues/update_service_spec.rb | 6 +++--- spec/services/merge_requests/update_service_spec.rb | 8 ++++---- spec/services/notification_service_spec.rb | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index a5e375578ec..60561cc64d0 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -331,7 +331,7 @@ describe Issues::UpdateService, services: true do perform_enqueued_jobs { update_issue(title: user4.to_reference) } end - it "should email only the newly-mentioned user" do + it 'emails only the newly-mentioned user' do should_not_email(user) should_not_email(user2) should_not_email(user3) @@ -339,12 +339,12 @@ describe Issues::UpdateService, services: true do end end - context "in description" do + context 'in description' do before do perform_enqueued_jobs { update_issue(description: user4.to_reference) } end - it "should email only the newly-mentioned user" do + it 'emails only the newly-mentioned user' do should_not_email(user) should_not_email(user2) should_not_email(user3) diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index e26e925cd81..86d78f8c898 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -232,12 +232,12 @@ describe MergeRequests::UpdateService, services: true do project.team << [user4, :developer] end - context "in title" do + context 'in title' do before do perform_enqueued_jobs { update_merge_request(title: user4.to_reference) } end - it "should email only the newly-mentioned user" do + it 'emails only the newly-mentioned user' do should_not_email(user) should_not_email(user2) should_not_email(user3) @@ -245,12 +245,12 @@ describe MergeRequests::UpdateService, services: true do end end - context "in description" do + context 'in description' do before do perform_enqueued_jobs { update_merge_request(description: user4.to_reference) } end - it "should email only the newly-mentioned user" do + it 'emails only the newly-mentioned user' do should_not_email(user) should_not_email(user2) should_not_email(user3) diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index fbca28bbb17..1cf644e1331 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -405,12 +405,12 @@ describe NotificationService, services: true do notification.new_mentions_in_issue(issue, new_mentions, @u_disabled) end - it "should not email anyone unless they are newly mentioned" do + it 'sends no emails when no new mentions are present' do send_notifications - expect(ActionMailer::Base.deliveries).to eq [] + expect(ActionMailer::Base.deliveries).to be_empty end - it "should email new mentions with a watch level higher than participant" do + it 'emails new mentions with a watch level higher than participant' do send_notifications(@u_watcher, @u_participant_mentioned, @u_custom_global) should_email(@u_watcher) @@ -420,9 +420,9 @@ describe NotificationService, services: true do expect(ActionMailer::Base.deliveries.count).to eq 3 end - it "should not email new mentions with a watch level equal to or less than participant" do + it 'does not email new mentions with a watch level equal to or less than participant' do send_notifications(@u_participating, @u_mentioned) - expect(ActionMailer::Base.deliveries).to eq [] + expect(ActionMailer::Base.deliveries).to be_empty end end @@ -798,12 +798,12 @@ describe NotificationService, services: true do notification.new_mentions_in_merge_request(merge_request, new_mentions, @u_disabled) end - it "should not email anyone unless they are newly mentioned" do + it 'sends no emails when there are no new mentions' do send_notifications - expect(ActionMailer::Base.deliveries).to eq [] + expect(ActionMailer::Base.deliveries).to be_empty end - it "should email new mentions with a watch level higher than participant" do + it 'emails new mentions with a watch level higher than participant' do send_notifications(@u_watcher, @u_participant_mentioned, @u_custom_global) should_email(@u_watcher) @@ -813,9 +813,9 @@ describe NotificationService, services: true do expect(ActionMailer::Base.deliveries.count).to eq 3 end - it "should not email new mentions with a watch level equal to or less than participant" do + it 'does not email new mentions with a watch level equal to or less than participant' do send_notifications(@u_participating, @u_mentioned) - expect(ActionMailer::Base.deliveries).to eq [] + expect(ActionMailer::Base.deliveries).to be_empty end end -- cgit v1.2.1 From b62954db4c40df435363994ce4632632fde01455 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 16 Aug 2016 14:12:05 +0100 Subject: Include the reason for emailing in the new_mention emails --- app/views/notify/new_mention_in_issue_email.html.haml | 3 +++ app/views/notify/new_mention_in_merge_request_email.html.haml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/app/views/notify/new_mention_in_issue_email.html.haml b/app/views/notify/new_mention_in_issue_email.html.haml index f42b150c0d6..4f3d36bd9ca 100644 --- a/app/views/notify/new_mention_in_issue_email.html.haml +++ b/app/views/notify/new_mention_in_issue_email.html.haml @@ -1,3 +1,6 @@ +%p + You have been mentioned in an issue. + - if current_application_settings.email_author_in_body %div #{link_to @issue.author_name, user_url(@issue.author)} wrote: diff --git a/app/views/notify/new_mention_in_merge_request_email.html.haml b/app/views/notify/new_mention_in_merge_request_email.html.haml index 158404de396..32aedb9e6b9 100644 --- a/app/views/notify/new_mention_in_merge_request_email.html.haml +++ b/app/views/notify/new_mention_in_merge_request_email.html.haml @@ -1,3 +1,6 @@ +%p + You have been mentioned in Merge Request #{@merge_request.to_reference} + - if current_application_settings.email_author_in_body %div #{link_to @merge_request.author_name, user_url(@merge_request.author)} wrote: -- cgit v1.2.1 From 0e9c4a902d7985d917fac1f833c9544133f83a95 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 16 Aug 2016 17:08:43 +0100 Subject: DRY up the added update service specs, add two email helpers --- spec/services/issues/update_service_spec.rb | 35 +++------------------- .../services/merge_requests/update_service_spec.rb | 34 ++------------------- spec/support/email_helpers.rb | 10 +++++++ spec/support/updating_mentions_shared_examples.rb | 32 ++++++++++++++++++++ 4 files changed, 49 insertions(+), 62 deletions(-) create mode 100644 spec/support/updating_mentions_shared_examples.rb diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 60561cc64d0..d36937b6c59 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -320,37 +320,10 @@ describe Issues::UpdateService, services: true do end end - context 'updated user mentions' do - let(:user4) { create(:user) } - before do - project.team << [user4, :developer] - end - - context "in title" do - before do - perform_enqueued_jobs { update_issue(title: user4.to_reference) } - end - - it 'emails only the newly-mentioned user' do - should_not_email(user) - should_not_email(user2) - should_not_email(user3) - should_email(user4) - end - end - - context 'in description' do - before do - perform_enqueued_jobs { update_issue(description: user4.to_reference) } - end - - it 'emails only the newly-mentioned user' do - should_not_email(user) - should_not_email(user2) - should_not_email(user3) - should_email(user4) - end - end + context 'updating mentions' do + let(:mentionable) { issue } + include_examples 'updating mentions', Issues::UpdateService end + end end diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index 86d78f8c898..6dfeb581975 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -226,37 +226,9 @@ describe MergeRequests::UpdateService, services: true do end end - context 'updated user mentions' do - let(:user4) { create(:user) } - before do - project.team << [user4, :developer] - end - - context 'in title' do - before do - perform_enqueued_jobs { update_merge_request(title: user4.to_reference) } - end - - it 'emails only the newly-mentioned user' do - should_not_email(user) - should_not_email(user2) - should_not_email(user3) - should_email(user4) - end - end - - context 'in description' do - before do - perform_enqueued_jobs { update_merge_request(description: user4.to_reference) } - end - - it 'emails only the newly-mentioned user' do - should_not_email(user) - should_not_email(user2) - should_not_email(user3) - should_email(user4) - end - end + context 'updating mentions' do + let(:mentionable) { merge_request } + include_examples 'updating mentions', MergeRequests::UpdateService end context 'when MergeRequest has tasks' do diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb index a85ab22ce36..0bfc4685532 100644 --- a/spec/support/email_helpers.rb +++ b/spec/support/email_helpers.rb @@ -3,6 +3,16 @@ module EmailHelpers ActionMailer::Base.deliveries.map(&:to).flatten.count(user.email) == 1 end + def reset_delivered_emails! + ActionMailer::Base.deliveries.clear + end + + def should_only_email(*users) + users.each {|user| should_email(user) } + recipients = ActionMailer::Base.deliveries.flat_map(&:to) + expect(recipients.count).to eq(users.count) + end + def should_email(user) expect(sent_to_user?(user)).to be_truthy end diff --git a/spec/support/updating_mentions_shared_examples.rb b/spec/support/updating_mentions_shared_examples.rb new file mode 100644 index 00000000000..e0c59a5c280 --- /dev/null +++ b/spec/support/updating_mentions_shared_examples.rb @@ -0,0 +1,32 @@ +RSpec.shared_examples 'updating mentions' do |service_class| + let(:mentioned_user) { create(:user) } + let(:service_class) { service_class } + + before { project.team << [mentioned_user, :developer] } + + def update_mentionable(opts) + reset_delivered_emails! + + perform_enqueued_jobs do + service_class.new(project, user, opts).execute(mentionable) + end + + mentionable.reload + end + + context 'in title' do + before { update_mentionable(title: mentioned_user.to_reference) } + + it 'emails only the newly-mentioned user' do + should_only_email(mentioned_user) + end + end + + context 'in description' do + before { update_mentionable(description: mentioned_user.to_reference) } + + it 'emails only the newly-mentioned user' do + should_only_email(mentioned_user) + end + end +end -- cgit v1.2.1 From ffd7311d03485f146cef4b915d1f7d71f70d30bb Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Tue, 16 Aug 2016 17:40:04 +0100 Subject: DRY up the additions to notification_service_spec.rb --- spec/services/notification_service_spec.rb | 74 +++++++++++------------------- 1 file changed, 28 insertions(+), 46 deletions(-) diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 1cf644e1331..62c97e09288 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -9,6 +9,28 @@ describe NotificationService, services: true do end end + shared_examples 'notifications for new mentions' do + def send_notifications(*new_mentions) + reset_delivered_emails! + notification.send(notification_method, mentionable, new_mentions, @u_disabled) + end + + it 'sends no emails when no new mentions are present' do + send_notifications + expect(ActionMailer::Base.deliveries).to be_empty + end + + it 'emails new mentions with a watch level higher than participant' do + send_notifications(@u_watcher, @u_participant_mentioned, @u_custom_global) + should_only_email(@u_watcher, @u_participant_mentioned, @u_custom_global) + end + + it 'does not email new mentions with a watch level equal to or less than participant' do + send_notifications(@u_participating, @u_mentioned) + expect(ActionMailer::Base.deliveries).to be_empty + end + end + describe 'Keys' do describe '#new_key' do let!(:key) { create(:personal_key) } @@ -400,30 +422,10 @@ describe NotificationService, services: true do end describe '#new_mentions_in_issue' do - def send_notifications(*new_mentions) - ActionMailer::Base.deliveries.clear - notification.new_mentions_in_issue(issue, new_mentions, @u_disabled) - end - - it 'sends no emails when no new mentions are present' do - send_notifications - expect(ActionMailer::Base.deliveries).to be_empty - end + let(:notification_method) { :new_mentions_in_issue } + let(:mentionable) { issue } - it 'emails new mentions with a watch level higher than participant' do - send_notifications(@u_watcher, @u_participant_mentioned, @u_custom_global) - - should_email(@u_watcher) - should_email(@u_participant_mentioned) - should_email(@u_custom_global) - - expect(ActionMailer::Base.deliveries.count).to eq 3 - end - - it 'does not email new mentions with a watch level equal to or less than participant' do - send_notifications(@u_participating, @u_mentioned) - expect(ActionMailer::Base.deliveries).to be_empty - end + include_examples 'notifications for new mentions' end describe '#reassigned_issue' do @@ -793,30 +795,10 @@ describe NotificationService, services: true do end describe '#new_mentions_in_merge_request' do - def send_notifications(*new_mentions) - ActionMailer::Base.deliveries.clear - notification.new_mentions_in_merge_request(merge_request, new_mentions, @u_disabled) - end - - it 'sends no emails when there are no new mentions' do - send_notifications - expect(ActionMailer::Base.deliveries).to be_empty - end + let(:notification_method) { :new_mentions_in_merge_request } + let(:mentionable) { merge_request } - it 'emails new mentions with a watch level higher than participant' do - send_notifications(@u_watcher, @u_participant_mentioned, @u_custom_global) - - should_email(@u_watcher) - should_email(@u_participant_mentioned) - should_email(@u_custom_global) - - expect(ActionMailer::Base.deliveries.count).to eq 3 - end - - it 'does not email new mentions with a watch level equal to or less than participant' do - send_notifications(@u_participating, @u_mentioned) - expect(ActionMailer::Base.deliveries).to be_empty - end + include_examples 'notifications for new mentions' end describe '#reassigned_merge_request' do -- cgit v1.2.1 From bdbc3d355a86bf03e7a7a00fc2d867fa043c0bdd Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 8 Aug 2016 16:26:33 -0500 Subject: Add build data to top of pipeline page --- app/assets/stylesheets/pages/pipelines.scss | 6 ++++++ app/views/projects/commit/_pipeline.html.haml | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 21919fe4d73..5bc8c3a7e6c 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -229,3 +229,9 @@ box-shadow: none; } } + +// Pipeline visualization +.stage-column { + display: inline-block; + vertical-align: top; +} diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 640abdb993f..2452326fc04 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,4 +1,16 @@ .row-content-block.build-content.middle-block + .pipeline-visualization + - pipeline.statuses.stages.each do |stage| + - statuses = pipeline.statuses.where(stage: stage) + .stage-column + %strong + %a{name: stage} + - if stage + = stage.titleize + - statuses.each do |status| + %div= status.name + + .pull-right - if can?(current_user, :update_pipeline, pipeline.project) - if pipeline.builds.latest.failed.any?(&:retryable?) -- cgit v1.2.1 From dfe94da0fb4da1a84bfd6324f7b2291067582af0 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 8 Aug 2016 17:42:28 -0500 Subject: Connect top level tests to each other --- app/assets/stylesheets/pages/pipelines.scss | 50 +++++++++++++++++++++++++++ app/views/projects/commit/_pipeline.html.haml | 16 ++++++--- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 5bc8c3a7e6c..e79c7e59720 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -231,7 +231,57 @@ } // Pipeline visualization + +.pipeline-visualization { + position: relative; +} + .stage-column { display: inline-block; vertical-align: top; + margin-right: 40px; + + .stage-name { + margin-bottom: 15px; + font-weight: bold; + } + + .builds-container { + + } + + .build { + border: 1px solid $border-color; + position: relative; + padding: 6px 10px; + border-radius: 30px; + width: 150px; + // TODO truncate text within .build div; not on build div itself + // white-space: nowrap; + // overflow: hidden; + // text-overflow: ellipsis; + margin-bottom: 10px; + + svg { + position: relative; + top: 2px; + margin-right: 5px; + } + + &:first-child { + &::after, &::before { + content: ''; + position: absolute; + top: 50%; + right: -44px; + border-top: 1px solid $border-color; + width: 44px; + height: 1px; + } + } + &:first-child::before, &:last-child::after{ + border: 0 none; + } + + } } diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 2452326fc04..b993ad5ce50 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,16 +1,22 @@ -.row-content-block.build-content.middle-block +.row-content-block.white + .pipeline-visualization - pipeline.statuses.stages.each do |stage| - statuses = pipeline.statuses.where(stage: stage) + - status = statuses.latest.status .stage-column - %strong + .stage-name %a{name: stage} - if stage = stage.titleize - - statuses.each do |status| - %div= status.name - + .builds-container + - statuses.each do |build| + .build + %span{class: "ci-status-link ci-status-icon-#{status}"} + = ci_icon_for_status(status) + = build.name +.row-content-block.build-content.middle-block .pull-right - if can?(current_user, :update_pipeline, pipeline.project) - if pipeline.builds.latest.failed.any?(&:retryable?) -- cgit v1.2.1 From ca9bba29fea30fd4cdb223273fca007c9abf12b0 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 14:26:25 -0500 Subject: Connect all builds in visual pipeline --- app/assets/stylesheets/pages/pipelines.scss | 81 ++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index e79c7e59720..fa422f4f3c5 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -234,6 +234,10 @@ .pipeline-visualization { position: relative; + + ul { + padding: 0; + } } .stage-column { @@ -241,15 +245,15 @@ vertical-align: top; margin-right: 40px; + li { + list-style: none; + } + .stage-name { margin-bottom: 15px; font-weight: bold; } - .builds-container { - - } - .build { border: 1px solid $border-color; position: relative; @@ -268,20 +272,81 @@ margin-right: 5px; } + // Connect first build in each stage with right horizontal line &:first-child { - &::after, &::before { + &::after { content: ''; position: absolute; top: 50%; right: -44px; - border-top: 1px solid $border-color; + border-top: 2px solid $border-color; width: 44px; height: 1px; } } - &:first-child::before, &:last-child::after{ - border: 0 none; + + // Connect each build (except for first) with curved lines + &:not(:first-child) { + &::after, &::before { + content: ''; + top: -47px; + position: absolute; + border-bottom: 2px solid $border-color; + width: 20px; + height: 65px; + } + + // Right connecting curves + &::after { + right: -21px; + border-right: 2px solid $border-color; + border-radius: 0 0 50px 0; + -webkit-border-radius: 0 0 50px 0; + } + + // Left connecting curves + &::before { + left: -21px; + border-left: 2px solid $border-color; + border-radius: 0 0 0 50px; + -webkit-border-radius: 0 0 0 50px; + } + } + + // Connect second build to first build with smaller curved line + &:nth-child(2) { + &::after, &::before { + height: 40px; + top: -26px; + } + } + } + + &:last-child { + .build { + // Remove right connecting horizontal line from first build in last stage + &:first-child { + &::after, &::before { + border: none; + } + } + // Remove right curved connectors from all builds in last stage + &:not(:first-child) { + &::after { + border: none; + } + } } + } + &:first-child { + .build { + // Remove left curved connectors from all builds in first stage + &:not(:first-child) { + &::before { + border: none; + } + } + } } } -- cgit v1.2.1 From 1b583583a9a93c2ba8e00982c33fca904e219fca Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 15:00:09 -0500 Subject: Add min width and horizontally scroll pipeline graph when overflow --- app/assets/stylesheets/pages/pipelines.scss | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index fa422f4f3c5..a9ffda00278 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -234,16 +234,22 @@ .pipeline-visualization { position: relative; + width: 100%; + overflow: auto; ul { padding: 0; } } +.stage-column-list { + min-width: 1220px; +} + .stage-column { display: inline-block; vertical-align: top; - margin-right: 40px; + margin-right: 50px; li { list-style: none; @@ -278,9 +284,9 @@ content: ''; position: absolute; top: 50%; - right: -44px; + right: -54px; border-top: 2px solid $border-color; - width: 44px; + width: 54px; height: 1px; } } @@ -298,7 +304,7 @@ // Right connecting curves &::after { - right: -21px; + right: -20px; border-right: 2px solid $border-color; border-radius: 0 0 50px 0; -webkit-border-radius: 0 0 50px 0; @@ -306,7 +312,7 @@ // Left connecting curves &::before { - left: -21px; + left: -20px; border-left: 2px solid $border-color; border-radius: 0 0 0 50px; -webkit-border-radius: 0 0 0 50px; @@ -316,9 +322,14 @@ // Connect second build to first build with smaller curved line &:nth-child(2) { &::after, &::before { - height: 40px; + height: 45px; top: -26px; } + &::after { + // border-left: 2px solid $border-color; + border-top-right-radius: -50px; + -webkit-border-top-right-radius: -50px; + } } } -- cgit v1.2.1 From d7b3b15f60e25e1b11b6fcc22f96c63bffa137a8 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 15:08:04 -0500 Subject: Truncate build and stage names --- CHANGELOG | 1 + app/assets/stylesheets/pages/pipelines.scss | 15 +++++++++---- app/views/projects/commit/_pipeline.html.haml | 31 +++++++++++++++------------ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index aececed9add..a3e824dcac6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -108,6 +108,7 @@ v 8.11.0 (unreleased) - Speed up and reduce memory usage of Commit#repo_changes, Repository#expire_avatar_cache and IrkerWorker - Add unfold links for Side-by-Side view. !5415 (Tim Masliuchenko) - Adds support for pending invitation project members importing projects + - Add pipeline visualization/graph on pipeline page - Update devise initializer to turn on changed password notification emails. !5648 (tombell) - Avoid to show the original password field when password is automatically set. !5712 (duduribeiro) - Fix importing GitLab projects with an invalid MR source project diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index a9ffda00278..49225d7d0d4 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -258,6 +258,10 @@ .stage-name { margin-bottom: 15px; font-weight: bold; + width: 150px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .build { @@ -266,12 +270,15 @@ padding: 6px 10px; border-radius: 30px; width: 150px; - // TODO truncate text within .build div; not on build div itself - // white-space: nowrap; - // overflow: hidden; - // text-overflow: ellipsis; margin-bottom: 10px; + .build-content { + width: 130px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + svg { position: relative; top: 2px; diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index b993ad5ce50..4dacff8f6eb 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,20 +1,23 @@ .row-content-block.white .pipeline-visualization - - pipeline.statuses.stages.each do |stage| - - statuses = pipeline.statuses.where(stage: stage) - - status = statuses.latest.status - .stage-column - .stage-name - %a{name: stage} - - if stage - = stage.titleize - .builds-container - - statuses.each do |build| - .build - %span{class: "ci-status-link ci-status-icon-#{status}"} - = ci_icon_for_status(status) - = build.name + %ul.stage-column-list + - pipeline.statuses.stages.each do |stage| + - statuses = pipeline.statuses.where(stage: stage) + - status = statuses.latest.status + %li.stage-column + .stage-name + %a{name: stage} + - if stage + = stage.titleize + .builds-container + %ul + - statuses.each do |build| + %li.build + .build-content + %span{class: "ci-status-link ci-status-icon-#{status}"} + = ci_icon_for_status(status) + = build.name .row-content-block.build-content.middle-block .pull-right -- cgit v1.2.1 From e573cdfb91308759923fbd0aacb12f801dfb561f Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 15:39:01 -0500 Subject: Fix graph scrolling bug --- app/assets/stylesheets/pages/pipelines.scss | 13 +++++++------ app/views/projects/commit/_pipeline.html.haml | 5 ++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 49225d7d0d4..01bd131940a 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -232,20 +232,21 @@ // Pipeline visualization -.pipeline-visualization { - position: relative; +.pipeline-graph { width: 100%; overflow: auto; + white-space: nowrap; +} + +.pipeline-visualization { + position: relative; + min-width: 1220px; ul { padding: 0; } } -.stage-column-list { - min-width: 1220px; -} - .stage-column { display: inline-block; vertical-align: top; diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 4dacff8f6eb..e2187673da7 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,5 +1,4 @@ -.row-content-block.white - +.row-content-block.build-content.middle-block.pipeline-graph .pipeline-visualization %ul.stage-column-list - pipeline.statuses.stages.each do |stage| @@ -19,7 +18,7 @@ = ci_icon_for_status(status) = build.name -.row-content-block.build-content.middle-block +.row-content-block.build-content.middle-block.pipeline-graph .pull-right - if can?(current_user, :update_pipeline, pipeline.project) - if pipeline.builds.latest.failed.any?(&:retryable?) -- cgit v1.2.1 From 0ff0acc89c80b9ef4a473e4be1549ef4a21a8b8a Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 16:15:09 -0500 Subject: Fix scss lint error --- app/assets/stylesheets/pages/pipelines.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 01bd131940a..ad256e2a728 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -314,8 +314,8 @@ &::after { right: -20px; border-right: 2px solid $border-color; - border-radius: 0 0 50px 0; - -webkit-border-radius: 0 0 50px 0; + border-radius: 0 0 50px; + -webkit-border-radius: 0 0 50px; } // Left connecting curves -- cgit v1.2.1 From a3ef844c0a59dd94bf8b8a962a92b6610758d5af Mon Sep 17 00:00:00 2001 From: winniehell Date: Sun, 24 Jul 2016 01:13:13 +0200 Subject: fix star button icon alignment --- app/views/projects/buttons/_star.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/projects/buttons/_star.html.haml b/app/views/projects/buttons/_star.html.haml index 71cf5582a4c..311583037e5 100644 --- a/app/views/projects/buttons/_star.html.haml +++ b/app/views/projects/buttons/_star.html.haml @@ -1,10 +1,10 @@ - if current_user = link_to toggle_star_namespace_project_path(@project.namespace, @project), { class: 'btn star-btn toggle-star has-tooltip', method: :post, remote: true, title: current_user.starred?(@project) ? 'Unstar project' : 'Star project' } do - if current_user.starred?(@project) - = icon('star fw') + = icon('star') %span.starred Unstar - else - = icon('star-o fw') + = icon('star-o') %span Star %div.count-with-arrow %span.arrow @@ -13,7 +13,7 @@ - else = link_to new_user_session_path, class: 'btn has-tooltip star-btn', title: 'You must sign in to star a project' do - = icon('star fw') + = icon('star') Star %div.count-with-arrow %span.arrow -- cgit v1.2.1 From c4141bac76d4d869054a2c2979af7cf59ed9411f Mon Sep 17 00:00:00 2001 From: winniehell Date: Sun, 24 Jul 2016 01:14:44 +0200 Subject: fix fork button icon alignment --- CHANGELOG | 1 + app/views/shared/icons/_icon_fork.svg | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 2a7109b3c2b..4289aded1ab 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -42,6 +42,7 @@ v 8.11.0 (unreleased) - Remove unused images (ClemMakesApps) - Get issue and merge request description templates from repositories - Add hover state to todos !5361 (winniehell) + - Fix icon alignment of star and fork buttons !5451 (winniehell) - Limit git rev-list output count to one in forced push check - Show deployment status on merge requests with external URLs - Clean up unused routes (Josef Strzibny) diff --git a/app/views/shared/icons/_icon_fork.svg b/app/views/shared/icons/_icon_fork.svg index a21f8f3a951..fc970e4ce50 100644 --- a/app/views/shared/icons/_icon_fork.svg +++ b/app/views/shared/icons/_icon_fork.svg @@ -1,3 +1,3 @@ - + -- cgit v1.2.1 From 9810c71d9b61983840df61aa662041cffb9c9541 Mon Sep 17 00:00:00 2001 From: winniehell Date: Fri, 5 Aug 2016 00:37:32 +0200 Subject: add space between icon and button text --- app/assets/stylesheets/framework/buttons.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index f1fe1697d30..6c3786b49bb 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -204,6 +204,10 @@ position: relative; top: 2px; } + + svg, .fa { + margin-right: 3px; + } } .btn-lg { -- cgit v1.2.1 From 8d5dc4fa6b0f01dbe46e89105aed5072c60cc102 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 16 Aug 2016 19:42:05 -0500 Subject: Add toggle button to hide graph; set max-height --- app/assets/javascripts/pipeline.js.es6 | 10 ++++++ app/assets/stylesheets/pages/pipelines.scss | 43 +++++++++++++++++++++---- app/views/projects/commit/_pipeline.html.haml | 46 +++++++++++++++------------ 3 files changed, 71 insertions(+), 28 deletions(-) create mode 100644 app/assets/javascripts/pipeline.js.es6 diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 new file mode 100644 index 00000000000..7054199ac89 --- /dev/null +++ b/app/assets/javascripts/pipeline.js.es6 @@ -0,0 +1,10 @@ +function toggleGraph() { + $('.pipeline-graph, .toggle-pipeline-btn').toggleClass('graph-collapsed'); + + const $btnText = $('.toggle-pipeline-btn .btn-text'); + const graphCollapsed = $('.pipeline-graph').hasClass('graph-collapsed'); + + graphCollapsed ? $btnText.text('Expand') : $btnText.text('Hide') +} + +$(document).on('click', '.toggle-pipeline-btn', toggleGraph); diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index ad256e2a728..f35aca193e9 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -232,10 +232,35 @@ // Pipeline visualization +.toggle-pipeline-btn { + background-color: $gray-dark; + + .caret { + border-top: none; + border-bottom: 4px solid; + } + + &.graph-collapsed { + background-color: $white-light; + + .caret { + border-bottom: none; + border-top: 4px solid; + } + } +} + .pipeline-graph { width: 100%; overflow: auto; white-space: nowrap; + max-height: 500px; + transition: max-height 0.3s, padding 0.3s; + + &.graph-collapsed { + max-height: 0; + padding: 0 16px; + } } .pipeline-visualization { @@ -315,7 +340,6 @@ right: -20px; border-right: 2px solid $border-color; border-radius: 0 0 50px; - -webkit-border-radius: 0 0 50px; } // Left connecting curves @@ -323,7 +347,6 @@ left: -20px; border-left: 2px solid $border-color; border-radius: 0 0 0 50px; - -webkit-border-radius: 0 0 0 50px; } } @@ -333,11 +356,6 @@ height: 45px; top: -26px; } - &::after { - // border-left: 2px solid $border-color; - border-top-right-radius: -50px; - -webkit-border-top-right-radius: -50px; - } } } @@ -369,3 +387,14 @@ } } } + +.pipeline-actions { + border-bottom: none; +} + +.toggle-pipeline-btn { + + .fa { + color: $dropdown-header-color; + } +} diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index e2187673da7..eb80aadd524 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,25 +1,9 @@ -.row-content-block.build-content.middle-block.pipeline-graph - .pipeline-visualization - %ul.stage-column-list - - pipeline.statuses.stages.each do |stage| - - statuses = pipeline.statuses.where(stage: stage) - - status = statuses.latest.status - %li.stage-column - .stage-name - %a{name: stage} - - if stage - = stage.titleize - .builds-container - %ul - - statuses.each do |build| - %li.build - .build-content - %span{class: "ci-status-link ci-status-icon-#{status}"} - = ci_icon_for_status(status) - = build.name - -.row-content-block.build-content.middle-block.pipeline-graph +.row-content-block.build-content.middle-block.pipeline-actions .pull-right + .btn.btn-grouped.btn-white.toggle-pipeline-btn + %span.btn-text Hide + %span pipeline graph + %span.caret - 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-grouped btn-primary', method: :post @@ -43,6 +27,26 @@ in = time_interval_in_words pipeline.duration +.row-content-block.build-content.middle-block.pipeline-graph + .pipeline-visualization + %ul.stage-column-list + - pipeline.statuses.stages.each do |stage| + - statuses = pipeline.statuses.where(stage: stage) + - status = statuses.latest.status + %li.stage-column + .stage-name + %a{name: stage} + - if stage + = stage.titleize + .builds-container + %ul + - statuses.each do |build| + %li.build + .build-content + %span{class: "ci-status-link ci-status-icon-#{status}"} + = ci_icon_for_status(status) + = build.name + - if pipeline.yaml_errors.present? .bs-callout.bs-callout-danger %h4 Found errors in your .gitlab-ci.yml: -- cgit v1.2.1 From b631985ad7a8a85d1350425e6d1cf1cb90c93b5f Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 16 Aug 2016 19:52:34 -0500 Subject: Add links to pipeline graph --- app/assets/stylesheets/pages/pipelines.scss | 4 ++++ app/views/projects/commit/_pipeline.html.haml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index f35aca193e9..ce9e3e95d3d 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -303,6 +303,10 @@ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + + a { + color: $layout-link-gray; + } } svg { diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index eb80aadd524..44250860020 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -45,7 +45,7 @@ .build-content %span{class: "ci-status-link ci-status-icon-#{status}"} = ci_icon_for_status(status) - = build.name + = link_to build.name, namespace_project_build_url(build.project.namespace, build.project, build) - if pipeline.yaml_errors.present? .bs-callout.bs-callout-danger -- cgit v1.2.1 From 2797cfbf604be698f5b0aaf7178a9aad78d2805b Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 17 Aug 2016 09:46:13 +0100 Subject: Fix a rubocop violation --- spec/services/issues/update_service_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index d36937b6c59..0313f424463 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -324,6 +324,5 @@ describe Issues::UpdateService, services: true do let(:mentionable) { issue } include_examples 'updating mentions', Issues::UpdateService end - end end -- cgit v1.2.1 From fee7992c08c434940f0722886dc96f249a8e7fbf Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 17 Aug 2016 09:46:34 +0100 Subject: Fix pipelines visualisation rendering --- app/models/ci/build.rb | 2 +- app/models/ci/pipeline.rb | 4 ++++ app/views/projects/commit/_pipeline.html.haml | 16 ++++++++++------ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 08f396210c9..b42977f9ebd 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -102,7 +102,7 @@ module Ci end def playable? - project.builds_enabled? && commands.present? && manual? + project.builds_enabled? && commands.present? && manual? && skipped? end def play(current_user = nil) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index bce6a992af6..caf4d25029f 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -34,6 +34,10 @@ module Ci CommitStatus.where(pipeline: pluck(:id)).stages end + def stages + statuses.order(:stage_idx).latest.group_by(&:stage) + end + def project_id project.id end diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 0c006656d1d..27501d89dc5 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,9 +1,8 @@ .row-content-block.build-content.middle-block.pipeline-graph .pipeline-visualization %ul.stage-column-list - - pipeline.statuses.stages.each do |stage| - - statuses = pipeline.statuses.where(stage: stage) - - status = statuses.latest.status + - stages = pipeline.statuses.latest.order(:stage_idx).group_by(&:stage) + - stages.each do |stage, builds| %li.stage-column .stage-name %a{name: stage} @@ -11,11 +10,16 @@ = stage.titleize .builds-container %ul - - statuses.each do |build| + - builds.each do |build| %li.build .build-content - %span{class: "ci-status-link ci-status-icon-#{status}"} - = ci_icon_for_status(status) + %span{class: "ci-status-link ci-status-icon-#{build.status}"} + - if build.try(:playable?) + = link_to play_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Play' do + = icon('play') + - else + = link_to namespace_project_build_url(build.project.namespace, build.project, build) do + = ci_icon_for_status(build.status) = build.name .row-content-block.build-content.middle-block.pipeline-graph -- cgit v1.2.1 From f52f62d7aec168b3b8c291cdb81f64501bd80e5a Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Tue, 16 Aug 2016 16:18:44 +0200 Subject: Update fixtures to make development testing easier --- db/fixtures/development/14_builds.rb | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/db/fixtures/development/14_builds.rb b/db/fixtures/development/14_builds.rb index e65abe4ef77..3734c861078 100644 --- a/db/fixtures/development/14_builds.rb +++ b/db/fixtures/development/14_builds.rb @@ -28,24 +28,44 @@ class Gitlab::Seeder::Builds build_create!(pipeline, name: 'production', stage: 'deploy', environment: 'production', when: 'manual', status: :success) commit_status_create!(pipeline, name: 'jenkins', status: :success) - print '.' rescue ActiveRecord::RecordInvalid print 'F' + ensure + pipeline.build_updated end end end def pipelines - commits = @project.repository.commits('master', limit: 5) - commits_sha = commits.map { |commit| commit.raw.id } - commits_sha.map do |sha| - @project.ensure_pipeline(sha, 'master') - end + master_pipelines + merge_request_pipelines + end + + def master_pipelines + create_pipelines_for(@project, 'master') rescue [] end + def merge_request_pipelines + @project.merge_requests.last(5).map do |merge_request| + create_pipelines(merge_request.source_project, merge_request.source_branch, merge_request.commits.last(5)) + end.flatten + rescue + [] + end + + def create_pipelines_for(project, ref) + commits = project.repository.commits(ref, limit: 5) + create_pipelines(project, ref, commits) + end + + def create_pipelines(project, ref, commits) + commits.map do |commit| + project.pipelines.create(sha: commit.id, ref: ref) + end + end + def build_create!(pipeline, opts = {}) attributes = build_attributes_for(pipeline, opts) build = Ci::Build.create!(attributes) -- cgit v1.2.1 From fd09311da93070546c52e65c0c2af9b8566c56b5 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 17 Aug 2016 11:18:57 +0100 Subject: Update fixtures to add a created status to pipeline --- db/fixtures/development/14_builds.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/db/fixtures/development/14_builds.rb b/db/fixtures/development/14_builds.rb index 0d493fa1c3c..069d9dd6226 100644 --- a/db/fixtures/development/14_builds.rb +++ b/db/fixtures/development/14_builds.rb @@ -1,9 +1,8 @@ class Gitlab::Seeder::Builds - STAGES = %w[build notify_build test notify_test deploy notify_deploy] + STAGES = %w[build test deploy notify] BUILDS = [ { name: 'build:linux', stage: 'build', status: :success }, { name: 'build:osx', stage: 'build', status: :success }, - { name: 'slack post build', stage: 'notify_build', status: :success }, { name: 'rspec:linux', stage: 'test', status: :success }, { name: 'rspec:windows', stage: 'test', status: :success }, { name: 'rspec:windows', stage: 'test', status: :success }, @@ -12,9 +11,9 @@ class Gitlab::Seeder::Builds { name: 'spinach:osx', stage: 'test', status: :canceled }, { name: 'cucumber:linux', stage: 'test', status: :running }, { name: 'cucumber:osx', stage: 'test', status: :failed }, - { name: 'slack post test', stage: 'notify_test', status: :success }, { name: 'staging', stage: 'deploy', environment: 'staging', status: :success }, - { name: 'production', stage: 'deploy', environment: 'production', when: 'manual', status: :success }, + { name: 'production', stage: 'deploy', environment: 'production', when: 'manual', status: :skipped }, + { name: 'slack', stage: 'notify', when: 'manual', status: :created }, ] def initialize(project) @@ -25,7 +24,7 @@ class Gitlab::Seeder::Builds pipelines.each do |pipeline| begin BUILDS.each { |opts| build_create!(pipeline, opts) } - commit_status_create!(pipeline, name: 'jenkins', status: :success) + commit_status_create!(pipeline, name: 'jenkins', stage: 'test', status: :success) print '.' rescue ActiveRecord::RecordInvalid print 'F' -- cgit v1.2.1 From 1cd9b3b8a0b1024d043b9344869aceeadb9c84f1 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 17 Aug 2016 11:21:00 +0100 Subject: Split pipeline status item for Commit Status and Build --- app/models/ci/pipeline.rb | 4 ++-- app/views/projects/ci/builds/_build_pipeline.html.haml | 12 ++++++++++++ app/views/projects/commit/_pipeline.html.haml | 17 ++++------------- .../_generic_commit_status_pipeline.html.haml | 9 +++++++++ 4 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 app/views/projects/ci/builds/_build_pipeline.html.haml create mode 100644 app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index d3fc5191721..c360a6ff729 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -78,8 +78,8 @@ module Ci CommitStatus.where(pipeline: pluck(:id)).stages end - def stages - statuses.order(:stage_idx).latest.group_by(&:stage) + def stages_with_latest_statuses + statuses.latest.order(:stage_idx).group_by(&:stage) end def project_id diff --git a/app/views/projects/ci/builds/_build_pipeline.html.haml b/app/views/projects/ci/builds/_build_pipeline.html.haml new file mode 100644 index 00000000000..5149d75e5a2 --- /dev/null +++ b/app/views/projects/ci/builds/_build_pipeline.html.haml @@ -0,0 +1,12 @@ +%li.build + .build-content + %span{class: "ci-status-link ci-status-icon-#{subject.status}"} + - if subject.playable? && can?(current_user, :update_build, @project) + = link_to play_namespace_project_build_path(subject.project.namespace, subject.project, subject, return_to: request.original_url), method: :post, title: 'Play' do + = icon('play') + - elsif can?(current_user, :read_build, @project) && subject.started? + = link_to namespace_project_build_path(subject.project.namespace, subject.project, subject) do + = ci_icon_for_status(subject.status) + - else + = ci_icon_for_status(subject.status) + = subject.name diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 5c8f40acfe3..7a7f61e9705 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,8 +1,8 @@ .row-content-block.build-content.middle-block.pipeline-graph .pipeline-visualization %ul.stage-column-list - - stages = pipeline.statuses.latest.order(:stage_idx).group_by(&:stage) - - stages.each do |stage, builds| + - stages = pipeline.stages_with_latest_statuses + - stages.each do |stage, statuses| %li.stage-column .stage-name %a{name: stage} @@ -10,17 +10,8 @@ = stage.titleize .builds-container %ul - - builds.each do |build| - %li.build - .build-content - %span{class: "ci-status-link ci-status-icon-#{build.status}"} - - if build.try(:playable?) - = link_to play_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Play' do - = icon('play') - - else - = link_to namespace_project_build_url(build.project.namespace, build.project, build) do - = ci_icon_for_status(build.status) - = build.name + - statuses.each do |status| + = render "projects/#{status.to_partial_path}_pipeline", subject: status .row-content-block.build-content.middle-block.pipeline-graph .pull-right diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml new file mode 100644 index 00000000000..760918b18a3 --- /dev/null +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml @@ -0,0 +1,9 @@ +%li.build + .build-content + %span{class: "ci-status-link ci-status-icon-#{subject.status}"} + - if subject.target_url + - link_to subject.target_url do + = ci_icon_for_status(subject.status) + - else + = ci_icon_for_status(subject.status) + = subject.name -- cgit v1.2.1 From 49e7070adfcb281938a43aceeb52cc0257601e1d Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 17 Aug 2016 12:08:45 +0100 Subject: Add support for Play and Created jobs --- app/helpers/ci_status_helper.rb | 26 ++++++++++++++-------- .../projects/ci/builds/_build_pipeline.html.haml | 22 +++++++++--------- app/views/projects/commit/_pipeline.html.haml | 14 +++++------- .../_generic_commit_status_pipeline.html.haml | 14 ++++++------ 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index ea2f5f9281a..573cdef767e 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -38,6 +38,10 @@ module CiStatusHelper 'icon_status_pending' when 'running' 'icon_status_running' + when 'play' + 'icon_status_warning' + when 'created' + 'icon_status_pending' else 'icon_status_cancel' end @@ -48,13 +52,13 @@ module CiStatusHelper def render_commit_status(commit, tooltip_placement: 'auto left') project = commit.project path = builds_namespace_project_commit_path(project.namespace, project, commit) - render_status_with_link('commit', commit.status, path, tooltip_placement) + render_status_with_link('commit', commit.status, path, tooltip_placement: tooltip_placement) end def render_pipeline_status(pipeline, tooltip_placement: 'auto left') project = pipeline.project path = namespace_project_pipeline_path(project.namespace, project, pipeline) - render_status_with_link('pipeline', pipeline.status, path, tooltip_placement) + render_status_with_link('pipeline', pipeline.status, path, tooltip_placement: tooltip_placement) end def no_runners_for_project?(project) @@ -62,13 +66,17 @@ module CiStatusHelper Ci::Runner.shared.blank? end - private + def render_status_with_link(type, status, path = nil, tooltip_placement: 'auto left', cssclass: '') + klass = "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}" + title = "#{type.titleize}: #{ci_label_for_status(status)}" + data = { toggle: 'tooltip', placement: tooltip_placement } - def render_status_with_link(type, status, path, tooltip_placement, cssclass: '') - link_to ci_icon_for_status(status), - path, - class: "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}", - title: "#{type.titleize}: #{ci_label_for_status(status)}", - data: { toggle: 'tooltip', placement: tooltip_placement } + if path + link_to ci_icon_for_status(status), path, + class: klass, title: title, data: data + else + content_tag :span, ci_icon_for_status(status), + class: klass, title: title, data: data + end end end diff --git a/app/views/projects/ci/builds/_build_pipeline.html.haml b/app/views/projects/ci/builds/_build_pipeline.html.haml index 5149d75e5a2..8c8e0efc60f 100644 --- a/app/views/projects/ci/builds/_build_pipeline.html.haml +++ b/app/views/projects/ci/builds/_build_pipeline.html.haml @@ -1,12 +1,14 @@ %li.build .build-content - %span{class: "ci-status-link ci-status-icon-#{subject.status}"} - - if subject.playable? && can?(current_user, :update_build, @project) - = link_to play_namespace_project_build_path(subject.project.namespace, subject.project, subject, return_to: request.original_url), method: :post, title: 'Play' do - = icon('play') - - elsif can?(current_user, :read_build, @project) && subject.started? - = link_to namespace_project_build_path(subject.project.namespace, subject.project, subject) do - = ci_icon_for_status(subject.status) - - else - = ci_icon_for_status(subject.status) - = subject.name + - if subject.playable? && can?(current_user, :update_build, @project) + = link_to play_namespace_project_build_path(subject.project.namespace, subject.project, subject, return_to: request.original_url), method: :post, title: 'Play' do + = render_status_with_link('build', 'play') + = subject.name + - elsif can?(current_user, :read_build, @project) + = link_to namespace_project_build_path(subject.project.namespace, subject.project, subject) do + = render_status_with_link('build', subject.status) + = subject.name + - else + = render_status_with_link('build', subject.status) + = ci_icon_for_status(subject.status) + diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 44250860020..9fa54057823 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -30,9 +30,8 @@ .row-content-block.build-content.middle-block.pipeline-graph .pipeline-visualization %ul.stage-column-list - - pipeline.statuses.stages.each do |stage| - - statuses = pipeline.statuses.where(stage: stage) - - status = statuses.latest.status + - stages = pipeline.stages_with_latest_statuses + - stages.each do |stage, statuses| %li.stage-column .stage-name %a{name: stage} @@ -40,12 +39,9 @@ = stage.titleize .builds-container %ul - - statuses.each do |build| - %li.build - .build-content - %span{class: "ci-status-link ci-status-icon-#{status}"} - = ci_icon_for_status(status) - = link_to build.name, namespace_project_build_url(build.project.namespace, build.project, build) + - statuses.each do |status| + = render "projects/#{status.to_partial_path}_pipeline", subject: status + - if pipeline.yaml_errors.present? .bs-callout.bs-callout-danger diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml index 760918b18a3..584c0fa18ae 100644 --- a/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml +++ b/app/views/projects/generic_commit_statuses/_generic_commit_status_pipeline.html.haml @@ -1,9 +1,9 @@ %li.build .build-content - %span{class: "ci-status-link ci-status-icon-#{subject.status}"} - - if subject.target_url - - link_to subject.target_url do - = ci_icon_for_status(subject.status) - - else - = ci_icon_for_status(subject.status) - = subject.name + - if subject.target_url + - link_to subject.target_url do + = render_status_with_link('commit status', subject.status) + = subject.name + - else + = render_status_with_link('commit status', subject.status) + = subject.name -- cgit v1.2.1 From c0a722a223e50efeab5ed3f10523d83806a09215 Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Mon, 15 Aug 2016 16:10:22 +0100 Subject: Removed sleep calls introduced in !5740 --- features/steps/project/issues/issues.rb | 2 -- features/steps/project/merge_requests.rb | 1 - 2 files changed, 3 deletions(-) diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index daee90b3767..35f166c7c08 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -354,8 +354,6 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps end def filter_issue(text) - sleep 1 fill_in 'issue_search', with: text - sleep 1 end end diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index 53d1aedf27f..f3d78780da3 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -489,7 +489,6 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps end step 'I fill in merge request search with "Fe"' do - sleep 1 fill_in 'issue_search', with: "Fe" end -- cgit v1.2.1 From 8691561016338a58e314cdaa69911523b35c6df4 Mon Sep 17 00:00:00 2001 From: Luke Bennett Date: Wed, 17 Aug 2016 13:33:44 +0100 Subject: Now waits for All issuables to load when clicked --- features/steps/project/issues/issues.rb | 2 ++ features/steps/project/merge_requests.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/features/steps/project/issues/issues.rb b/features/steps/project/issues/issues.rb index 35f166c7c08..056462a7152 100644 --- a/features/steps/project/issues/issues.rb +++ b/features/steps/project/issues/issues.rb @@ -45,6 +45,8 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps step 'I click link "All"' do click_link "All" + # Waits for load + expect(find('.issues-state-filters > .active')).to have_content 'All' end step 'I click link "Release 0.4"' do diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb index f3d78780da3..9778ff4a6c7 100644 --- a/features/steps/project/merge_requests.rb +++ b/features/steps/project/merge_requests.rb @@ -22,6 +22,8 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps step 'I click link "All"' do click_link "All" + # Waits for load + expect(find('.issues-state-filters > .active')).to have_content 'All' end step 'I click link "Merged"' do -- cgit v1.2.1 From 4e66551a6614283f5b085a523bdbfbc552edb976 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 17 Aug 2016 10:06:10 -0500 Subject: Add deploy btn in graph; fix JS to toggle one graph at a time if multiple pipelines --- app/assets/javascripts/pipeline.js.es6 | 9 ++++++--- app/assets/stylesheets/pages/pipelines.scss | 8 ++++++++ app/helpers/ci_status_helper.rb | 4 ++-- app/views/projects/ci/builds/_build_pipeline.html.haml | 3 +-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index 7054199ac89..ae7369004de 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -1,8 +1,11 @@ function toggleGraph() { - $('.pipeline-graph, .toggle-pipeline-btn').toggleClass('graph-collapsed'); + const indexOfBtn = $('.toggle-pipeline-btn').index($(this)); - const $btnText = $('.toggle-pipeline-btn .btn-text'); - const graphCollapsed = $('.pipeline-graph').hasClass('graph-collapsed'); + $($('.pipeline-graph')[indexOfBtn]).toggleClass('graph-collapsed'); + $($('.toggle-pipeline-btn')[indexOfBtn]).toggleClass('graph-collapsed'); + + const $btnText = $($('.toggle-pipeline-btn .btn-text')[indexOfBtn]); + const graphCollapsed = $($('.pipeline-graph')[indexOfBtn]).hasClass('graph-collapsed'); graphCollapsed ? $btnText.text('Expand') : $btnText.text('Hide') } diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index ce9e3e95d3d..e49543d661f 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -298,6 +298,10 @@ width: 150px; margin-bottom: 10px; + &.deployable { + background-color: $gray-light; + } + .build-content { width: 130px; white-space: nowrap; @@ -315,6 +319,10 @@ margin-right: 5px; } + .fa { + font-size: 13px; + } + // Connect first build in each stage with right horizontal line &:first-child { &::after { diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 573cdef767e..eb385d58e3b 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -39,14 +39,14 @@ module CiStatusHelper when 'running' 'icon_status_running' when 'play' - 'icon_status_warning' + 'play' when 'created' 'icon_status_pending' else 'icon_status_cancel' end - custom_icon(icon_name) + status == 'play' ? icon(icon_name + ' fw') : custom_icon(icon_name) end def render_commit_status(commit, tooltip_placement: 'auto left') diff --git a/app/views/projects/ci/builds/_build_pipeline.html.haml b/app/views/projects/ci/builds/_build_pipeline.html.haml index 8c8e0efc60f..6be75860db2 100644 --- a/app/views/projects/ci/builds/_build_pipeline.html.haml +++ b/app/views/projects/ci/builds/_build_pipeline.html.haml @@ -1,4 +1,4 @@ -%li.build +%li.build{class: ("deployable" if subject.playable? && can?(current_user, :update_build, @project))} .build-content - if subject.playable? && can?(current_user, :update_build, @project) = link_to play_namespace_project_build_path(subject.project.namespace, subject.project, subject, return_to: request.original_url), method: :post, title: 'Play' do @@ -11,4 +11,3 @@ - else = render_status_with_link('build', subject.status) = ci_icon_for_status(subject.status) - -- cgit v1.2.1 From bfe2259bb76b320bd148de4fbdcebfd1b70a59ba Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 17 Aug 2016 10:20:46 -0500 Subject: Update CSS selector and play icon --- app/assets/stylesheets/pages/pipelines.scss | 2 +- app/helpers/ci_status_helper.rb | 4 ++-- app/views/projects/ci/builds/_build_pipeline.html.haml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index e49543d661f..30239d609bc 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -298,7 +298,7 @@ width: 150px; margin-bottom: 10px; - &.deployable { + &.playable { background-color: $gray-light; } diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index eb385d58e3b..94df7d131ca 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -39,14 +39,14 @@ module CiStatusHelper when 'running' 'icon_status_running' when 'play' - 'play' + return icon('play fw') when 'created' 'icon_status_pending' else 'icon_status_cancel' end - status == 'play' ? icon(icon_name + ' fw') : custom_icon(icon_name) + custom_icon(icon_name) end def render_commit_status(commit, tooltip_placement: 'auto left') diff --git a/app/views/projects/ci/builds/_build_pipeline.html.haml b/app/views/projects/ci/builds/_build_pipeline.html.haml index 6be75860db2..13088ef64d9 100644 --- a/app/views/projects/ci/builds/_build_pipeline.html.haml +++ b/app/views/projects/ci/builds/_build_pipeline.html.haml @@ -1,4 +1,4 @@ -%li.build{class: ("deployable" if subject.playable? && can?(current_user, :update_build, @project))} +%li.build{class: ("playable" if subject.playable? && can?(current_user, :update_build, @project))} .build-content - if subject.playable? && can?(current_user, :update_build, @project) = link_to play_namespace_project_build_path(subject.project.namespace, subject.project, subject, return_to: request.original_url), method: :post, title: 'Play' do -- cgit v1.2.1 From 2c23465d05fa1efa4213bd5d7b0e86b1cd521212 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 17 Aug 2016 10:48:49 -0500 Subject: Move deployable conditional to variable; fix pipelines_spec --- app/views/projects/ci/builds/_build_pipeline.html.haml | 5 +++-- spec/features/projects/pipelines_spec.rb | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/views/projects/ci/builds/_build_pipeline.html.haml b/app/views/projects/ci/builds/_build_pipeline.html.haml index 13088ef64d9..04cbd0c3591 100644 --- a/app/views/projects/ci/builds/_build_pipeline.html.haml +++ b/app/views/projects/ci/builds/_build_pipeline.html.haml @@ -1,6 +1,7 @@ -%li.build{class: ("playable" if subject.playable? && can?(current_user, :update_build, @project))} +- is_playable = subject.playable? && can?(current_user, :update_build, @project) +%li.build{class: ("playable" if is_playable)} .build-content - - if subject.playable? && can?(current_user, :update_build, @project) + - if is_playable = link_to play_namespace_project_build_path(subject.project.namespace, subject.project, subject, return_to: request.original_url), method: :post, title: 'Play' do = render_status_with_link('build', 'play') = subject.name diff --git a/spec/features/projects/pipelines_spec.rb b/spec/features/projects/pipelines_spec.rb index 29d150bc597..47482bc3cc9 100644 --- a/spec/features/projects/pipelines_spec.rb +++ b/spec/features/projects/pipelines_spec.rb @@ -193,7 +193,11 @@ describe "Pipelines" do end context 'playing manual build' do - before { click_link('Play') } + before do + within '.pipeline-holder' do + click_link('Play') + end + end it { expect(@manual.reload).to be_pending } end -- cgit v1.2.1 From 8e4ec561dc6771d13fee289e1c8247b71b289d08 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Fri, 29 Jul 2016 11:23:05 -0500 Subject: Order by build status --- app/views/projects/builds/show.html.haml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 4421f3b9562..ce9522b9929 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -8,7 +8,19 @@ - builds = @build.pipeline.builds.latest.to_a - if builds.size > 1 %ul.nav-links.no-top.no-bottom - - builds.each do |build| + - statuses = ["failed", "pending", "running", "canceled", "skipped", "success"] + - statuses.each do |build_status| + - builds.select{|build| build.status == build_status}.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 + + - builds.select{|build| build.status == "success"}.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) -- cgit v1.2.1 From 283c1dc3301a8583f21feac71aed2c4d6773ccd8 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 1 Aug 2016 15:46:50 -0500 Subject: Add overflow tests to dropdown --- app/assets/javascripts/build.js | 11 +++++++++++ app/views/projects/builds/show.html.haml | 18 +++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 3d9b824d406..3468c87f5df 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -20,6 +20,7 @@ $(document).off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar); $(window).off('resize.build').on('resize.build', this.hideSidebar); this.updateArtifactRemoveDate(); + this.displayTestStatuses(); if ($('#build-trace').length) { this.getInitialBuildTrace(); this.initScrollButtonAffix(); @@ -132,6 +133,16 @@ } }; + Build.prototype.displayTestStatuses = function() { + $jobTopPosition = $('.build-job').first().offset().top; + + $('.build-job').each(function() { + if ($(this).offset().top > $jobTopPosition) { + $('.overflow-jobs > li').append($(this)); + } + }) + }; + return Build; })(); diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index ce9522b9929..8101d7a13da 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -12,23 +12,19 @@ - statuses.each do |build_status| - builds.select{|build| build.status == build_status}.each do |build| %li{class: ('active' if build == @build) } - = link_to namespace_project_build_path(@project.namespace, @project, build) do + = link_to namespace_project_build_path(@project.namespace, @project, build), class: 'build-job' do = ci_icon_for_status(build.status) %span - if build.name = build.name - else = build.id - - - builds.select{|build| build.status == "success"}.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 + .dropdown + %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} + %span Test Name + = icon('chevron-down') + %ul.dropdown-menu.overflow-jobs + %li - if @build.retried? %li.active -- cgit v1.2.1 From d3cd603b46f55c0048445578fbb6d4819bff8cd1 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 1 Aug 2016 17:51:23 -0500 Subject: Hide dropdown if all tests fit on one line; add counter to dropdown --- app/assets/javascripts/build.js | 10 +++++++++- app/assets/stylesheets/pages/builds.scss | 10 ++++++++++ app/views/projects/builds/show.html.haml | 16 ++++++++-------- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 3468c87f5df..4b28436b524 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -135,12 +135,20 @@ Build.prototype.displayTestStatuses = function() { $jobTopPosition = $('.build-job').first().offset().top; + $dropdownCounter = []; - $('.build-job').each(function() { + $('.build-job a').each(function() { if ($(this).offset().top > $jobTopPosition) { + $dropdownCounter.push($(this)); $('.overflow-jobs > li').append($(this)); } }) + + $('.more-tests').text('More (' + $dropdownCounter.length + ')'); + + if ($('.overflow-jobs > li > a').length == 0) { + $('.overflow-jobs-dropdown').hide(); + } }; return Build; diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index e26f8f7080d..9e79ad0db89 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -61,6 +61,16 @@ margin-right: 3px; } } + + .overflow-jobs-dropdown { + float: right; + padding: 7px 0 7px 5px; + + .dropdown-menu-toggle { + width: auto; + border: none; + } + } } .build-header { diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 8101d7a13da..f3718b3cb49 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -7,24 +7,24 @@ - builds = @build.pipeline.builds.latest.to_a - if builds.size > 1 + .dropdown.overflow-jobs-dropdown + %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} + %span.more-tests More + = icon('caret-down') + %ul.dropdown-menu.dropdown-menu-align-right.overflow-jobs + %li %ul.nav-links.no-top.no-bottom - statuses = ["failed", "pending", "running", "canceled", "skipped", "success"] - statuses.each do |build_status| - builds.select{|build| build.status == build_status}.each do |build| - %li{class: ('active' if build == @build) } - = link_to namespace_project_build_path(@project.namespace, @project, build), class: 'build-job' do + %li.build-job{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 - .dropdown - %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} - %span Test Name - = icon('chevron-down') - %ul.dropdown-menu.overflow-jobs - %li - if @build.retried? %li.active -- cgit v1.2.1 From 4d32a8b7e9a07f82b6c12bbed4e772da68da4707 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Mon, 1 Aug 2016 17:57:50 -0500 Subject: Change active state of list items; style dropdown items --- app/assets/stylesheets/pages/builds.scss | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 9e79ad0db89..3039475695c 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -60,6 +60,18 @@ top: 2px; margin-right: 3px; } + + .build-job { + a { + color: $gl-text-color; + } + + &.active { + a { + font-weight: bold; + } + } + } } .overflow-jobs-dropdown { @@ -70,6 +82,12 @@ width: auto; border: none; } + + svg { + position: relative; + top: 2px; + margin-right: 3px; + } } } -- cgit v1.2.1 From 5bfca3b16d12e63675233f1d91e74db35c2545e3 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 3 Aug 2016 13:52:06 -0500 Subject: Add data attributes to builds --- app/assets/javascripts/build.js | 22 ++++++------------- app/assets/stylesheets/pages/builds.scss | 9 +------- app/views/projects/builds/show.html.haml | 37 +++++++++++++++++++------------- 3 files changed, 29 insertions(+), 39 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 4b28436b524..3482c580edb 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -16,11 +16,11 @@ clearInterval(Build.interval); this.bp = Breakpoints.get(); this.hideSidebar(); + this.displayTestStatuses(); $('.js-build-sidebar').niceScroll(); $(document).off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar); $(window).off('resize.build').on('resize.build', this.hideSidebar); this.updateArtifactRemoveDate(); - this.displayTestStatuses(); if ($('#build-trace').length) { this.getInitialBuildTrace(); this.initScrollButtonAffix(); @@ -134,21 +134,11 @@ }; Build.prototype.displayTestStatuses = function() { - $jobTopPosition = $('.build-job').first().offset().top; - $dropdownCounter = []; - - $('.build-job a').each(function() { - if ($(this).offset().top > $jobTopPosition) { - $dropdownCounter.push($(this)); - $('.overflow-jobs > li').append($(this)); - } - }) - - $('.more-tests').text('More (' + $dropdownCounter.length + ')'); - - if ($('.overflow-jobs > li > a').length == 0) { - $('.overflow-jobs-dropdown').hide(); - } + $jobs = $('.build-job'); + jobjects = $jobs.map(function () { + return $(this).data(); + }); + console.log(jobjects); }; return Build; diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 3039475695c..5a6a35f42d1 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -74,14 +74,7 @@ } } - .overflow-jobs-dropdown { - float: right; - padding: 7px 0 7px 5px; - - .dropdown-menu-toggle { - width: auto; - border: none; - } + .jobs-dropdown { svg { position: relative; diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index f3718b3cb49..3fedba488c8 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -7,24 +7,31 @@ - builds = @build.pipeline.builds.latest.to_a - if builds.size > 1 - .dropdown.overflow-jobs-dropdown + .dropdown.stage %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} %span.more-tests More = icon('caret-down') - %ul.dropdown-menu.dropdown-menu-align-right.overflow-jobs - %li - %ul.nav-links.no-top.no-bottom - - statuses = ["failed", "pending", "running", "canceled", "skipped", "success"] - - statuses.each do |build_status| - - builds.select{|build| build.status == build_status}.each do |build| - %li.build-job{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 + %ul.dropdown-menu.overflow-jobs + - builds.each do |build| + %li + %a= build.stage + + - statuses = ["failed", "pending", "running", "canceled", "skipped", "success"] + .dropdown.jobs-dropdown + %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} + %span.more-tests More + = icon('caret-down') + %ul.dropdown-menu.overflow-jobs + - statuses.each do |build_status| + - builds.select{|build| build.status == build_status}.each do |build| + %li.build-job{class: ('active' if build == @build), data: {id: build.id, name: build.name, status: build.status}} + = 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 -- cgit v1.2.1 From f97939a791ae1e71f8e9d366cdfe106decb9545e Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 3 Aug 2016 15:04:40 -0500 Subject: Selecting stage updates builds dropdown --- app/assets/javascripts/build.js | 21 +++++++++++++-------- app/views/projects/builds/show.html.haml | 12 ++++++------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 3482c580edb..baa91e221e8 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -13,13 +13,14 @@ this.state = state1; 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(); - this.displayTestStatuses(); $('.js-build-sidebar').niceScroll(); + 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).on('click', '.stage-item', this.updateDropdown); this.updateArtifactRemoveDate(); if ($('#build-trace').length) { this.getInitialBuildTrace(); @@ -133,12 +134,16 @@ } }; - Build.prototype.displayTestStatuses = function() { - $jobs = $('.build-job'); - jobjects = $jobs.map(function () { - return $(this).data(); - }); - console.log(jobjects); + Build.prototype.populateJobDropdown = function(stage) { + $('.build-job').hide(); + $('.build-job[data-stage="' + stage + '"]').show(); + }; + + Build.prototype.updateDropdown = function(e) { + e.preventDefault(); + var stage = e.target.text; + $('.stage-selection').text(stage); + this.populateJobDropdown(stage); }; return Build; diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 3fedba488c8..2302aa2d1e7 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -6,25 +6,25 @@ = render "header" - builds = @build.pipeline.builds.latest.to_a + - statuses = ["failed", "pending", "running", "canceled", "skipped", "success"] - if builds.size > 1 .dropdown.stage %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} - %span.more-tests More + %span.stage-selection More = icon('caret-down') %ul.dropdown-menu.overflow-jobs - - builds.each do |build| + - builds.map(&:stage).uniq.each do |stage| %li - %a= build.stage + %a.stage-item= stage - - statuses = ["failed", "pending", "running", "canceled", "skipped", "success"] .dropdown.jobs-dropdown %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} - %span.more-tests More + %span.build-selection More = icon('caret-down') %ul.dropdown-menu.overflow-jobs - statuses.each do |build_status| - builds.select{|build| build.status == build_status}.each do |build| - %li.build-job{class: ('active' if build == @build), data: {id: build.id, name: build.name, status: build.status}} + %li.build-job{class: ('active' if build == @build), data: {id: build.id, name: build.name, stage: build.stage}} = link_to namespace_project_build_path(@project.namespace, @project, build) do = ci_icon_for_status(build.status) %span -- cgit v1.2.1 From 0b9cd0a1f635d1e3751aa1279d52292d23a0a9dc Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 3 Aug 2016 15:40:10 -0500 Subject: Populate dropdowns with current build on pageload --- app/assets/javascripts/build.js | 18 ++++++++++++++++-- app/views/projects/builds/show.html.haml | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index baa91e221e8..2725ddcf465 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -6,7 +6,7 @@ Build.state = null; - function Build(page_url, build_url, build_status, state1) { + function Build(page_url, build_url, build_status, build_stage, build_name, state1) { this.page_url = page_url; this.build_url = build_url; this.build_status = build_status; @@ -17,7 +17,12 @@ clearInterval(Build.interval); this.bp = Breakpoints.get(); $('.js-build-sidebar').niceScroll(); + + this.populateJobDropdown(build_stage); + this.updateStageDropdownText(build_stage); + this.updateJobDropdownText(build_name); 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).on('click', '.stage-item', this.updateDropdown); @@ -139,10 +144,19 @@ $('.build-job[data-stage="' + stage + '"]').show(); }; + Build.prototype.updateStageDropdownText = function(stage) { + $('.stage-selection').text(stage); + this.updateJobDropdownText('-'); + }; + + Build.prototype.updateJobDropdownText = function(name) { + $('.build-selection').text(name); + }; + Build.prototype.updateDropdown = function(e) { e.preventDefault(); var stage = e.target.text; - $('.stage-selection').text(stage); + this.updateStageDropdownText(stage); this.populateJobDropdown(stage); }; diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 2302aa2d1e7..5f7c66e4dd2 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -82,4 +82,4 @@ = 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("#{namespace_project_build_url(@project.namespace, @project, @build)}", "#{namespace_project_build_url(@project.namespace, @project, @build, :json)}", "#{@build.status}", "#{@build.stage}", "#{@build.name}", "#{trace_with_state[:state]}") -- cgit v1.2.1 From 3693495e6136a9dc1266fc25a1b6ff9a764de005 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Thu, 4 Aug 2016 15:33:41 -0500 Subject: Style build dropdowns --- app/assets/stylesheets/pages/builds.scss | 27 +++++++-------------------- app/views/projects/builds/show.html.haml | 8 ++++---- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 5a6a35f42d1..5ecbe038612 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -54,32 +54,19 @@ } } - .nav-links { + .build-dropdown { + display: inline-block; + margin-top: 16px; + svg { position: relative; top: 2px; margin-right: 3px; + height: 13px; } - .build-job { - a { - color: $gl-text-color; - } - - &.active { - a { - font-weight: bold; - } - } - } - } - - .jobs-dropdown { - - svg { - position: relative; - top: 2px; - margin-right: 3px; + .stage-item { + cursor: pointer; } } } diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 5f7c66e4dd2..b4834ae42a2 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -8,20 +8,20 @@ - builds = @build.pipeline.builds.latest.to_a - statuses = ["failed", "pending", "running", "canceled", "skipped", "success"] - if builds.size > 1 - .dropdown.stage + .dropdown.build-dropdown %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} %span.stage-selection More = icon('caret-down') - %ul.dropdown-menu.overflow-jobs + %ul.dropdown-menu - builds.map(&:stage).uniq.each do |stage| %li %a.stage-item= stage - .dropdown.jobs-dropdown + .dropdown.build-dropdown %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} %span.build-selection More = icon('caret-down') - %ul.dropdown-menu.overflow-jobs + %ul.dropdown-menu - statuses.each do |build_status| - builds.select{|build| build.status == build_status}.each do |build| %li.build-job{class: ('active' if build == @build), data: {id: build.id, name: build.name, stage: build.stage}} -- cgit v1.2.1 From 6357c75c5784479a71a5b50204aa8633a3650756 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Thu, 4 Aug 2016 15:39:02 -0500 Subject: Update changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 837e9e27aba..2c00255f6d2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -99,6 +99,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 -- cgit v1.2.1 From 1b98f15444449b075ea52346d6368c7e2de8f2b6 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Thu, 4 Aug 2016 15:54:07 -0500 Subject: Remove unused data attributes --- app/views/projects/builds/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index b4834ae42a2..956851c651f 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -24,7 +24,7 @@ %ul.dropdown-menu - statuses.each do |build_status| - builds.select{|build| build.status == build_status}.each do |build| - %li.build-job{class: ('active' if build == @build), data: {id: build.id, name: build.name, stage: build.stage}} + %li.build-job{class: ('active' if build == @build), data: {stage: build.stage}} = link_to namespace_project_build_path(@project.namespace, @project, build) do = ci_icon_for_status(build.status) %span -- cgit v1.2.1 From f80aa9026f6ce7ebfb88c437163868a596b492c4 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Tue, 9 Aug 2016 10:20:21 -0500 Subject: Move skipped tests to end of array --- app/views/projects/builds/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 956851c651f..dba0a0a9f4e 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -6,7 +6,7 @@ = render "header" - builds = @build.pipeline.builds.latest.to_a - - statuses = ["failed", "pending", "running", "canceled", "skipped", "success"] + - statuses = ["failed", "pending", "running", "canceled", "success", "skipped"] - if builds.size > 1 .dropdown.build-dropdown %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} -- cgit v1.2.1 From 8dbb1b2fbeff6caf1ad91173d707b5f55469cb40 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 17 Aug 2016 11:46:41 -0500 Subject: Move stages and jobs to build sidebar --- app/assets/javascripts/build.js | 6 ++--- app/views/projects/builds/_sidebar.html.haml | 36 ++++++++++++++++++++++++++++ app/views/projects/builds/show.html.haml | 35 --------------------------- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 2725ddcf465..1ee4ee5f10e 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -18,7 +18,7 @@ this.bp = Breakpoints.get(); $('.js-build-sidebar').niceScroll(); - this.populateJobDropdown(build_stage); + this.populateJobs(build_stage); this.updateStageDropdownText(build_stage); this.updateJobDropdownText(build_name); this.hideSidebar(); @@ -139,7 +139,7 @@ } }; - Build.prototype.populateJobDropdown = function(stage) { + Build.prototype.populateJobs = function(stage) { $('.build-job').hide(); $('.build-job[data-stage="' + stage + '"]').show(); }; @@ -157,7 +157,7 @@ e.preventDefault(); var stage = e.target.text; this.updateStageDropdownText(stage); - this.populateJobDropdown(stage); + this.populateJobs(stage); }; return Build; diff --git a/app/views/projects/builds/_sidebar.html.haml b/app/views/projects/builds/_sidebar.html.haml index a8bc53c2849..47d0c93b0ba 100644 --- a/app/views/projects/builds/_sidebar.html.haml +++ b/app/views/projects/builds/_sidebar.html.haml @@ -11,6 +11,42 @@ %p.build-detail-row #{@build.coverage}% + - builds = @build.pipeline.builds.latest.to_a + - statuses = ["failed", "pending", "running", "canceled", "success", "skipped"] + - if builds.size > 1 + .dropdown.build-dropdown + %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 + + .dropdown.build-dropdown + %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} + %span.build-selection More + = icon('caret-down') + %ul.dropdown-menu + - statuses.each do |build_status| + - builds.select{|build| build.status == build_status}.each do |build| + %li.build-job{class: ('active' if build == @build), data: {stage: build.stage}} + = 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 can?(current_user, :read_build, @project) && (@build.artifacts? || @build.artifacts_expired?) .block{ class: ("block-first" if !@build.coverage) } .title diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index dba0a0a9f4e..70e02cb2d13 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -5,41 +5,6 @@ .build-page = render "header" - - builds = @build.pipeline.builds.latest.to_a - - statuses = ["failed", "pending", "running", "canceled", "success", "skipped"] - - if builds.size > 1 - .dropdown.build-dropdown - %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 - - .dropdown.build-dropdown - %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} - %span.build-selection More - = icon('caret-down') - %ul.dropdown-menu - - statuses.each do |build_status| - - builds.select{|build| build.status == build_status}.each do |build| - %li.build-job{class: ('active' if build == @build), data: {stage: build.stage}} - = 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 -- cgit v1.2.1 From 162ef4b07262fdc0ad75564225f311a67c11833b Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 17 Aug 2016 12:15:36 -0500 Subject: Display jobs as scrolling list in sidebar --- app/assets/javascripts/build.js | 6 - app/assets/stylesheets/pages/builds.scss | 68 ++++++--- app/views/projects/builds/_sidebar.html.haml | 203 +++++++++++++-------------- 3 files changed, 149 insertions(+), 128 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index 1ee4ee5f10e..c54d8fc2267 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -20,7 +20,6 @@ this.populateJobs(build_stage); this.updateStageDropdownText(build_stage); - this.updateJobDropdownText(build_name); this.hideSidebar(); $(document).off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar); @@ -146,11 +145,6 @@ Build.prototype.updateStageDropdownText = function(stage) { $('.stage-selection').text(stage); - this.updateJobDropdownText('-'); - }; - - Build.prototype.updateJobDropdownText = function(name) { - $('.build-selection').text(name); }; Build.prototype.updateDropdown = function(e) { diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 5ecbe038612..f22b5fb84f8 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -53,22 +53,6 @@ left: 70px; } } - - .build-dropdown { - display: inline-block; - margin-top: 16px; - - svg { - position: relative; - top: 2px; - margin-right: 3px; - height: 13px; - } - - .stage-item { - cursor: pointer; - } - } } .build-header { @@ -116,24 +100,70 @@ } .right-sidebar.build-sidebar { - padding-top: $gl-padding; - padding-bottom: $gl-padding; + padding: $gl-padding 0; + border-left: 1px solid $border-color; &.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; + } + + .builds-container { + margin: $gl-padding 0; + background-color: $white-light; + border-top: 1px solid $border-color; + border-bottom: 1px solid $border-color; + + svg { + position: relative; + top: 2px; + margin-right: 3px; + height: 13px; + } + + a { + display: block; + padding: $gl-padding 10px; + + &:hover { + background-color: $row-hover; + color: $gl-text-color; + } + } + + .build-job { + &.active { + font-weight: bold; + } + } + } } .build-detail-row { diff --git a/app/views/projects/builds/_sidebar.html.haml b/app/views/projects/builds/_sidebar.html.haml index 47d0c93b0ba..726c816716c 100644 --- a/app/views/projects/builds/_sidebar.html.haml +++ b/app/views/projects/builds/_sidebar.html.haml @@ -23,122 +23,119 @@ %li %a.stage-item= stage - .dropdown.build-dropdown - %button.dropdown-menu-toggle{type: 'button', 'data-toggle' => 'dropdown'} - %span.build-selection More - = icon('caret-down') - %ul.dropdown-menu - - statuses.each do |build_status| - - builds.select{|build| build.status == build_status}.each do |build| - %li.build-job{class: ('active' if build == @build), data: {stage: build.stage}} - = 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 + .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 + = 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.retried? + %li.active + %a + Build ##{@build.id} + · + %i.fa.fa-warning + This build was retried. - - 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 + .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 - - 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 + - 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 + = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do + Download - - if @build.artifacts_metadata? - = link_to browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do - Browse + - if @build.artifacts_metadata? + = link_to browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do + Browse - .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 + .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 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 + %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 + .build-widget + %h4.title + Trigger - %p - %span.build-light-text Token: - #{@build.trigger_request.trigger.short_token} - - - 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 -- cgit v1.2.1 From b6c670cf9c1e86748aa0a97decdd5ed9014f4f97 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 17 Aug 2016 13:08:44 -0500 Subject: Style build container box; add check mark to active build --- app/assets/stylesheets/framework/sidebar.scss | 4 ++++ app/assets/stylesheets/pages/builds.scss | 28 ++++++++++++++++++++++++--- app/views/projects/builds/_sidebar.html.haml | 2 ++ 3 files changed, 31 insertions(+), 3 deletions(-) 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 f22b5fb84f8..d910ec0ccc9 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -101,7 +101,6 @@ .right-sidebar.build-sidebar { padding: $gl-padding 0; - border-left: 1px solid $border-color; &.right-sidebar-collapsed { display: none; @@ -133,13 +132,19 @@ .build-dropdown { padding: 0 $gl-padding; + + .dropdown-menu-toggle { + margin-top: 8px; + } } .builds-container { - margin: $gl-padding 0; + 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; @@ -150,7 +155,11 @@ a { display: block; - padding: $gl-padding 10px; + padding: $gl-padding 10px $gl-padding 40px; + width: 270px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; &:hover { background-color: $row-hover; @@ -159,8 +168,21 @@ } .build-job { + position: relative; + + .fa { + position: absolute; + left: 15px; + top: 20px; + display: none; + } + &.active { font-weight: bold; + + .fa { + display: block; + } } } } diff --git a/app/views/projects/builds/_sidebar.html.haml b/app/views/projects/builds/_sidebar.html.haml index 726c816716c..5b0b58e087b 100644 --- a/app/views/projects/builds/_sidebar.html.haml +++ b/app/views/projects/builds/_sidebar.html.haml @@ -15,6 +15,7 @@ - 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') @@ -28,6 +29,7 @@ - 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 -- cgit v1.2.1 From cc7b3db5a2d9a04d976c3db95059e3163a01ec70 Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 17 Aug 2016 13:43:28 -0500 Subject: Remove params from build; general refactor --- app/assets/javascripts/build.js | 19 ++++++++++--------- app/assets/stylesheets/pages/builds.scss | 6 ++++++ app/views/projects/builds/show.html.haml | 8 +++++++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/build.js b/app/assets/javascripts/build.js index c54d8fc2267..0d7d29bb0d0 100644 --- a/app/assets/javascripts/build.js +++ b/app/assets/javascripts/build.js @@ -6,11 +6,12 @@ Build.state = null; - function Build(page_url, build_url, build_status, build_stage, build_name, 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); @@ -18,13 +19,13 @@ this.bp = Breakpoints.get(); $('.js-build-sidebar').niceScroll(); - this.populateJobs(build_stage); - this.updateStageDropdownText(build_stage); + 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).on('click', '.stage-item', this.updateDropdown); + $(document).off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown); this.updateArtifactRemoveDate(); if ($('#build-trace').length) { this.getInitialBuildTrace(); @@ -149,7 +150,7 @@ Build.prototype.updateDropdown = function(e) { e.preventDefault(); - var stage = e.target.text; + var stage = e.currentTarget.text; this.updateStageDropdownText(stage); this.populateJobs(stage); }; diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index d910ec0ccc9..81fce55853c 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -136,6 +136,12 @@ .dropdown-menu-toggle { margin-top: 8px; } + + .dropdown-menu { + right: $gl-padding; + left: $gl-padding; + width: auto; + } } .builds-container { diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml index 70e02cb2d13..e4d41288aa6 100644 --- a/app/views/projects/builds/show.html.haml +++ b/app/views/projects/builds/show.html.haml @@ -47,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}", "#{@build.stage}", "#{@build.name}", "#{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]}" + }) -- cgit v1.2.1 From 5f6c6d6a0d8feee9b17d309e4da180dce7ca8ce0 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 17 Aug 2016 16:04:08 -0300 Subject: Hide `Create new list button` on Issues and MRs pages --- app/views/shared/issuable/_filter.html.haml | 6 +++--- spec/features/projects/issues/list_spec.rb | 20 ++++++++++++++++++++ spec/features/projects/merge_requests/list_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 spec/features/projects/issues/list_spec.rb create mode 100644 spec/features/projects/merge_requests/list_spec.rb diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml index ffe8d4fbdbf..4f8ea7e7cef 100644 --- a/app/views/shared/issuable/_filter.html.haml +++ b/app/views/shared/issuable/_filter.html.haml @@ -27,9 +27,7 @@ = render "shared/issuable/label_dropdown" .pull-right - - if controller.controller_name != 'boards' - = render 'shared/sort_dropdown' - - if can?(current_user, :admin_list, @project) + - if controller.controller_name == 'boards' && can?(current_user, :admin_list, @project) .dropdown %button.btn.btn-create.js-new-board-list{ type: "button", data: { toggle: "dropdown", labels: labels_filter_path, project_id: @project.try(:id) } } Create new list @@ -38,6 +36,8 @@ - if can?(current_user, :admin_label, @project) = render partial: "shared/issuable/label_page_create" = dropdown_loading + - else + = render 'shared/sort_dropdown' - if controller.controller_name == 'issues' .issues_bulk_update.hide diff --git a/spec/features/projects/issues/list_spec.rb b/spec/features/projects/issues/list_spec.rb new file mode 100644 index 00000000000..3137af074ca --- /dev/null +++ b/spec/features/projects/issues/list_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +feature 'Issues List' do + let(:user) { create(:user) } + let(:project) { create(:empty_project) } + + background do + project.team << [user, :developer] + + login_as(user) + end + + scenario 'user does not see create new list button' do + create(:issue, project: project) + + visit namespace_project_issues_path(project.namespace, project) + + expect(page).not_to have_selector('.js-new-board-list') + end +end diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb new file mode 100644 index 00000000000..5dd58ad66a7 --- /dev/null +++ b/spec/features/projects/merge_requests/list_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +feature 'Merge Requests List' do + let(:user) { create(:user) } + let(:project) { create(:project) } + + background do + project.team << [user, :developer] + + login_as(user) + end + + scenario 'user does not see create new list button' do + create(:merge_request, source_project: project) + + visit namespace_project_merge_requests_path(project.namespace, project) + + expect(page).not_to have_selector('.js-new-board-list') + end +end -- cgit v1.2.1 From 74f80465f6078b4a78ae2ebe4e367d4f1d7c890a Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Date: Wed, 17 Aug 2016 16:41:24 -0500 Subject: Remove index from pipeline toggles --- app/assets/javascripts/pipeline.js.es6 | 20 +++++++++++--------- app/views/projects/commit/_pipeline.html.haml | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/pipeline.js.es6 b/app/assets/javascripts/pipeline.js.es6 index ae7369004de..bf33eb10100 100644 --- a/app/assets/javascripts/pipeline.js.es6 +++ b/app/assets/javascripts/pipeline.js.es6 @@ -1,13 +1,15 @@ -function toggleGraph() { - const indexOfBtn = $('.toggle-pipeline-btn').index($(this)); +(function() { + function toggleGraph() { + const $pipelineBtn = $(this).closest('.toggle-pipeline-btn'); + const $pipelineGraph = $(this).closest('.row-content-block').next('.pipeline-graph'); + const $btnText = $(this).find('.toggle-btn-text'); - $($('.pipeline-graph')[indexOfBtn]).toggleClass('graph-collapsed'); - $($('.toggle-pipeline-btn')[indexOfBtn]).toggleClass('graph-collapsed'); + $($pipelineBtn).add($pipelineGraph).toggleClass('graph-collapsed'); - const $btnText = $($('.toggle-pipeline-btn .btn-text')[indexOfBtn]); - const graphCollapsed = $($('.pipeline-graph')[indexOfBtn]).hasClass('graph-collapsed'); + const graphCollapsed = $pipelineGraph.hasClass('graph-collapsed'); - graphCollapsed ? $btnText.text('Expand') : $btnText.text('Hide') -} + graphCollapsed ? $btnText.text('Expand') : $btnText.text('Hide') + } -$(document).on('click', '.toggle-pipeline-btn', toggleGraph); + $(document).on('click', '.toggle-pipeline-btn', toggleGraph); +})(); diff --git a/app/views/projects/commit/_pipeline.html.haml b/app/views/projects/commit/_pipeline.html.haml index 9fa54057823..20a85148ab5 100644 --- a/app/views/projects/commit/_pipeline.html.haml +++ b/app/views/projects/commit/_pipeline.html.haml @@ -1,7 +1,7 @@ .row-content-block.build-content.middle-block.pipeline-actions .pull-right .btn.btn-grouped.btn-white.toggle-pipeline-btn - %span.btn-text Hide + %span.toggle-btn-text Hide %span pipeline graph %span.caret - if can?(current_user, :update_pipeline, pipeline.project) -- cgit v1.2.1 From 43252ccbee64333634f13dd59509a1d19eef5c6e Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Wed, 17 Aug 2016 22:51:49 -0500 Subject: Fix tabs navigation and do not update URL via pushstate --- app/assets/javascripts/merge_request_tabs.js | 5 ++++- app/controllers/projects/merge_requests_controller.rb | 8 +++++++- app/views/projects/merge_requests/_new_submit.html.haml | 11 ++++------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 1bba69a255a..4e2273f5aa8 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -15,6 +15,7 @@ function MergeRequestTabs(opts) { this.opts = opts != null ? opts : {}; + this.opts.setUrl = this.opts.setUrl !== undefined ? this.opts.setUrl : true; this.setCurrentAction = bind(this.setCurrentAction, this); this.tabShown = bind(this.tabShown, this); this.showTab = bind(this.showTab, this); @@ -58,7 +59,9 @@ } else { this.expandView(); } - return this.setCurrentAction(action); + if (this.opts.setUrl) { + this.setCurrentAction(action); + } }; MergeRequestTabs.prototype.scrollToElement = function(container) { diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 00a3022cbf7..696f7192131 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -216,7 +216,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController @base_commit = @merge_request.diff_base_commit @diffs = @merge_request.diffs(diff_options) if @merge_request.compare @diff_notes_disabled = true - + @show_diff_tab = check_diff_tab @pipeline = @merge_request.pipeline @statuses = @pipeline.statuses.relevant if @pipeline @@ -520,4 +520,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController params[:merge_request] ||= ActionController::Parameters.new(source_project: @project) @merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params).execute end + + private + + def check_diff_tab + request.query_parameters[:view].present? + end end diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index 598bd743676..0b05a2693a6 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -20,7 +20,7 @@ .mr-compare.merge-request %ul.merge-request-tabs.nav-links.no-top.no-bottom %li.commits-tab - = link_to url_for(params), data: {target: 'div#commits', action: 'commits', toggle: 'tab'} do + = link_to url_for(params), data: {target: 'div#commits', action: 'new', toggle: 'tab'} do Commits %span.badge= @commits.size - if @pipeline @@ -52,11 +52,8 @@ $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change"); e.preventDefault(); }); - :javascript - var merge_request - merge_request = new MergeRequest({ - action: 'new', - diffs_loaded: true, - commits_loaded: true + var merge_request = new MergeRequest({ + action: "#{(@show_diff_tab ? 'diffs' : 'new')}", + setUrl: false }); -- cgit v1.2.1 From bac19f4c5c62218f7c59894957548a25b03f69d5 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Wed, 17 Aug 2016 22:55:24 -0500 Subject: Fix failing test Test was not waiting for the page to be fully loaded --- spec/features/merge_requests/create_new_mr_spec.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index b63931d9d35..775b38814eb 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' feature 'Create New Merge Request', feature: true, js: true do + include WaitForAjax + let(:user) { create(:user) } let(:project) { create(:project, :public) } @@ -53,10 +55,11 @@ feature 'Create New Merge Request', feature: true, js: true do expect(page.find_link('Side-by-side')[:class]).not_to match(/\bactive\b/) click_link 'Side-by-side' + wait_for_ajax - click_link 'Changes' - - expect(page.find_link('Inline')[:class]).not_to match(/\bactive\b/) - expect(page.find_link('Side-by-side')[:class]).to match(/\bactive\b/) + within '.merge-request' do + expect(page).not_to have_css('a.btn.active', text: 'Inline') + expect(page).to have_css('a.btn.active', text: 'Side-by-side') + end end end -- cgit v1.2.1 From 163c4f5658d0b58dd5925936b3b5498adcf60fb7 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 17 Aug 2016 13:27:14 +0300 Subject: Refactor description templates documentation --- app/views/shared/issuable/_form.html.haml | 2 +- doc/user/project/description_templates.md | 41 +++++++++++++++++++++++++ doc/user/project/img/description_templates.png | Bin 0 -> 57670 bytes doc/workflow/README.md | 2 +- doc/workflow/description_templates.md | 12 -------- doc/workflow/img/description_templates.png | Bin 57670 -> 0 bytes 6 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 doc/user/project/description_templates.md create mode 100644 doc/user/project/img/description_templates.png delete mode 100644 doc/workflow/description_templates.md delete mode 100644 doc/workflow/img/description_templates.png diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index 210b43c7e0b..9e2e096d5f9 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -42,7 +42,7 @@ - if can_add_template?(issuable) %p.help-block Add - = link_to "issuable templates", help_page_path('workflow/description_templates') + = link_to "description templates", help_page_path('user/project/description_templates') to help your contributors communicate effectively! .form-group.detail-page-description diff --git a/doc/user/project/description_templates.md b/doc/user/project/description_templates.md new file mode 100644 index 00000000000..5f1cd126425 --- /dev/null +++ b/doc/user/project/description_templates.md @@ -0,0 +1,41 @@ +# Description templates + +>**Note:** [Introduced][ce-4981] in GitLab 8.11. + +Description templates allow you to define context-specific templates for issue +and merge request description fields for your project. + +## Overview + +By using the description templates, users that create a new issue or merge +request can select a description template to help them communicate with other +contributors effectively. + +Every GitLab project can define its own set of description templates as they +are added to the root directory of a GitLab project's repository. + +Description templates must be written in [Markdown](../markdown.md) and stored +in your project's repository under a directory named `.gitlab`. Only the +templates of the default branch will be taken into account. + +## Creating issue templates + +Create a new Markdown (`.md`) file inside the `.gitlab/issue_templates/` +directory in your repository. Commit and push to your default branch. + +## Creating merge request templates + +Similarly to issue templates, create a new Markdown (`.md`) file inside the +`.gitlab/merge_request_templates/` directory in your repository. Commit and +push to your default branch. + +## Using the templates + +Let's take for example that you have created the file `.gitlab/issue_templates/bug.md`. +This will enable the `bug` dropdown option when creating or editing issues. When +`bug` is selected, the content from the `bug.md` template file will be copied +to the issue description field. + +![Description templates](img/description_templates.png) + +[ce-4981]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/4981 diff --git a/doc/user/project/img/description_templates.png b/doc/user/project/img/description_templates.png new file mode 100644 index 00000000000..af2e9403826 Binary files /dev/null and b/doc/user/project/img/description_templates.png differ diff --git a/doc/workflow/README.md b/doc/workflow/README.md index 993349e5b46..3055411c484 100644 --- a/doc/workflow/README.md +++ b/doc/workflow/README.md @@ -2,6 +2,7 @@ - [Authorization for merge requests](authorization_for_merge_requests.md) - [Change your time zone](timezone.md) +- [Description templates](../user/project/description_templates.md) - [Feature branch workflow](workflow.md) - [GitLab Flow](gitlab_flow.md) - [Groups](groups.md) @@ -17,7 +18,6 @@ - [Share projects with other groups](share_projects_with_other_groups.md) - [Web Editor](web_editor.md) - [Releases](releases.md) -- [Issuable Templates](issuable_templates.md) - [Milestones](milestones.md) - [Merge Requests](merge_requests.md) - [Revert changes](revert_changes.md) diff --git a/doc/workflow/description_templates.md b/doc/workflow/description_templates.md deleted file mode 100644 index 9514564af02..00000000000 --- a/doc/workflow/description_templates.md +++ /dev/null @@ -1,12 +0,0 @@ -# Description templates - -Description templates allow you to define context-specific templates for issue and merge request description fields for your project. When in use, users that create a new issue or merge request can select a description template to help them communicate with other contributors effectively. - -Every GitLab project can define its own set of description templates as they are added to the root directory of a GitLab project's repository. - -Description templates are written in markdown _(`.md`)_ and stored in your projects repository under the `/.gitlab/issue_templates/` and `/.gitlab/merge_request_templates/` directories. - -![Description templates](img/description_templates.png) - -_Example:_ -`/.gitlab/issue_templates/bug.md` will enable the `bug` dropdown option for new issues. When `bug` is selected, the content from the `bug.md` template file will be copied to the issue description field. diff --git a/doc/workflow/img/description_templates.png b/doc/workflow/img/description_templates.png deleted file mode 100644 index af2e9403826..00000000000 Binary files a/doc/workflow/img/description_templates.png and /dev/null differ -- cgit v1.2.1 From a6985c77e03daea9af0077eb219cdb58724e29d2 Mon Sep 17 00:00:00 2001 From: Achilleas Pipinellis Date: Wed, 17 Aug 2016 15:27:18 +0300 Subject: Add new image to show the 'Reset template' button --- doc/user/project/description_templates.md | 11 ++++++----- doc/user/project/img/description_templates.png | Bin 57670 -> 20444 bytes 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/user/project/description_templates.md b/doc/user/project/description_templates.md index 5f1cd126425..ea7496af089 100644 --- a/doc/user/project/description_templates.md +++ b/doc/user/project/description_templates.md @@ -1,6 +1,6 @@ # Description templates ->**Note:** [Introduced][ce-4981] in GitLab 8.11. +>[Introduced][ce-4981] in GitLab 8.11. Description templates allow you to define context-specific templates for issue and merge request description fields for your project. @@ -31,10 +31,11 @@ push to your default branch. ## Using the templates -Let's take for example that you have created the file `.gitlab/issue_templates/bug.md`. -This will enable the `bug` dropdown option when creating or editing issues. When -`bug` is selected, the content from the `bug.md` template file will be copied -to the issue description field. +Let's take for example that you've created the file `.gitlab/issue_templates/Bug.md`. +This will enable the `Bug` dropdown option when creating or editing issues. When +`Bug` is selected, the content from the `Bug.md` template file will be copied +to the issue description field. The 'Reset template' button will discard any +changes you made after picking the template and return it to its initial status. ![Description templates](img/description_templates.png) diff --git a/doc/user/project/img/description_templates.png b/doc/user/project/img/description_templates.png index af2e9403826..c41cc77a94c 100644 Binary files a/doc/user/project/img/description_templates.png and b/doc/user/project/img/description_templates.png differ -- cgit v1.2.1 From 22ce76d447407024d9bd58eedce6c166eb7b6eb2 Mon Sep 17 00:00:00 2001 From: Ruben Davila Date: Thu, 18 Aug 2016 07:33:27 -0500 Subject: Refactor to mark Changes tab as active on new MR page. --- app/controllers/projects/application_controller.rb | 1 + app/controllers/projects/merge_requests_controller.rb | 7 ------- app/views/projects/merge_requests/_new_submit.html.haml | 4 ++-- spec/features/merge_requests/create_new_mr_spec.rb | 7 ++----- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 996909a28c6..91315a07deb 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -83,6 +83,7 @@ class Projects::ApplicationController < ApplicationController end def apply_diff_view_cookie! + @show_changes_tab = params[:view].present? cookies.permanent[:diff_view] = params.delete(:view) if params[:view].present? end diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 696f7192131..4c1f38be9f3 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -216,7 +216,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController @base_commit = @merge_request.diff_base_commit @diffs = @merge_request.diffs(diff_options) if @merge_request.compare @diff_notes_disabled = true - @show_diff_tab = check_diff_tab @pipeline = @merge_request.pipeline @statuses = @pipeline.statuses.relevant if @pipeline @@ -520,10 +519,4 @@ class Projects::MergeRequestsController < Projects::ApplicationController params[:merge_request] ||= ActionController::Parameters.new(source_project: @project) @merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params).execute end - - private - - def check_diff_tab - request.query_parameters[:view].present? - end end diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml index 0b05a2693a6..00bd4e143df 100644 --- a/app/views/projects/merge_requests/_new_submit.html.haml +++ b/app/views/projects/merge_requests/_new_submit.html.haml @@ -54,6 +54,6 @@ }); :javascript var merge_request = new MergeRequest({ - action: "#{(@show_diff_tab ? 'diffs' : 'new')}", - setUrl: false + action: "#{(@show_changes_tab ? 'diffs' : 'new')}", + setUrl: false }); diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index 775b38814eb..b963d1305b5 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -1,8 +1,6 @@ require 'spec_helper' feature 'Create New Merge Request', feature: true, js: true do - include WaitForAjax - let(:user) { create(:user) } let(:project) { create(:project, :public) } @@ -51,11 +49,10 @@ feature 'Create New Merge Request', feature: true, js: true do click_link 'Changes' - expect(page.find_link('Inline')[:class]).to match(/\bactive\b/) - expect(page.find_link('Side-by-side')[:class]).not_to match(/\bactive\b/) + expect(page).to have_css('a.btn.active', text: 'Inline') + expect(page).not_to have_css('a.btn.active', text: 'Side-by-side') click_link 'Side-by-side' - wait_for_ajax within '.merge-request' do expect(page).not_to have_css('a.btn.active', text: 'Inline') -- cgit v1.2.1