From 52252e70e8222e573901632a03d408f3f8698f63 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Aug 2017 09:14:06 +0100 Subject: Improvements to breadcrumbs Closes #35269 --- app/assets/stylesheets/new_nav.scss | 42 +++++++++++----------------- app/helpers/projects_helper.rb | 11 ++++++-- app/views/layouts/nav/_breadcrumbs.html.haml | 15 ++++------ 3 files changed, 29 insertions(+), 39 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index 3e2f23e6b2a..f39ccaac287 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -402,6 +402,20 @@ header.navbar-gitlab-new { } } +.breadcrumbs-list { + display: flex; + margin-bottom: 0; + + > li { + display: flex; + align-items: center; + } + + a { + color: $gl-text-color; + } +} + .breadcrumbs-extra { display: flex; flex: 0 0 auto; @@ -409,34 +423,10 @@ header.navbar-gitlab-new { } .breadcrumbs-sub-title { - margin: 2px 0; - font-size: 16px; + margin: 0; + font-size: $gl-font-size; font-weight: normal; line-height: 1; - - ul { - margin: 0; - } - - li { - display: inline-block; - - &:not(:last-child) { - &::after { - content: "/"; - margin: 0 2px 0 5px; - color: rgba($black, .65); - } - } - - &:last-child a { - font-weight: 600; - } - } - - a { - color: $gl-text-color; - } } .top-area { diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index bee4950e414..2fbb294a5ec 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -58,7 +58,7 @@ module ProjectsHelper link_to(simple_sanitize(owner.name), user_path(owner)) end - project_link = link_to project_path(project), { class: "project-item-select-holder" } do + project_link = link_to project_path(project), { class: ("project-item-select-holder" unless show_new_nav?) } do output = if show_new_nav? project_icon(project, alt: project.name, class: 'avatar-tile', width: 16, height: 16) @@ -70,13 +70,18 @@ module ProjectsHelper output.html_safe end - if current_user + if show_new_nav? + namespace_link = content_tag "li", namespace_link + project_link = content_tag "li", project_link + end + + if current_user && !show_new_nav? project_link << button_tag(type: 'button', class: 'dropdown-toggle-caret js-projects-dropdown-toggle', aria: { label: 'Toggle switch project dropdown' }, data: { target: '.js-dropdown-menu-projects', toggle: 'dropdown', order_by: 'last_activity_at' }) do icon("chevron-down") end end - "#{namespace_link} / #{project_link}".html_safe + "#{namespace_link} #{project_link}".html_safe end def remove_project_message(project) diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 4db84771f4e..9c13395e3d6 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -7,21 +7,16 @@ = button_tag class: 'toggle-mobile-nav', type: 'button' do %span.sr-only Open sidebar = icon ('bars') - .breadcrumbs-links.js-title-container - - unless hide_top_links - .title - = link_to "GitLab", root_path - \/ + .breadcrumbs-links.js-title-container + %ul.list-unstyled.breadcrumbs-list - if content_for?(:header_title_before) - = yield :header_title_before - \/ + %li= yield :header_title_before = header_title - %h2.breadcrumbs-sub-title - %ul.list-unstyled - if @breadcrumbs_extra_links - @breadcrumbs_extra_links.each do |extra| %li= link_to extra[:text], extra[:link] - %li= link_to @breadcrumb_title, breadcrumb_link + %li + %h2.breadcrumbs-sub-title= link_to @breadcrumb_title, breadcrumb_link - if content_for?(:breadcrumbs_extra) .breadcrumbs-extra.hidden-xs= yield :breadcrumbs_extra = yield :header_content -- cgit v1.2.1 From 85b272b22365a7e4588d4897ad9ce78ea180f124 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Aug 2017 10:35:59 +0100 Subject: updated a bunch of breadcrumb titles [ci skip] --- app/assets/stylesheets/new_nav.scss | 97 ++++++---------------- app/helpers/breadcrumbs_helper.rb | 8 ++ app/helpers/groups_helper.rb | 22 +++-- app/helpers/page_layout_helper.rb | 6 +- app/helpers/projects_helper.rb | 4 +- app/views/groups/edit.html.haml | 1 + app/views/groups/projects.html.haml | 1 + app/views/groups/settings/ci_cd/show.html.haml | 3 +- app/views/groups/show.html.haml | 2 +- app/views/layouts/nav/_breadcrumbs.html.haml | 9 +- app/views/profiles/show.html.haml | 2 +- app/views/projects/activity.html.haml | 4 +- app/views/projects/boards/_show.html.haml | 4 +- app/views/projects/branches/index.html.haml | 3 - app/views/projects/commit/show.html.haml | 1 + app/views/projects/commits/show.html.haml | 3 - app/views/projects/compare/index.html.haml | 2 - app/views/projects/compare/show.html.haml | 2 - app/views/projects/cycle_analytics/show.html.haml | 2 - app/views/projects/edit.html.haml | 1 + app/views/projects/empty.html.haml | 1 + app/views/projects/environments/index.html.haml | 3 - app/views/projects/environments/show.html.haml | 1 + app/views/projects/graphs/charts.html.haml | 2 - app/views/projects/graphs/show.html.haml | 3 - app/views/projects/issues/show.html.haml | 1 + app/views/projects/jobs/index.html.haml | 3 - app/views/projects/jobs/show.html.haml | 1 + app/views/projects/merge_requests/show.html.haml | 1 + app/views/projects/milestones/show.html.haml | 1 + app/views/projects/network/show.html.haml | 2 - app/views/projects/pipelines/charts.html.haml | 1 + app/views/projects/pipelines/show.html.haml | 1 + app/views/projects/project_members/index.html.haml | 3 - app/views/projects/settings/ci_cd/show.html.haml | 6 +- .../projects/settings/integrations/show.html.haml | 3 +- .../projects/settings/repository/show.html.haml | 4 +- app/views/projects/show.html.haml | 2 +- app/views/projects/snippets/show.html.haml | 1 + app/views/projects/tags/index.html.haml | 3 - app/views/projects/tags/show.html.haml | 1 + 41 files changed, 87 insertions(+), 134 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index f39ccaac287..c1168734198 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -1,6 +1,7 @@ @import "framework/variables"; @import 'framework/tw_bootstrap_variables'; @import "bootstrap/variables"; +@import "framework/mixins"; header.navbar-gitlab-new { color: $white-light; @@ -293,45 +294,6 @@ header.navbar-gitlab-new { display: flex; min-height: 61px; color: $gl-text-color; - border-bottom: 1px solid $border-color; - - .dropdown-toggle-caret { - position: relative; - top: -1px; - padding: 0 5px; - color: $gl-text-color-secondary; - font-size: 10px; - line-height: 1; - background: none; - border: 0; - - &:focus { - outline: 0; - } - } - - // TODO: fallback to global style - .dropdown-menu { - .divider { - margin: 6px 0; - } - - li { - padding: 0 1px; - - a { - border-radius: 0; - padding: 8px 16px; - - &.is-focused, - &:hover, - &:active, - &:focus { - background-color: $gray-darker; - } - } - } - } } .breadcrumbs-container { @@ -339,42 +301,14 @@ header.navbar-gitlab-new { width: 100%; position: relative; align-items: center; - - .dropdown-menu-projects { - margin-top: -$gl-padding; - margin-left: $gl-padding; - } + border-bottom: 1px solid $border-color; } .breadcrumbs-links { flex: 1; min-width: 0; align-self: center; - color: $gl-text-color-quaternary; - - a { - color: $gl-text-color-secondary; - - &:not(:first-child), - &.group-path { - margin-left: 4px; - } - - &:not(:last-of-type), - &.group-path { - margin-right: 3px; - } - } - - .title { - display: inline-block; - - > a { - &:last-of-type:not(:first-child) { - font-weight: 600; - } - } - } + color: $gl-text-color-secondary; .avatar-tile { margin-right: 5px; @@ -409,13 +343,30 @@ header.navbar-gitlab-new { > li { display: flex; align-items: center; + position: relative; + + &:not(:last-child) { + margin-right: 10px; + } + + &:not(:first-child) { + margin-left: 10px; + } } a { - color: $gl-text-color; + @include str-truncated(128px); + color: currentColor; } } +.breadcrumbs-list-angle { + position: absolute; + right: -12px; + top: 50%; + transform: translateY(-50%); +} + .breadcrumbs-extra { display: flex; flex: 0 0 auto; @@ -425,8 +376,12 @@ header.navbar-gitlab-new { .breadcrumbs-sub-title { margin: 0; font-size: $gl-font-size; - font-weight: normal; + font-weight: 600; line-height: 1; + + a { + color: $gl-text-color; + } } .top-area { diff --git a/app/helpers/breadcrumbs_helper.rb b/app/helpers/breadcrumbs_helper.rb index abe8edd6a8c..044cc905eb4 100644 --- a/app/helpers/breadcrumbs_helper.rb +++ b/app/helpers/breadcrumbs_helper.rb @@ -22,4 +22,12 @@ module BreadcrumbsHelper @breadcrumb_title = title end + + def breadcrumb_list_item(link) + content_tag "li" do + output = link + output << icon("angle-right", class: "breadcrumbs-list-angle") + output + end + end end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 4123a96911f..1badaf721f2 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -15,17 +15,27 @@ module GroupsHelper @has_group_title = true full_title = '' - group.ancestors.reverse.each do |parent| - full_title += group_title_link(parent, hidable: true) - - full_title += ' / '.html_safe + group.ancestors.reverse.each_with_index do |parent, index| + full_title += if show_new_nav? + breadcrumb_list_item group_title_link(parent, hidable: index > 0) + else + group_title_link(parent, hidable: true) + end end - full_title += group_title_link(group) + full_title += if show_new_nav? + breadcrumb_list_item group_title_link(group) + else + group_title_link(group) + end full_title += ' · '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path') if name - content_tag :span, class: 'group-title' do + if show_new_nav? full_title.html_safe + else + content_tag :span, class: 'group-title' do + full_title.html_safe + end end end diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb index b30b2eb1d03..e2ed8f7cdff 100644 --- a/app/helpers/page_layout_helper.rb +++ b/app/helpers/page_layout_helper.rb @@ -80,7 +80,11 @@ module PageLayoutHelper @header_title = title @header_title_url = title_url else - @header_title_url ? link_to(@header_title, @header_title_url) : @header_title + if show_new_nav? + @header_title_url ? breadcrumb_list_item(link_to(@header_title, @header_title_url)) : @header_title + else + @header_title_url ? link_to(@header_title, @header_title_url) : @header_title + end end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 2fbb294a5ec..9e325564d23 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -71,8 +71,8 @@ module ProjectsHelper end if show_new_nav? - namespace_link = content_tag "li", namespace_link - project_link = content_tag "li", project_link + namespace_link = breadcrumb_list_item(namespace_link) if project.group.nil? + project_link = breadcrumb_list_item project_link end if current_user && !show_new_nav? diff --git a/app/views/groups/edit.html.haml b/app/views/groups/edit.html.haml index 9ebb3894c55..839f23e69fd 100644 --- a/app/views/groups/edit.html.haml +++ b/app/views/groups/edit.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "General Settings" = render "groups/settings_head" .panel.panel-default.prepend-top-default .panel-heading diff --git a/app/views/groups/projects.html.haml b/app/views/groups/projects.html.haml index 7a2e688a114..7f3f2f707f7 100644 --- a/app/views/groups/projects.html.haml +++ b/app/views/groups/projects.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "Projects" = render "groups/settings_head" .panel.panel-default.prepend-top-default diff --git a/app/views/groups/settings/ci_cd/show.html.haml b/app/views/groups/settings/ci_cd/show.html.haml index bf36baf48ab..9f9ae01e7c5 100644 --- a/app/views/groups/settings/ci_cd/show.html.haml +++ b/app/views/groups/settings/ci_cd/show.html.haml @@ -1,4 +1,5 @@ -- page_title "Pipelines" +- breadcrumb_title "CI / CD Settings" +- page_title "CI / CD" = render "groups/settings_head" = render 'ci/variables/index' diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index e07f61c94e4..f4f76887422 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,5 +1,5 @@ - @no_container = true -- breadcrumb_title "Group" +- breadcrumb_title "Details" = content_for :meta_tags do = auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity") diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 9c13395e3d6..875b5b7be11 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -7,16 +7,17 @@ = button_tag class: 'toggle-mobile-nav', type: 'button' do %span.sr-only Open sidebar = icon ('bars') - .breadcrumbs-links.js-title-container - %ul.list-unstyled.breadcrumbs-list + .breadcrumbs-links.js-title-container + %ul.list-unstyled.breadcrumbs-list + - unless hide_top_links - if content_for?(:header_title_before) %li= yield :header_title_before = header_title - if @breadcrumbs_extra_links - @breadcrumbs_extra_links.each do |extra| %li= link_to extra[:text], extra[:link] - %li - %h2.breadcrumbs-sub-title= link_to @breadcrumb_title, breadcrumb_link + %li + %h2.breadcrumbs-sub-title= link_to @breadcrumb_title, breadcrumb_link - if content_for?(:breadcrumbs_extra) .breadcrumbs-extra.hidden-xs= yield :breadcrumbs_extra = yield :header_content diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index a8ae0b92334..aa8d5a8bc1a 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -1,4 +1,4 @@ -- breadcrumb_title "Profile" +- breadcrumb_title "Edit Profile" - @content_class = "limit-container-width" unless fluid_layout = render 'profiles/head' diff --git a/app/views/projects/activity.html.haml b/app/views/projects/activity.html.haml index 5452c6db6a6..f80dadb8037 100644 --- a/app/views/projects/activity.html.haml +++ b/app/views/projects/activity.html.haml @@ -1,9 +1,7 @@ - @no_container = true -- if show_new_nav? - - add_to_breadcrumbs(_("Project"), project_path(@project)) - - page_title _("Activity") + = render "projects/head" = render 'projects/last_push' diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml index 2076e46fde8..66aa99e964b 100644 --- a/app/views/projects/boards/_show.html.haml +++ b/app/views/projects/boards/_show.html.haml @@ -1,10 +1,8 @@ - @no_container = true - @content_class = "issue-boards-content" +- breadcrumb_title "Issue Board" - page_title "Boards" -- if show_new_nav? - - add_to_breadcrumbs("Issues", project_issues_path(@project)) - - content_for :page_specific_javascripts do = webpack_bundle_tag 'common_vue' = webpack_bundle_tag 'filtered_search' diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml index 945a5c11d6d..73583c6bbc2 100644 --- a/app/views/projects/branches/index.html.haml +++ b/app/views/projects/branches/index.html.haml @@ -2,9 +2,6 @@ - page_title "Branches" = render "projects/commits/head" -- if show_new_nav? - - add_to_breadcrumbs("Repository", project_tree_path(@project)) - %div{ class: container_class } .top-area.adjust - if can?(current_user, :admin_project, @project) diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index 07c83c0a590..b37b3bfd460 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Commit #{@commit.short_id}" - container_class = !fluid_layout && diff_view == :inline ? 'container-limited' : '' - limited_container_width = fluid_layout ? '' : 'limit-container-width' - @content_class = limited_container_width diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml index 7ae56086177..e873b931683 100644 --- a/app/views/projects/commits/show.html.haml +++ b/app/views/projects/commits/show.html.haml @@ -5,9 +5,6 @@ = content_for :meta_tags do = auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, rss_url_options), title: "#{@project.name}:#{@ref} commits") -- if show_new_nav? - - add_to_breadcrumbs("Repository", project_tree_path(@project)) - = content_for :sub_nav do = render "head" diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml index 05de21e8dbf..2cf14859f30 100644 --- a/app/views/projects/compare/index.html.haml +++ b/app/views/projects/compare/index.html.haml @@ -1,7 +1,5 @@ - @no_container = true - page_title "Compare" -- if show_new_nav? - - add_to_breadcrumbs("Repository", project_tree_path(@project)) = render "projects/commits/head" %div{ class: container_class } diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml index 8bc863f77b3..8cfa279bd68 100644 --- a/app/views/projects/compare/show.html.haml +++ b/app/views/projects/compare/show.html.haml @@ -1,8 +1,6 @@ - @no_container = true - breadcrumb_title "Compare" - page_title "#{params[:from]}...#{params[:to]}" -- if show_new_nav? - - add_to_breadcrumbs("Repository", project_tree_path(@project)) = render "projects/commits/head" %div{ class: container_class } diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml index 3467e357c49..8d008be5aae 100644 --- a/app/views/projects/cycle_analytics/show.html.haml +++ b/app/views/projects/cycle_analytics/show.html.haml @@ -1,7 +1,5 @@ - @no_container = true - page_title "Cycle Analytics" -- if show_new_nav? - - add_to_breadcrumbs("Project", project_path(@project)) - content_for :page_specific_javascripts do = page_specific_javascript_bundle_tag('common_vue') = page_specific_javascript_bundle_tag('cycle_analytics') diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml index 6178abe9160..fcc4b5c06c7 100644 --- a/app/views/projects/edit.html.haml +++ b/app/views/projects/edit.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "General Settings" - page_title "General" - @content_class = "limit-container-width" unless fluid_layout - expanded = Rails.env.test? diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml index d17709380d5..5e980314307 100644 --- a/app/views/projects/empty.html.haml +++ b/app/views/projects/empty.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Details" = render partial: 'flash_messages', locals: { project: @project } diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml index d0f723af5bf..30cdbc5ae04 100644 --- a/app/views/projects/environments/index.html.haml +++ b/app/views/projects/environments/index.html.haml @@ -2,9 +2,6 @@ - page_title "Environments" = render "projects/pipelines/head" -- if show_new_nav? - - add_to_breadcrumbs("Pipelines", project_pipelines_path(@project)) - - content_for :page_specific_javascripts do = page_specific_javascript_bundle_tag('common_vue') = page_specific_javascript_bundle_tag("environments") diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml index 0ce0f5465fc..0d0bc499dfa 100644 --- a/app/views/projects/environments/show.html.haml +++ b/app/views/projects/environments/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Enviroment '#{@environment.name}'" - page_title "Environments" = render "projects/pipelines/head" diff --git a/app/views/projects/graphs/charts.html.haml b/app/views/projects/graphs/charts.html.haml index 9f5a1239a82..f0ef647ddb3 100644 --- a/app/views/projects/graphs/charts.html.haml +++ b/app/views/projects/graphs/charts.html.haml @@ -1,7 +1,5 @@ - @no_container = true - page_title "Charts" -- if show_new_nav? - - add_to_breadcrumbs("Repository", project_tree_path(@project)) - content_for :page_specific_javascripts do = webpack_bundle_tag('common_d3') = webpack_bundle_tag('graphs') diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml index f41a0d8293b..08b38428b50 100644 --- a/app/views/projects/graphs/show.html.haml +++ b/app/views/projects/graphs/show.html.haml @@ -5,9 +5,6 @@ = webpack_bundle_tag('graphs') = webpack_bundle_tag('graphs_show') -- if show_new_nav? - - add_to_breadcrumbs("Repository", project_tree_path(@project)) - = render 'projects/commits/head' .js-graphs-show{ class: container_class, 'data-project-graph-path': project_graph_path(@project, current_ref, format: :json) } diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index ad5befc6ee5..4c27083f54f 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -1,4 +1,5 @@ - @content_class = "limit-container-width" unless fluid_layout +- breadcrumb_title "Issues #{@issue.to_reference}" - page_title "#{@issue.title} (#{@issue.to_reference})", "Issues" - page_description @issue.description - page_card_attributes @issue.card_attributes diff --git a/app/views/projects/jobs/index.html.haml b/app/views/projects/jobs/index.html.haml index d78891546f7..8604c7d3ea4 100644 --- a/app/views/projects/jobs/index.html.haml +++ b/app/views/projects/jobs/index.html.haml @@ -2,9 +2,6 @@ - page_title "Jobs" = render "projects/pipelines/head" -- if show_new_nav? - - add_to_breadcrumbs("Pipelines", project_pipelines_path(@project)) - %div{ class: container_class } .top-area - build_path_proc = ->(scope) { project_jobs_path(@project, scope: scope) } diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml index fa086413fbe..2c76ca91155 100644 --- a/app/views/projects/jobs/show.html.haml +++ b/app/views/projects/jobs/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Jobs ##{@build.id}" - page_title "#{@build.name} (##{@build.id})", "Jobs" = render "projects/pipelines/head" diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index d27e121beb4..f6132300c40 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -1,4 +1,5 @@ - @content_class = "limit-container-width" unless fluid_layout +- breadcrumb_title "Merge Requests #{@merge_request.to_reference}" - page_title "#{@merge_request.title} (#{@merge_request.to_reference})", "Merge Requests" - page_description @merge_request.description - page_card_attributes @merge_request.card_attributes diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 0bf0e11c107..4137bddef6f 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Milestone #{@milestone.title}" - page_title @milestone.title, "Milestones" - page_description @milestone.description = render "shared/mr_head" diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml index ab948df4a3f..e29cb277389 100644 --- a/app/views/projects/network/show.html.haml +++ b/app/views/projects/network/show.html.haml @@ -2,8 +2,6 @@ - page_title "Graph", @ref - content_for :page_specific_javascripts do = page_specific_javascript_bundle_tag('network') -- if show_new_nav? - - add_to_breadcrumbs("Repository", project_tree_path(@project)) = render "projects/commits/head" = render "head" %div{ class: container_class } diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml index fd3ad69d85d..96da90362c4 100644 --- a/app/views/projects/pipelines/charts.html.haml +++ b/app/views/projects/pipelines/charts.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "CI / CD Charts" - page_title _("Charts"), _("Pipelines") - if show_new_nav? - add_to_breadcrumbs("Pipelines", project_pipelines_path(@project)) diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml index 63f85fc69a2..bb25cfb440c 100644 --- a/app/views/projects/pipelines/show.html.haml +++ b/app/views/projects/pipelines/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Pipelines ##{@pipeline.id}" - page_title "Pipeline" = render "projects/pipelines/head" diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml index 9f7c5a315eb..25153fd0b6f 100644 --- a/app/views/projects/project_members/index.html.haml +++ b/app/views/projects/project_members/index.html.haml @@ -1,8 +1,5 @@ - page_title "Members" -- if show_new_nav? - - add_to_breadcrumbs("Settings", edit_project_path(@project)) - .row.prepend-top-default .col-lg-12 %h4 diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml index 0c4130857da..099e3b8493f 100644 --- a/app/views/projects/settings/ci_cd/show.html.haml +++ b/app/views/projects/settings/ci_cd/show.html.haml @@ -1,8 +1,6 @@ - @content_class = "limit-container-width" unless fluid_layout -- page_title "Pipelines" - -- if show_new_nav? - - add_to_breadcrumbs("Settings", edit_project_path(@project)) +- page_title "CI / CD Settings" +- page_title "CI / CD" = render "projects/settings/head" diff --git a/app/views/projects/settings/integrations/show.html.haml b/app/views/projects/settings/integrations/show.html.haml index 149da96d3f6..933daa7f549 100644 --- a/app/views/projects/settings/integrations/show.html.haml +++ b/app/views/projects/settings/integrations/show.html.haml @@ -1,7 +1,6 @@ - @content_class = "limit-container-width" unless fluid_layout +- breadcrumb_title "Integrations Settings" - page_title 'Integrations' -- if show_new_nav? - - add_to_breadcrumbs("Settings", edit_project_path(@project)) = render "projects/settings/head" = render 'projects/hooks/index' = render 'projects/services/index' diff --git a/app/views/projects/settings/repository/show.html.haml b/app/views/projects/settings/repository/show.html.haml index cb37f3c7580..6d4af72b8ea 100644 --- a/app/views/projects/settings/repository/show.html.haml +++ b/app/views/projects/settings/repository/show.html.haml @@ -1,9 +1,7 @@ +- breadcrumb_title "Repository Settings" - page_title "Repository" - @content_class = "limit-container-width" unless fluid_layout -- if show_new_nav? - - add_to_breadcrumbs("Settings", edit_project_path(@project)) - = render "projects/settings/head" - content_for :page_specific_javascripts do diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index a9b39cedb1d..3f0a24cfe83 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -1,5 +1,5 @@ - @no_container = true -- breadcrumb_title "Project" +- breadcrumb_title "Details" - @content_class = "limit-container-width" unless fluid_layout = content_for :meta_tags do diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index d8e448dd2af..ff59d26441f 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -1,4 +1,5 @@ - @content_class = "limit-container-width limited-inner-width-container" unless fluid_layout +- breadcrumb_title "Snippet #{@snippet.to_reference}" - page_title "#{@snippet.title} (#{@snippet.to_reference})", "Snippets" = render 'shared/snippets/header' diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml index 00000e0667c..bf97cbc1f68 100644 --- a/app/views/projects/tags/index.html.haml +++ b/app/views/projects/tags/index.html.haml @@ -3,9 +3,6 @@ - page_title "Tags" = render "projects/commits/head" -- if show_new_nav? - - add_to_breadcrumbs("Repository", project_tree_path(@project)) - .flex-list{ class: container_class } .top-area.adjust .nav-text.row-main-content diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml index d02cd70f4c3..3b6601f4dcf 100644 --- a/app/views/projects/tags/show.html.haml +++ b/app/views/projects/tags/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Tags #{@tag.name}" - page_title @tag.name, "Tags" = render "projects/commits/head" -- cgit v1.2.1 From a10cc2202dffcf8b4a7bc7db22757ac83bf95eb4 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 16 Aug 2017 13:13:34 +0100 Subject: added collapsible sub-groups & wiki pages [ci skip] --- app/assets/javascripts/breadcrumb.js | 20 ++++++++++++++++++++ app/assets/javascripts/main.js | 3 +++ app/assets/stylesheets/framework/dropdowns.scss | 4 ++++ app/assets/stylesheets/new_nav.scss | 20 ++++++-------------- app/assets/stylesheets/pages/commits.scss | 2 +- app/helpers/breadcrumbs_helper.rb | 6 ++++++ app/helpers/groups_helper.rb | 20 ++++++++++++++------ app/helpers/projects_helper.rb | 2 +- app/helpers/wiki_helper.rb | 11 +++++++++++ app/views/layouts/nav/_breadcrumbs.html.haml | 11 +++++------ .../nav/breadcrumbs/_collapsed_dropdown.html.haml | 11 +++++++++++ app/views/projects/wikis/show.html.haml | 11 ++++++++--- 12 files changed, 90 insertions(+), 31 deletions(-) create mode 100644 app/assets/javascripts/breadcrumb.js create mode 100644 app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml (limited to 'app') diff --git a/app/assets/javascripts/breadcrumb.js b/app/assets/javascripts/breadcrumb.js new file mode 100644 index 00000000000..7dfdf844325 --- /dev/null +++ b/app/assets/javascripts/breadcrumb.js @@ -0,0 +1,20 @@ +export const addTooltipToEl = (el) => { + if (el.scrollWidth > el.offsetWidth) { + el.setAttribute('title', el.textContent); + el.setAttribute('data-container', 'body'); + el.classList.add('has-tooltip'); + } +}; + +export default () => { + const breadcrumbs = document.querySelector('.breadcrumbs-list'); + const topLevelLinks = breadcrumbs.querySelectorAll('.breadcrumbs-list > li > a'); + const $expander = $('.js-breadcrumbs-collapsed-expander'); + + topLevelLinks.forEach(el => addTooltipToEl(el)); + + $expander.closest('.dropdown') + .on('show.bs.dropdown hide.bs.dropdown', () => { + $expander.toggleClass('open'); + }); +}; diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 6d7c7e3c930..928394f4fae 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -142,6 +142,7 @@ import './smart_interval'; import './star'; import './subscription'; import './subscription_select'; +import initBreadcrumbs from './breadcrumb'; import './dispatcher'; @@ -179,6 +180,8 @@ $(function () { var bootstrapBreakpoint = bp.getBreakpointSize(); var fitSidebarForSize; + initBreadcrumbs(); + // Set the default path for all cookies to GitLab's root directory Cookies.defaults.path = gon.relative_url_root || '/'; diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 958159b507a..b60f69a5d37 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -782,3 +782,7 @@ margin-top: 2px; } } + +.breadcrumbs-list { + @include new-style-dropdown; +} diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index c1168734198..b1d1ea1ba5f 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -315,19 +315,11 @@ header.navbar-gitlab-new { border: 1px solid $border-color; border-radius: 50%; vertical-align: sub; - - &.identicon { - float: left; - width: 16px; - height: 16px; - margin-top: 2px; - font-size: 10px; - } } .text-expander { - margin-left: 4px; - margin-right: 4px; + margin-left: 0; + margin-right: 2px; > i { position: relative; @@ -352,11 +344,11 @@ header.navbar-gitlab-new { &:not(:first-child) { margin-left: 10px; } - } - a { - @include str-truncated(128px); - color: currentColor; + > a { + @include str-truncated(128px); + color: currentColor; + } } } diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss index 46fbfe5f91e..01f5d2b67aa 100644 --- a/app/assets/stylesheets/pages/commits.scss +++ b/app/assets/stylesheets/pages/commits.scss @@ -151,7 +151,7 @@ outline: none; &.open { - background: $gray-light; + background-color: darken($gray-light, 10%); box-shadow: inset 0 0 2px rgba($black, 0.2); } diff --git a/app/helpers/breadcrumbs_helper.rb b/app/helpers/breadcrumbs_helper.rb index 044cc905eb4..d4c3e1b3929 100644 --- a/app/helpers/breadcrumbs_helper.rb +++ b/app/helpers/breadcrumbs_helper.rb @@ -30,4 +30,10 @@ module BreadcrumbsHelper output end end + + def add_to_breadcrumb_dropdown(link, location: :before) + @breadcrumb_dropdown_links ||= {} + @breadcrumb_dropdown_links[location] = [] unless @breadcrumb_dropdown_links[location] + @breadcrumb_dropdown_links[location] << link + end end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 1badaf721f2..51acd557ea7 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -16,11 +16,19 @@ module GroupsHelper full_title = '' group.ancestors.reverse.each_with_index do |parent, index| - full_title += if show_new_nav? - breadcrumb_list_item group_title_link(parent, hidable: index > 0) - else - group_title_link(parent, hidable: true) - end + if show_new_nav? && index > 0 + add_to_breadcrumb_dropdown(group_title_link(parent, hidable: false), location: :before) + else + full_title += if show_new_nav? + breadcrumb_list_item group_title_link(parent, hidable: false) + else + group_title_link(parent, hidable: true) + end + end + end + + if show_new_nav? + full_title += render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :before, title: _("Show parent subgroups") end full_title += if show_new_nav? @@ -78,7 +86,7 @@ module GroupsHelper def group_title_link(group, hidable: false) link_to(group_path(group), class: "group-path #{'hidable' if hidable}") do output = - if show_new_nav? + if show_new_nav? && group.try(:avatar_url) image_tag(group_icon(group), class: "avatar-tile", width: 16, height: 16) else "" diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 9e325564d23..cd62835fd29 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -60,7 +60,7 @@ module ProjectsHelper project_link = link_to project_path(project), { class: ("project-item-select-holder" unless show_new_nav?) } do output = - if show_new_nav? + if show_new_nav? && project.avatar_url project_icon(project, alt: project.name, class: 'avatar-tile', width: 16, height: 16) else "" diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb index 99212a3438f..3d26c92e58a 100644 --- a/app/helpers/wiki_helper.rb +++ b/app/helpers/wiki_helper.rb @@ -10,4 +10,15 @@ module WikiHelper .map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize } .join(' / ') end + + def wiki_breadcrumb_dropdown_links(page_slug) + page_slug_split = page_slug.split('/') + page_slug_split.pop(1) + current_slug = "" + page_slug_split + .map do |dir_or_page| + current_slug = "#{current_slug}/#{dir_or_page}" + add_to_breadcrumb_dropdown link_to(WikiPage.unhyphenize(dir_or_page).capitalize, project_wiki_path(@project, current_slug)), location: :after + end + end end diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 875b5b7be11..240aee19a9e 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -10,14 +10,13 @@ .breadcrumbs-links.js-title-container %ul.list-unstyled.breadcrumbs-list - unless hide_top_links - - if content_for?(:header_title_before) - %li= yield :header_title_before = header_title - - if @breadcrumbs_extra_links - - @breadcrumbs_extra_links.each do |extra| - %li= link_to extra[:text], extra[:link] + - if @breadcrumbs_extra_links + - @breadcrumbs_extra_links.each do |extra| + = breadcrumb_list_item link_to(extra[:text], extra[:link]) + = render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after %li - %h2.breadcrumbs-sub-title= link_to @breadcrumb_title, breadcrumb_link + %h2.breadcrumbs-sub-title= @breadcrumb_title - if content_for?(:breadcrumbs_extra) .breadcrumbs-extra.hidden-xs= yield :breadcrumbs_extra = yield :header_content diff --git a/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml b/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml new file mode 100644 index 00000000000..ddcc884b83b --- /dev/null +++ b/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml @@ -0,0 +1,11 @@ +- dropdown_location = local_assigns.fetch(:location, nil) +- button_tooltip = local_assigns.fetch(:title, _("Show parent pages")) +- if defined?(@breadcrumb_dropdown_links) && @breadcrumb_dropdown_links.key?(dropdown_location) + %li.dropdown + %button.text-expander.has-tooltip.js-breadcrumbs-collapsed-expander{ type: "button", data: { toggle: "dropdown", container: "body" }, "aria-label": button_tooltip, title: button_tooltip } + = icon("ellipsis-h") + = icon("angle-right", class: "breadcrumbs-list-angle") + .dropdown-menu + %ul + - @breadcrumb_dropdown_links[dropdown_location].each_with_index do |link, index| + %li{ style: "text-indent: #{[index * 15, 60].min}px;"}= link diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml index 9dadd685ea2..5f93168bdde 100644 --- a/app/views/projects/wikis/show.html.haml +++ b/app/views/projects/wikis/show.html.haml @@ -1,13 +1,18 @@ - @content_class = "limit-container-width limit-container-width-sm" unless fluid_layout -- breadcrumb_title "Wiki" +- breadcrumb_title @page.title.capitalize +- wiki_breadcrumb_dropdown_links(@page.slug) - page_title @page.title.capitalize, "Wiki" +- if show_new_nav? + - add_to_breadcrumbs "Wiki", get_project_wiki_path(@project) + .wiki-page-header.has-sidebar-toggle %button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" } = icon('angle-double-left') - .wiki-breadcrumb - %span= breadcrumb(@page.slug) + - unless show_new_nav? + .wiki-breadcrumb + %span= breadcrumb(@page.slug) .nav-text %h2.wiki-page-title= @page.title.capitalize -- cgit v1.2.1 From dae629e5e9a75ef0594399b46191306dcbaab90b Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Aug 2017 10:42:04 +0100 Subject: fix some inconsistencies with the breadcrumbs --- app/assets/javascripts/breadcrumb.js | 5 +++-- app/assets/stylesheets/new_nav.scss | 7 ++----- app/helpers/groups_helper.rb | 2 +- app/helpers/issuables_helper.rb | 19 ++++++++++++++----- app/helpers/projects_helper.rb | 2 +- app/views/layouts/nav/_breadcrumbs.html.haml | 5 ++--- app/views/projects/commit/show.html.haml | 3 ++- app/views/projects/environments/show.html.haml | 3 ++- app/views/projects/issues/show.html.haml | 3 ++- app/views/projects/jobs/show.html.haml | 3 ++- app/views/projects/merge_requests/show.html.haml | 3 ++- app/views/projects/milestones/show.html.haml | 3 ++- app/views/projects/pipelines/show.html.haml | 3 ++- app/views/projects/snippets/show.html.haml | 3 ++- app/views/projects/tags/show.html.haml | 3 ++- app/views/shared/snippets/_header.html.haml | 10 +++++++--- app/views/snippets/show.html.haml | 2 ++ 17 files changed, 50 insertions(+), 29 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/breadcrumb.js b/app/assets/javascripts/breadcrumb.js index 7dfdf844325..97340953c77 100644 --- a/app/assets/javascripts/breadcrumb.js +++ b/app/assets/javascripts/breadcrumb.js @@ -14,7 +14,8 @@ export default () => { topLevelLinks.forEach(el => addTooltipToEl(el)); $expander.closest('.dropdown') - .on('show.bs.dropdown hide.bs.dropdown', () => { - $expander.toggleClass('open'); + .on('show.bs.dropdown hide.bs.dropdown', (e) => { + $('.js-breadcrumbs-collapsed-expander', e.currentTarget).toggleClass('open') + .tooltip('hide'); }); }; diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index b1d1ea1ba5f..8beaf64e7a1 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -330,6 +330,7 @@ header.navbar-gitlab-new { .breadcrumbs-list { display: flex; + flex-wrap: wrap; margin-bottom: 0; > li { @@ -338,11 +339,7 @@ header.navbar-gitlab-new { position: relative; &:not(:last-child) { - margin-right: 10px; - } - - &:not(:first-child) { - margin-left: 10px; + margin-right: 20px; } > a { diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 51acd557ea7..7f43e4106fc 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -22,7 +22,7 @@ module GroupsHelper full_title += if show_new_nav? breadcrumb_list_item group_title_link(parent, hidable: false) else - group_title_link(parent, hidable: true) + "#{group_title_link(parent, hidable: true)} / ".html_safe end end end diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 197c90c4081..eba8aed05d3 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -126,12 +126,21 @@ module IssuablesHelper end def issuable_meta(issuable, project, text) - output = content_tag(:strong, class: "identifier") do - concat("#{text} ") - concat(to_url_reference(issuable)) + output = "" + + unless show_new_nav? + output << content_tag(:strong, class: "identifier") do + concat("#{text} ") + concat(to_url_reference(issuable)) + end end - output << " opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe + opened_text = if show_new_nav? + "Opened" + else + " opened" + end + output << "#{opened_text} #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe output << content_tag(:strong) do author_output = link_to_member(project, issuable.author, size: 24, mobile_classes: "hidden-xs", tooltip: true) author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "hidden-sm hidden-md hidden-lg") @@ -141,7 +150,7 @@ module IssuablesHelper output << content_tag(:span, (issuable.task_status if issuable.tasks?), id: "task_status", class: "hidden-xs hidden-sm") output << content_tag(:span, (issuable.task_status_short if issuable.tasks?), id: "task_status_short", class: "hidden-md hidden-lg") - output + output.html_safe end def issuable_todo(issuable) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index cd62835fd29..867f3fadfb9 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -81,7 +81,7 @@ module ProjectsHelper end end - "#{namespace_link} #{project_link}".html_safe + "#{namespace_link} #{('/' unless show_new_nav?)} #{project_link}".html_safe end def remove_project_message(project) diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 240aee19a9e..9f0cb2fad3a 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -1,8 +1,7 @@ -- breadcrumb_link = breadcrumb_title_link - hide_top_links = @hide_top_links || false -%nav.breadcrumbs{ role: "navigation" } - .breadcrumbs-container{ class: [container_class, @content_class] } +%nav.breadcrumbs{ role: "navigation", class: [container_class, @content_class] } + .breadcrumbs-container - if defined?(@new_sidebar) = button_tag class: 'toggle-mobile-nav', type: 'button' do %span.sr-only Open sidebar diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index b37b3bfd460..c282b1fe2f9 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -1,5 +1,6 @@ - @no_container = true -- breadcrumb_title "Commit #{@commit.short_id}" +- add_to_breadcrumbs "Commit", project_commits_path(@project) +- breadcrumb_title @commit.short_id - container_class = !fluid_layout && diff_view == :inline ? 'container-limited' : '' - limited_container_width = fluid_layout ? '' : 'limit-container-width' - @content_class = limited_container_width diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml index 0d0bc499dfa..c35d1b5aaee 100644 --- a/app/views/projects/environments/show.html.haml +++ b/app/views/projects/environments/show.html.haml @@ -1,5 +1,6 @@ - @no_container = true -- breadcrumb_title "Enviroment '#{@environment.name}'" +- add_to_breadcrumbs "Environments", project_environments_path(@project) +- breadcrumb_title @environment.name - page_title "Environments" = render "projects/pipelines/head" diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml index 4c27083f54f..fd4588ca101 100644 --- a/app/views/projects/issues/show.html.haml +++ b/app/views/projects/issues/show.html.haml @@ -1,5 +1,6 @@ - @content_class = "limit-container-width" unless fluid_layout -- breadcrumb_title "Issues #{@issue.to_reference}" +- add_to_breadcrumbs "Issues", project_issues_path(@project) +- breadcrumb_title @issue.to_reference - page_title "#{@issue.title} (#{@issue.to_reference})", "Issues" - page_description @issue.description - page_card_attributes @issue.card_attributes diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml index 2c76ca91155..975c08c06e6 100644 --- a/app/views/projects/jobs/show.html.haml +++ b/app/views/projects/jobs/show.html.haml @@ -1,5 +1,6 @@ - @no_container = true -- breadcrumb_title "Jobs ##{@build.id}" +- add_to_breadcrumbs "Jobs", project_jobs_path(@project) +- breadcrumb_title "##{@build.id}" - page_title "#{@build.name} (##{@build.id})", "Jobs" = render "projects/pipelines/head" diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index f6132300c40..c2d16f7e731 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -1,5 +1,6 @@ - @content_class = "limit-container-width" unless fluid_layout -- breadcrumb_title "Merge Requests #{@merge_request.to_reference}" +- add_to_breadcrumbs "Merge Requests", project_merge_requests_path(@project) +- breadcrumb_title @merge_request.to_reference - page_title "#{@merge_request.title} (#{@merge_request.to_reference})", "Merge Requests" - page_description @merge_request.description - page_card_attributes @merge_request.card_attributes diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index 4137bddef6f..1f5f18801ad 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -1,5 +1,6 @@ - @no_container = true -- breadcrumb_title "Milestone #{@milestone.title}" +- add_to_breadcrumbs "Milestones", project_milestones_path(@project) +- breadcrumb_title @milestone.title - page_title @milestone.title, "Milestones" - page_description @milestone.description = render "shared/mr_head" diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml index bb25cfb440c..7cc9fe79afd 100644 --- a/app/views/projects/pipelines/show.html.haml +++ b/app/views/projects/pipelines/show.html.haml @@ -1,5 +1,6 @@ - @no_container = true -- breadcrumb_title "Pipelines ##{@pipeline.id}" +- add_to_breadcrumbs "Pipelines", project_pipelines_path(@project) +- breadcrumb_title "##{@pipeline.id}" - page_title "Pipeline" = render "projects/pipelines/head" diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml index ff59d26441f..fda068f08c2 100644 --- a/app/views/projects/snippets/show.html.haml +++ b/app/views/projects/snippets/show.html.haml @@ -1,5 +1,6 @@ - @content_class = "limit-container-width limited-inner-width-container" unless fluid_layout -- breadcrumb_title "Snippet #{@snippet.to_reference}" +- add_to_breadcrumbs "Snippets", dashboard_snippets_path +- breadcrumb_title @snippet.to_reference - page_title "#{@snippet.title} (#{@snippet.to_reference})", "Snippets" = render 'shared/snippets/header' diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml index 3b6601f4dcf..5d6eb4f4026 100644 --- a/app/views/projects/tags/show.html.haml +++ b/app/views/projects/tags/show.html.haml @@ -1,5 +1,6 @@ - @no_container = true -- breadcrumb_title "Tags #{@tag.name}" +- add_to_breadcrumbs "Tags", project_tags_path(@project) +- breadcrumb_title @tag.name - page_title @tag.name, "Tags" = render "projects/commits/head" diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml index 17b34c5eeb3..03bc0b25055 100644 --- a/app/views/shared/snippets/_header.html.haml +++ b/app/views/shared/snippets/_header.html.haml @@ -3,10 +3,14 @@ %span.sr-only = visibility_level_label(@snippet.visibility_level) = visibility_level_icon(@snippet.visibility_level, fw: false) - %strong.item-title - Snippet #{@snippet.to_reference} + - unless show_new_nav? + %strong.item-title + Snippet #{@snippet.to_reference} %span.creator - authored + - if show_new_nav? + Authored + - else + authored = time_ago_with_tooltip(@snippet.created_at, placement: 'bottom', html_class: 'snippet_updated_ago') by #{link_to_member(@project, @snippet.author, size: 24, author_class: "author item-title", avatar_class: "hidden-xs")} diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml index 706f13dd004..578327883e5 100644 --- a/app/views/snippets/show.html.haml +++ b/app/views/snippets/show.html.haml @@ -1,5 +1,7 @@ - @hide_top_links = true - @content_class = "limit-container-width limited-inner-width-container" unless fluid_layout +- add_to_breadcrumbs "Snippets", dashboard_snippets_path +- breadcrumb_title @snippet.to_reference - page_title "#{@snippet.title} (#{@snippet.to_reference})", "Snippets" = render 'shared/snippets/header' -- cgit v1.2.1 From bec6ea20f6933f07cb616c29ce72efc076a97dc0 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Aug 2017 14:00:50 +0100 Subject: fixed breadcrumbs being undefined --- app/assets/javascripts/breadcrumb.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/breadcrumb.js b/app/assets/javascripts/breadcrumb.js index 97340953c77..7433fcbbad1 100644 --- a/app/assets/javascripts/breadcrumb.js +++ b/app/assets/javascripts/breadcrumb.js @@ -8,14 +8,17 @@ export const addTooltipToEl = (el) => { export default () => { const breadcrumbs = document.querySelector('.breadcrumbs-list'); - const topLevelLinks = breadcrumbs.querySelectorAll('.breadcrumbs-list > li > a'); - const $expander = $('.js-breadcrumbs-collapsed-expander'); - topLevelLinks.forEach(el => addTooltipToEl(el)); + if (breadcrumbs) { + const topLevelLinks = breadcrumbs.querySelectorAll('.breadcrumbs-list > li > a'); + const $expander = $('.js-breadcrumbs-collapsed-expander'); - $expander.closest('.dropdown') - .on('show.bs.dropdown hide.bs.dropdown', (e) => { - $('.js-breadcrumbs-collapsed-expander', e.currentTarget).toggleClass('open') - .tooltip('hide'); - }); + topLevelLinks.forEach(el => addTooltipToEl(el)); + + $expander.closest('.dropdown') + .on('show.bs.dropdown hide.bs.dropdown', (e) => { + $('.js-breadcrumbs-collapsed-expander', e.currentTarget).toggleClass('open') + .tooltip('hide'); + }); + } }; -- cgit v1.2.1 From d5ab1000aa705558db7b7b1e2a8f49bbc72f3db2 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Thu, 17 Aug 2017 15:53:50 +0100 Subject: various breadcrumb updates --- app/views/admin/applications/edit.html.haml | 2 ++ app/views/admin/cohorts/index.html.haml | 1 + app/views/admin/dashboard/index.html.haml | 1 + app/views/admin/groups/show.html.haml | 2 ++ app/views/admin/hooks/edit.html.haml | 1 + app/views/admin/jobs/index.html.haml | 1 + app/views/admin/labels/edit.html.haml | 2 ++ app/views/admin/projects/show.html.haml | 2 ++ app/views/admin/runners/index.html.haml | 1 + app/views/admin/services/edit.html.haml | 2 ++ app/views/admin/users/show.html.haml | 2 ++ app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml | 2 +- app/views/profiles/passwords/edit.html.haml | 1 + app/views/profiles/personal_access_tokens/index.html.haml | 1 + app/views/projects/commit/show.html.haml | 2 +- app/views/projects/wikis/pages.html.haml | 2 ++ 16 files changed, 23 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/views/admin/applications/edit.html.haml b/app/views/admin/applications/edit.html.haml index 13b583e6072..13c408914bb 100644 --- a/app/views/admin/applications/edit.html.haml +++ b/app/views/admin/applications/edit.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs "Applications", admin_applications_path +- breadcrumb_title @application.name - page_title "Edit", @application.name, "Applications" %h3.page-title Edit application diff --git a/app/views/admin/cohorts/index.html.haml b/app/views/admin/cohorts/index.html.haml index be8644c0ca6..bff53da1d9a 100644 --- a/app/views/admin/cohorts/index.html.haml +++ b/app/views/admin/cohorts/index.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "Cohorts" - @no_container = true = render "admin/dashboard/head" diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 8e94e68bc11..069f8f89e0b 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Dashboard" = render "admin/dashboard/head" %div{ class: container_class } diff --git a/app/views/admin/groups/show.html.haml b/app/views/admin/groups/show.html.haml index 2aadc071c75..3e02f7b1e16 100644 --- a/app/views/admin/groups/show.html.haml +++ b/app/views/admin/groups/show.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs "Groups", admin_groups_path +- breadcrumb_title @group.name - page_title @group.name, "Groups" %h3.page-title Group: #{@group.full_name} diff --git a/app/views/admin/hooks/edit.html.haml b/app/views/admin/hooks/edit.html.haml index 665e8c7e74f..efb15ccc8df 100644 --- a/app/views/admin/hooks/edit.html.haml +++ b/app/views/admin/hooks/edit.html.haml @@ -1,3 +1,4 @@ +- add_to_breadcrumbs "System Hooks", admin_hooks_path - page_title 'Edit System Hook' %h3.page-title Edit System Hook diff --git a/app/views/admin/jobs/index.html.haml b/app/views/admin/jobs/index.html.haml index 09be17f07be..aa6e9db3900 100644 --- a/app/views/admin/jobs/index.html.haml +++ b/app/views/admin/jobs/index.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "Jobs" - @no_container = true = render "admin/dashboard/head" diff --git a/app/views/admin/labels/edit.html.haml b/app/views/admin/labels/edit.html.haml index 309aedceded..96f0d404ac4 100644 --- a/app/views/admin/labels/edit.html.haml +++ b/app/views/admin/labels/edit.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs "Labels", admin_labels_path +- breadcrumb_title "Edit Label" - page_title "Edit", @label.name, "Labels" %h3.page-title Edit Label diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index 7b1b15cfeb8..ab4165c0bf2 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs "Projects", admin_projects_path +- breadcrumb_title @project.name_with_namespace - page_title @project.name_with_namespace, "Projects" %h3.page-title Project: #{@project.name_with_namespace} diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml index 126550ee10e..6793ce557c4 100644 --- a/app/views/admin/runners/index.html.haml +++ b/app/views/admin/runners/index.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "Runners" - @no_container = true = render "admin/dashboard/head" diff --git a/app/views/admin/services/edit.html.haml b/app/views/admin/services/edit.html.haml index 53d970e33c1..512176649e6 100644 --- a/app/views/admin/services/edit.html.haml +++ b/app/views/admin/services/edit.html.haml @@ -1,2 +1,4 @@ +- add_to_breadcrumbs "Service Templates", admin_application_settings_services_path +- breadcrumb_title @service.title - page_title @service.title, "Service Templates" = render 'form' diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index b556ff056c0..98ff592eb64 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs "Users", admin_users_path +- breadcrumb_title @user.name - page_title @user.name, "Users" = render 'admin/users/head' diff --git a/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml b/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml index ddcc884b83b..5454e452a84 100644 --- a/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml +++ b/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml @@ -8,4 +8,4 @@ .dropdown-menu %ul - @breadcrumb_dropdown_links[dropdown_location].each_with_index do |link, index| - %li{ style: "text-indent: #{[index * 15, 60].min}px;"}= link + %li{ style: "text-indent: #{[index * 15, 60].min}px;" }= link diff --git a/app/views/profiles/passwords/edit.html.haml b/app/views/profiles/passwords/edit.html.haml index 985bb79508f..c606b5a1e6c 100644 --- a/app/views/profiles/passwords/edit.html.haml +++ b/app/views/profiles/passwords/edit.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "Edit Password" - page_title "Password" - @content_class = "limit-container-width" unless fluid_layout diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 2216708d354..06bb72b9f0d 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "Access Tokens" - page_title "Personal Access Tokens" - @content_class = "limit-container-width" unless fluid_layout diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index c282b1fe2f9..717de85c5d2 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -1,5 +1,5 @@ - @no_container = true -- add_to_breadcrumbs "Commit", project_commits_path(@project) +- add_to_breadcrumbs "Commits", project_commits_path(@project) - breadcrumb_title @commit.short_id - container_class = !fluid_layout && diff_view == :inline ? 'container-limited' : '' - limited_container_width = fluid_layout ? '' : 'limit-container-width' diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml index dece1fad0bb..d533c611a38 100644 --- a/app/views/projects/wikis/pages.html.haml +++ b/app/views/projects/wikis/pages.html.haml @@ -1,4 +1,6 @@ - @no_container = true +- add_to_breadcrumbs "Wiki", get_project_wiki_path(@project) +- breadcrumb_title "Pages" - page_title "Pages", "Wiki" %div{ class: container_class } -- cgit v1.2.1 From 4e74eb8178faaf364a421a5113877db434d365e8 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 18 Aug 2017 13:54:48 +0100 Subject: removed bottom border from context-header link --- app/assets/stylesheets/new_sidebar.scss | 1 - 1 file changed, 1 deletion(-) (limited to 'app') diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index cee5b22adb9..2642d16d33d 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -45,7 +45,6 @@ $new-sidebar-collapsed-width: 50px; margin-right: 2px; a { - border-bottom: 1px solid $border-color; font-weight: 600; display: flex; align-items: center; -- cgit v1.2.1 From a8460f215cc1949b993e774dc00bad0b506abcfa Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Fri, 18 Aug 2017 17:19:23 +0100 Subject: style updates fixed some more breadcrumb titles --- app/assets/stylesheets/new_nav.scss | 16 ++++++++++++---- app/helpers/groups_helper.rb | 6 +++--- app/helpers/projects_helper.rb | 4 ++-- app/views/groups/subgroups.html.haml | 1 + app/views/layouts/nav/_breadcrumbs.html.haml | 3 ++- .../nav/breadcrumbs/_collapsed_dropdown.html.haml | 2 +- app/views/projects/boards/_show.html.haml | 2 +- app/views/projects/compare/index.html.haml | 1 + app/views/projects/compare/show.html.haml | 2 +- app/views/projects/pipeline_schedules/edit.html.haml | 2 ++ app/views/projects/pipeline_schedules/index.html.haml | 2 +- app/views/projects/releases/edit.html.haml | 2 ++ app/views/projects/snippets/edit.html.haml | 2 ++ app/views/projects/snippets/new.html.haml | 2 ++ 14 files changed, 33 insertions(+), 14 deletions(-) (limited to 'app') diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss index 8beaf64e7a1..2ff1098b8e5 100644 --- a/app/assets/stylesheets/new_nav.scss +++ b/app/assets/stylesheets/new_nav.scss @@ -292,7 +292,7 @@ header.navbar-gitlab-new { .breadcrumbs { display: flex; - min-height: 61px; + min-height: 48px; color: $gl-text-color; } @@ -300,6 +300,8 @@ header.navbar-gitlab-new { display: flex; width: 100%; position: relative; + padding-top: $gl-padding; + padding-bottom: $gl-padding; align-items: center; border-bottom: 1px solid $border-color; } @@ -311,7 +313,7 @@ header.navbar-gitlab-new { color: $gl-text-color-secondary; .avatar-tile { - margin-right: 5px; + margin-right: 4px; border: 1px solid $border-color; border-radius: 50%; vertical-align: sub; @@ -332,6 +334,7 @@ header.navbar-gitlab-new { display: flex; flex-wrap: wrap; margin-bottom: 0; + line-height: 16px; > li { display: flex; @@ -343,16 +346,21 @@ header.navbar-gitlab-new { } > a { - @include str-truncated(128px); + font-size: 12px; color: currentColor; } } } +.breadcrumb-item-project-name { + @include str-truncated(128px); +} + .breadcrumbs-list-angle { position: absolute; right: -12px; top: 50%; + color: $gl-text-color-tertiary; transform: translateY(-50%); } @@ -364,7 +372,7 @@ header.navbar-gitlab-new { .breadcrumbs-sub-title { margin: 0; - font-size: $gl-font-size; + font-size: 12px; font-weight: 600; line-height: 1; diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 7f43e4106fc..3edeb406b36 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -17,7 +17,7 @@ module GroupsHelper group.ancestors.reverse.each_with_index do |parent, index| if show_new_nav? && index > 0 - add_to_breadcrumb_dropdown(group_title_link(parent, hidable: false), location: :before) + add_to_breadcrumb_dropdown(group_title_link(parent, hidable: false, show_avatar: true), location: :before) else full_title += if show_new_nav? breadcrumb_list_item group_title_link(parent, hidable: false) @@ -83,10 +83,10 @@ module GroupsHelper private - def group_title_link(group, hidable: false) + def group_title_link(group, hidable: false, show_avatar: false) link_to(group_path(group), class: "group-path #{'hidable' if hidable}") do output = - if show_new_nav? && group.try(:avatar_url) + if show_new_nav? && group.try(:avatar_url) || (show_new_nav? && show_avatar) image_tag(group_icon(group), class: "avatar-tile", width: 16, height: 16) else "" diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 867f3fadfb9..5f61dafaae5 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -52,7 +52,7 @@ module ProjectsHelper def project_title(project) namespace_link = if project.group - group_title(project.group) + group_title(project.group, nil, nil) else owner = project.namespace.owner link_to(simple_sanitize(owner.name), user_path(owner)) @@ -66,7 +66,7 @@ module ProjectsHelper "" end - output << simple_sanitize(project.name) + output << content_tag("span", simple_sanitize(project.name), class: "breadcrumb-item-project-name") output.html_safe end diff --git a/app/views/groups/subgroups.html.haml b/app/views/groups/subgroups.html.haml index 8f0724c0677..7abc84412c6 100644 --- a/app/views/groups/subgroups.html.haml +++ b/app/views/groups/subgroups.html.haml @@ -1,3 +1,4 @@ +- breadcrumb_title "Details" - @no_container = true = render 'head' diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 9f0cb2fad3a..8933fdd14db 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -13,7 +13,8 @@ - if @breadcrumbs_extra_links - @breadcrumbs_extra_links.each do |extra| = breadcrumb_list_item link_to(extra[:text], extra[:link]) - = render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after + - if defined?(@breadcrumb_dropdown_links) && @breadcrumb_dropdown_links.key?(:after) + = render "layouts/nav/breadcrumbs/collapsed_dropdown", items: @breadcrumb_dropdown_links[:after] %li %h2.breadcrumbs-sub-title= @breadcrumb_title - if content_for?(:breadcrumbs_extra) diff --git a/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml b/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml index 5454e452a84..28022eebb19 100644 --- a/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml +++ b/app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml @@ -8,4 +8,4 @@ .dropdown-menu %ul - @breadcrumb_dropdown_links[dropdown_location].each_with_index do |link, index| - %li{ style: "text-indent: #{[index * 15, 60].min}px;" }= link + %li{ style: "text-indent: #{[index * 16, 60].min}px;" }= link diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml index 66aa99e964b..cea942f213d 100644 --- a/app/views/projects/boards/_show.html.haml +++ b/app/views/projects/boards/_show.html.haml @@ -1,6 +1,6 @@ - @no_container = true - @content_class = "issue-boards-content" -- breadcrumb_title "Issue Board" +- breadcrumb_title "Issues Board" - page_title "Boards" - content_for :page_specific_javascripts do diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml index 2cf14859f30..2632fea6eba 100644 --- a/app/views/projects/compare/index.html.haml +++ b/app/views/projects/compare/index.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- breadcrumb_title "Compare Revisions" - page_title "Compare" = render "projects/commits/head" diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml index 8cfa279bd68..7cc42455394 100644 --- a/app/views/projects/compare/show.html.haml +++ b/app/views/projects/compare/show.html.haml @@ -1,5 +1,5 @@ - @no_container = true -- breadcrumb_title "Compare" +- add_to_breadcrumbs "Compare Revisions", project_compare_index_path(@project) - page_title "#{params[:from]}...#{params[:to]}" = render "projects/commits/head" diff --git a/app/views/projects/pipeline_schedules/edit.html.haml b/app/views/projects/pipeline_schedules/edit.html.haml index 9b2a7b5821d..d95fa6da903 100644 --- a/app/views/projects/pipeline_schedules/edit.html.haml +++ b/app/views/projects/pipeline_schedules/edit.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs _("Schedules"), pipeline_schedules_path(@project) +- breadcrumb_title "##{@schedule.id}" - page_title _("Edit"), @schedule.description, _("Pipeline Schedule") %h3.page-title diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml index 8426b29bb14..9197d9ae8fc 100644 --- a/app/views/projects/pipeline_schedules/index.html.haml +++ b/app/views/projects/pipeline_schedules/index.html.haml @@ -1,4 +1,4 @@ -- breadcrumb_title "Schedules" +- breadcrumb_title _("Schedules") - content_for :page_specific_javascripts do = webpack_bundle_tag 'common_vue' diff --git a/app/views/projects/releases/edit.html.haml b/app/views/projects/releases/edit.html.haml index 0a5a38a3694..c786298e341 100644 --- a/app/views/projects/releases/edit.html.haml +++ b/app/views/projects/releases/edit.html.haml @@ -1,4 +1,6 @@ - @no_container = true +- add_to_breadcrumbs "Tags", project_tags_path(@project) +- breadcrumb_title @tag.name - page_title "Edit", @tag.name, "Tags" = render "projects/commits/head" diff --git a/app/views/projects/snippets/edit.html.haml b/app/views/projects/snippets/edit.html.haml index d41cc8e0425..32844f5204a 100644 --- a/app/views/projects/snippets/edit.html.haml +++ b/app/views/projects/snippets/edit.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs "Snippets", project_snippets_path(@project) +- breadcrumb_title @snippet.to_reference - page_title "Edit", "#{@snippet.title} (#{@snippet.to_reference})", "Snippets" %h3.page-title diff --git a/app/views/projects/snippets/new.html.haml b/app/views/projects/snippets/new.html.haml index d3e6b456f48..1359a815429 100644 --- a/app/views/projects/snippets/new.html.haml +++ b/app/views/projects/snippets/new.html.haml @@ -1,3 +1,5 @@ +- add_to_breadcrumbs "Snippets", project_snippets_path(@project) +- breadcrumb_title "New" - page_title "New Snippets" %h3.page-title -- cgit v1.2.1 From 62ef67acc3a8d260aa3e641b350aaecf8d60f1aa Mon Sep 17 00:00:00 2001 From: Robin Bobbitt Date: Fri, 4 Aug 2017 09:17:20 -0400 Subject: Hide read_registry scope when registry is disabled on instance --- app/models/personal_access_token.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index 654be927ed8..ec0ebe4d353 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -28,7 +28,7 @@ class PersonalAccessToken < ActiveRecord::Base protected def validate_scopes - unless scopes.all? { |scope| Gitlab::Auth::AVAILABLE_SCOPES.include?(scope.to_sym) } + unless revoked || scopes.all? { |scope| Gitlab::Auth::AVAILABLE_SCOPES.include?(scope.to_sym) } errors.add :scopes, "can only contain available scopes" end end -- cgit v1.2.1 From 85c3128a505a999b2ac775aac1336a0d27e7df55 Mon Sep 17 00:00:00 2001 From: Jeff Stubler Date: Thu, 24 Aug 2017 09:50:47 -0500 Subject: Fix division by zero for blame age map --- app/helpers/blame_helper.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'app') diff --git a/app/helpers/blame_helper.rb b/app/helpers/blame_helper.rb index d1dc4d94560..089d9e3e387 100644 --- a/app/helpers/blame_helper.rb +++ b/app/helpers/blame_helper.rb @@ -11,11 +11,15 @@ module BlameHelper end def age_map_class(commit_date, duration) - commit_date_days_ago = (duration[:now] - commit_date).to_i / 1.day - # Numbers 0 to 10 come from this calculation, but only commits on the oldest - # day get number 10 (all other numbers can be multiple days), so the range - # is normalized to 0-9 - age_group = [(10 * commit_date_days_ago) / duration[:started_days_ago], 9].min - "blame-commit-age-#{age_group}" + if duration[:started_days_ago] == 0 + "blame-commit-age-0" + else + commit_date_days_ago = (duration[:now] - commit_date).to_i / 1.day + # Numbers 0 to 10 come from this calculation, but only commits on the oldest + # day get number 10 (all other numbers can be multiple days), so the range + # is normalized to 0-9 + age_group = [(10 * commit_date_days_ago) / duration[:started_days_ago], 9].min + "blame-commit-age-#{age_group}" + end end end -- cgit v1.2.1 From f2a43ff5b7eec188ffc470649bf40d268cbdce2a Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Mon, 28 Aug 2017 18:56:49 -0300 Subject: Group boards CE backport --- app/controllers/boards/application_controller.rb | 21 +++++ app/controllers/boards/issues_controller.rb | 89 ++++++++++++++++++++ app/controllers/boards/lists_controller.rb | 74 +++++++++++++++++ .../projects/boards/application_controller.rb | 15 ---- .../projects/boards/issues_controller.rb | 94 ---------------------- .../projects/boards/lists_controller.rb | 86 -------------------- app/controllers/projects/boards_controller.rb | 27 +++---- app/helpers/boards_helper.rb | 78 ++++++++++++++++-- app/helpers/issuables_helper.rb | 8 ++ app/helpers/labels_helper.rb | 7 +- app/helpers/search_helper.rb | 14 ++-- app/models/board.rb | 6 +- app/models/concerns/relative_positioning.rb | 14 ++-- app/models/label.rb | 3 +- app/models/project.rb | 8 ++ app/services/boards/base_service.rb | 10 +++ app/services/boards/create_service.rb | 6 +- app/services/boards/issues/create_service.rb | 12 ++- app/services/boards/issues/list_service.rb | 8 +- app/services/boards/issues/move_service.rb | 20 ++--- app/services/boards/list_service.rb | 8 +- app/services/boards/lists/create_service.rb | 7 +- app/services/boards/lists/generate_service.rb | 4 +- app/services/issues/update_service.rb | 14 ++-- 24 files changed, 366 insertions(+), 267 deletions(-) create mode 100644 app/controllers/boards/application_controller.rb create mode 100644 app/controllers/boards/issues_controller.rb create mode 100644 app/controllers/boards/lists_controller.rb delete mode 100644 app/controllers/projects/boards/application_controller.rb delete mode 100644 app/controllers/projects/boards/issues_controller.rb delete mode 100644 app/controllers/projects/boards/lists_controller.rb create mode 100644 app/services/boards/base_service.rb (limited to 'app') diff --git a/app/controllers/boards/application_controller.rb b/app/controllers/boards/application_controller.rb new file mode 100644 index 00000000000..b2675025fc0 --- /dev/null +++ b/app/controllers/boards/application_controller.rb @@ -0,0 +1,21 @@ +module Boards + class ApplicationController < ::ApplicationController + respond_to :json + + rescue_from ActiveRecord::RecordNotFound, with: :record_not_found + + private + + def board + @board ||= Board.find(params[:board_id]) + end + + def board_parent + @board_parent ||= board.parent + end + + def record_not_found(exception) + render json: { error: exception.message }, status: :not_found + end + end +end diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb new file mode 100644 index 00000000000..7d776d9b591 --- /dev/null +++ b/app/controllers/boards/issues_controller.rb @@ -0,0 +1,89 @@ +module Boards + class IssuesController < Boards::ApplicationController + include BoardsResponses + + before_action :authorize_read_issue, only: [:index] + before_action :authorize_create_issue, only: [:create] + before_action :authorize_update_issue, only: [:update] + + def index + issues = Boards::Issues::ListService.new(board_parent, current_user, filter_params).execute + issues = issues.page(params[:page]).per(params[:per] || 20) + make_sure_position_is_set(issues) unless Gitlab::Geo.secondary? + + render json: { + issues: serialize_as_json(issues.preload(:project)), + size: issues.total_count + } + end + + def create + service = Boards::Issues::CreateService.new(board_parent, project, current_user, issue_params) + issue = service.execute + + if issue.valid? + render json: serialize_as_json(issue) + else + render json: issue.errors, status: :unprocessable_entity + end + end + + def update + service = Boards::Issues::MoveService.new(board_parent, current_user, move_params) + + if service.execute(issue) + head :ok + else + head :unprocessable_entity + end + end + + private + + def make_sure_position_is_set(issues) + issues.each do |issue| + issue.move_to_end && issue.save unless issue.relative_position + end + end + + def issue + @issue ||= issues_finder.execute.find(params[:id]) + end + + def filter_params + params.merge(board_id: params[:board_id], id: params[:list_id]) + .reject { |_, value| value.nil? } + end + + def issues_finder + IssuesFinder.new(current_user, project_id: board_parent.id) + end + + def project + @project ||= Project.find(issue_params[:project_id]) + end + + def move_params + params.permit(:board_id, :id, :from_list_id, :to_list_id, :move_before_id, :move_after_id) + end + + def issue_params + params.require(:issue) + .permit(:title, :milestone_id, :project_id) + .merge(board_id: params[:board_id], list_id: params[:list_id], request: request) + end + + def serialize_as_json(resource) + resource.as_json( + labels: true, + only: [:id, :iid, :project_id, :title, :confidential, :due_date, :relative_position], + include: { + project: { only: [:id, :path] }, + assignees: { only: [:id, :name, :username], methods: [:avatar_url] }, + milestone: { only: [:id, :title] } + }, + user: current_user + ) + end + end +end diff --git a/app/controllers/boards/lists_controller.rb b/app/controllers/boards/lists_controller.rb new file mode 100644 index 00000000000..a4ed37dab31 --- /dev/null +++ b/app/controllers/boards/lists_controller.rb @@ -0,0 +1,74 @@ +module Boards + class ListsController < Boards::ApplicationController + include BoardsResponses + + before_action :authorize_admin_list, only: [:create, :update, :destroy, :generate] + before_action :authorize_read_list, only: [:index] + + def index + lists = Boards::Lists::ListService.new(board.parent, current_user).execute(board) + + render json: serialize_as_json(lists) + end + + def create + list = Boards::Lists::CreateService.new(board.parent, current_user, list_params).execute(board) + + if list.valid? + render json: serialize_as_json(list) + else + render json: list.errors, status: :unprocessable_entity + end + end + + def update + list = board.lists.movable.find(params[:id]) + service = Boards::Lists::MoveService.new(board_parent, current_user, move_params) + + if service.execute(list) + head :ok + else + head :unprocessable_entity + end + end + + def destroy + list = board.lists.destroyable.find(params[:id]) + service = Boards::Lists::DestroyService.new(board_parent, current_user) + + if service.execute(list) + head :ok + else + head :unprocessable_entity + end + end + + def generate + service = Boards::Lists::GenerateService.new(board_parent, current_user) + + if service.execute(board) + render json: serialize_as_json(board.lists.movable) + else + head :unprocessable_entity + end + end + + private + + def list_params + params.require(:list).permit(:label_id) + end + + def move_params + params.require(:list).permit(:position) + end + + def serialize_as_json(resource) + resource.as_json( + only: [:id, :list_type, :position], + methods: [:title], + label: true + ) + end + end +end diff --git a/app/controllers/projects/boards/application_controller.rb b/app/controllers/projects/boards/application_controller.rb deleted file mode 100644 index dad38fff6b9..00000000000 --- a/app/controllers/projects/boards/application_controller.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Projects - module Boards - class ApplicationController < Projects::ApplicationController - respond_to :json - - rescue_from ActiveRecord::RecordNotFound, with: :record_not_found - - private - - def record_not_found(exception) - render json: { error: exception.message }, status: :not_found - end - end - end -end diff --git a/app/controllers/projects/boards/issues_controller.rb b/app/controllers/projects/boards/issues_controller.rb deleted file mode 100644 index 653e7bc7e40..00000000000 --- a/app/controllers/projects/boards/issues_controller.rb +++ /dev/null @@ -1,94 +0,0 @@ -module Projects - module Boards - class IssuesController < Boards::ApplicationController - before_action :authorize_read_issue!, only: [:index] - before_action :authorize_create_issue!, only: [:create] - before_action :authorize_update_issue!, only: [:update] - - def index - issues = ::Boards::Issues::ListService.new(project, current_user, filter_params).execute - issues = issues.page(params[:page]).per(params[:per] || 20) - make_sure_position_is_set(issues) - - render json: { - issues: serialize_as_json(issues), - size: issues.total_count - } - end - - def create - service = ::Boards::Issues::CreateService.new(project, current_user, issue_params) - issue = service.execute - - if issue.valid? - render json: serialize_as_json(issue) - else - render json: issue.errors, status: :unprocessable_entity - end - end - - def update - service = ::Boards::Issues::MoveService.new(project, current_user, move_params) - - if service.execute(issue) - head :ok - else - head :unprocessable_entity - end - end - - private - - def make_sure_position_is_set(issues) - issues.each do |issue| - issue.move_to_end && issue.save unless issue.relative_position - end - end - - def issue - @issue ||= - IssuesFinder.new(current_user, project_id: project.id) - .execute - .where(iid: params[:id]) - .first! - end - - def authorize_read_issue! - return render_403 unless can?(current_user, :read_issue, project) - end - - def authorize_create_issue! - return render_403 unless can?(current_user, :admin_issue, project) - end - - def authorize_update_issue! - return render_403 unless can?(current_user, :update_issue, issue) - end - - def filter_params - params.merge(board_id: params[:board_id], id: params[:list_id]) - .reject { |_, value| value.nil? } - end - - def move_params - params.permit(:board_id, :id, :from_list_id, :to_list_id, :move_before_iid, :move_after_iid) - end - - def issue_params - params.require(:issue).permit(:title).merge(board_id: params[:board_id], list_id: params[:list_id], request: request) - end - - def serialize_as_json(resource) - resource.as_json( - labels: true, - only: [:id, :iid, :title, :confidential, :due_date, :relative_position], - include: { - assignees: { only: [:id, :name, :username], methods: [:avatar_url] }, - milestone: { only: [:id, :title] } - }, - user: current_user - ) - end - end - end -end diff --git a/app/controllers/projects/boards/lists_controller.rb b/app/controllers/projects/boards/lists_controller.rb deleted file mode 100644 index ad53bb749a0..00000000000 --- a/app/controllers/projects/boards/lists_controller.rb +++ /dev/null @@ -1,86 +0,0 @@ -module Projects - module Boards - class ListsController < Boards::ApplicationController - before_action :authorize_admin_list!, only: [:create, :update, :destroy, :generate] - before_action :authorize_read_list!, only: [:index] - - def index - lists = ::Boards::Lists::ListService.new(project, current_user).execute(board) - - render json: serialize_as_json(lists) - end - - def create - list = ::Boards::Lists::CreateService.new(project, current_user, list_params).execute(board) - - if list.valid? - render json: serialize_as_json(list) - else - render json: list.errors, status: :unprocessable_entity - end - end - - def update - list = board.lists.movable.find(params[:id]) - service = ::Boards::Lists::MoveService.new(project, current_user, move_params) - - if service.execute(list) - head :ok - else - head :unprocessable_entity - end - end - - def destroy - list = board.lists.destroyable.find(params[:id]) - service = ::Boards::Lists::DestroyService.new(project, current_user) - - if service.execute(list) - head :ok - else - head :unprocessable_entity - end - end - - def generate - service = ::Boards::Lists::GenerateService.new(project, current_user) - - if service.execute(board) - render json: serialize_as_json(board.lists.movable) - else - head :unprocessable_entity - end - end - - private - - def authorize_admin_list! - return render_403 unless can?(current_user, :admin_list, project) - end - - def authorize_read_list! - return render_403 unless can?(current_user, :read_list, project) - end - - def board - @board ||= project.boards.find(params[:board_id]) - end - - def list_params - params.require(:list).permit(:label_id) - end - - def move_params - params.require(:list).permit(:position) - end - - def serialize_as_json(resource) - resource.as_json( - only: [:id, :list_type, :position], - methods: [:title], - label: true - ) - end - end - end -end diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index 808affa4f98..88a57749d78 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -1,32 +1,31 @@ class Projects::BoardsController < Projects::ApplicationController include IssuableCollections + include BoardsResponses before_action :authorize_read_board!, only: [:index, :show] + before_action :assign_endpoint_vars def index - @boards = ::Boards::ListService.new(project, current_user).execute - - respond_to do |format| - format.html - format.json do - render json: serialize_as_json(@boards) - end - end + @boards = Boards::ListService.new(project, current_user).execute + + respond_with_boards end def show @board = project.boards.find(params[:id]) - respond_to do |format| - format.html - format.json do - render json: serialize_as_json(@board) - end - end + respond_with_board end private + def assign_endpoint_vars + @boards_endpoint = project_boards_url(project) + @bulk_issues_path = bulk_update_project_issues_path(project) + @namespace_path = project.namespace.path + @labels_endpoint = project_labels_path(project) + end + def authorize_read_board! return access_denied! unless can?(current_user, :read_board, project) end diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index 8b33c362a9c..062c3dcf164 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -1,15 +1,81 @@ module BoardsHelper - def board_data - board = @board || @boards.first + def board + @board ||= @board || @boards.first + end + def board_data { - endpoint: project_boards_path(@project), + boards_endpoint: @boards_endpoint, + lists_endpoint: board_lists_url(board), board_id: board.id, - disabled: "#{!can?(current_user, :admin_list, @project)}", - issue_link_base: project_issues_path(@project), + board_milestone_title: board&.milestone&.title, + disabled: "#{!can?(current_user, :admin_list, current_board_parent)}", + issue_link_base: build_issue_link_base, root_path: root_path, - bulk_update_path: bulk_update_project_issues_path(@project), + bulk_update_path: @bulk_issues_path, default_avatar: image_path(default_avatar) } end + + def build_issue_link_base + project_issues_path(@project) + end + + def current_board_json + board = @board || @boards.first + + board.to_json( + only: [:id, :name, :milestone_id], + include: { + milestone: { only: [:title] } + } + ) + end + + def board_base_url + project_boards_path(@project) + end + + def multiple_boards_available? + current_board_parent.multiple_issue_boards_available?(current_user) + end + + def board_path(board) + @board_path ||= project_board_path(current_board_parent, board) + end + + def current_board_parent + @current_board_parent ||= @project + end + + def can_admin_issue? + can?(current_user, :admin_issue, current_board_parent) + end + + def board_list_data + { + toggle: "dropdown", + list_labels_path: labels_filter_path(true), + labels: labels_filter_path(true), + labels_endpoint: @labels_endpoint, + namespace_path: @namespace_path, + project_path: @project&.try(:path) + } + end + + def board_sidebar_user_data + dropdown_options = issue_assignees_dropdown_options + + { + toggle: 'dropdown', + field_name: 'issue[assignee_ids][]', + first_user: current_user&.username, + current_user: 'true', + project_id: @project&.try(:id), + null_user: 'true', + multi_select: 'true', + 'dropdown-header': dropdown_options[:data][:'dropdown-header'], + 'max-select': dropdown_options[:data][:'max-select'] + } + end end diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index 197c90c4081..256de454ecc 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -358,6 +358,14 @@ module IssuablesHelper end end + def labels_path + if @project + project_labels_path(@project) + elsif @group + group_labels_path(@group) + end + end + def issuable_sidebar_options(issuable, can_edit_issuable) { endpoint: "#{issuable_json_path(issuable)}?basic=true", diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb index e60513b35c7..e1ba7898ee6 100644 --- a/app/helpers/labels_helper.rb +++ b/app/helpers/labels_helper.rb @@ -121,13 +121,14 @@ module LabelsHelper end end - def labels_filter_path - return group_labels_path(@group, :json) if @group - + def labels_filter_path(only_group_labels = false) project = @target_project || @project if project project_labels_path(project, :json) + elsif @group + options = { only_group_labels: only_group_labels } if only_group_labels + group_labels_path(@group, :json, options) else dashboard_labels_path(:json) end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index ae0e0aa3cf9..b85fd96d57a 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -127,19 +127,21 @@ module SearchHelper end def search_filter_input_options(type) - opts = { - id: "filtered-search-#{type}", - placeholder: 'Search or filter results...', - data: { - 'username-params' => @users.to_json(only: [:id, :username]) + opts = + { + id: "filtered-search-#{type}", + placeholder: 'Search or filter results...', + data: { + 'username-params' => @users.to_json(only: [:id, :username]) + } } - } if @project.present? opts[:data]['project-id'] = @project.id opts[:data]['base-endpoint'] = project_path(@project) else # Group context + opts[:data]['group-id'] = @group.id opts[:data]['base-endpoint'] = group_canonical_path(@group) end diff --git a/app/models/board.rb b/app/models/board.rb index 97d0f550925..8a6de31ea30 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -3,7 +3,11 @@ class Board < ActiveRecord::Base has_many :lists, -> { order(:list_type, :position) }, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent - validates :project, presence: true + validates :project, presence: true, if: :project_needed? + + def project_needed? + true + end def backlog_list lists.merge(List.backlog).take diff --git a/app/models/concerns/relative_positioning.rb b/app/models/concerns/relative_positioning.rb index 7cb9a28a284..e961c97e337 100644 --- a/app/models/concerns/relative_positioning.rb +++ b/app/models/concerns/relative_positioning.rb @@ -10,8 +10,12 @@ module RelativePositioning after_save :save_positionable_neighbours end + def project_ids + [project.id] + end + def max_relative_position - self.class.in_projects(project.id).maximum(:relative_position) + self.class.in_projects(project_ids).maximum(:relative_position) end def prev_relative_position @@ -19,7 +23,7 @@ module RelativePositioning if self.relative_position prev_pos = self.class - .in_projects(project.id) + .in_projects(project_ids) .where('relative_position < ?', self.relative_position) .maximum(:relative_position) end @@ -32,7 +36,7 @@ module RelativePositioning if self.relative_position next_pos = self.class - .in_projects(project.id) + .in_projects(project_ids) .where('relative_position > ?', self.relative_position) .minimum(:relative_position) end @@ -59,7 +63,7 @@ module RelativePositioning pos_after = before.next_relative_position if before.shift_after? - issue_to_move = self.class.in_projects(project.id).find_by!(relative_position: pos_after) + issue_to_move = self.class.in_projects(project_ids).find_by!(relative_position: pos_after) issue_to_move.move_after @positionable_neighbours = [issue_to_move] @@ -74,7 +78,7 @@ module RelativePositioning pos_before = after.prev_relative_position if after.shift_before? - issue_to_move = self.class.in_projects(project.id).find_by!(relative_position: pos_before) + issue_to_move = self.class.in_projects(project_ids).find_by!(relative_position: pos_before) issue_to_move.move_before @positionable_neighbours = [issue_to_move] diff --git a/app/models/label.rb b/app/models/label.rb index 674bb3f2720..7fb017f9b0c 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -34,7 +34,8 @@ class Label < ActiveRecord::Base scope :templates, -> { where(template: true) } scope :with_title, ->(title) { where(title: title) } - scope :on_project_boards, ->(project_id) { joins(lists: :board).merge(List.movable).where(boards: { project_id: project_id }) } + scope :with_lists_and_board, -> { joins(lists: :board).merge(List.movable) } + scope :on_project_boards, ->(project_id) { with_lists_and_board.where(boards: { project_id: project_id }) } def self.prioritized(project) joins(:priorities) diff --git a/app/models/project.rb b/app/models/project.rb index d5324ceac31..8ade8c3fc38 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1469,6 +1469,14 @@ class Project < ActiveRecord::Base end end + def multiple_issue_boards_available?(user) + feature_available?(:multiple_issue_boards, user) + end + + def issue_board_milestone_available?(user = nil) + feature_available?(:issue_board_milestone, user) + end + def full_path_was File.join(namespace.full_path, previous_changes['path'].first) end diff --git a/app/services/boards/base_service.rb b/app/services/boards/base_service.rb new file mode 100644 index 00000000000..72822ffffa1 --- /dev/null +++ b/app/services/boards/base_service.rb @@ -0,0 +1,10 @@ +module Boards + class BaseService < ::BaseService + # Parent can either a group or a project + attr_accessor :parent, :current_user, :params + + def initialize(parent, user, params = {}) + @parent, @current_user, @params = parent, user, params.dup + end + end +end diff --git a/app/services/boards/create_service.rb b/app/services/boards/create_service.rb index 9eedb9e65a2..bd0bb387662 100644 --- a/app/services/boards/create_service.rb +++ b/app/services/boards/create_service.rb @@ -1,5 +1,5 @@ module Boards - class CreateService < BaseService + class CreateService < Boards::BaseService def execute create_board! if can_create_board? end @@ -7,11 +7,11 @@ module Boards private def can_create_board? - project.boards.size == 0 + parent.boards.size == 0 end def create_board! - board = project.boards.create(params) + board = parent.boards.create(params) if board.persisted? board.lists.create(list_type: :backlog) diff --git a/app/services/boards/issues/create_service.rb b/app/services/boards/issues/create_service.rb index c0d7ff5b585..7c4a79f555e 100644 --- a/app/services/boards/issues/create_service.rb +++ b/app/services/boards/issues/create_service.rb @@ -1,6 +1,14 @@ module Boards module Issues - class CreateService < BaseService + class CreateService < Boards::BaseService + attr_accessor :project + + def initialize(parent, project, user, params = {}) + @project = project + + super(parent, user, params) + end + def execute create_issue(params.merge(label_ids: [list.label_id])) end @@ -8,7 +16,7 @@ module Boards private def board - @board ||= project.boards.find(params.delete(:board_id)) + @board ||= parent.boards.find(params.delete(:board_id)) end def list diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index eb345fead2d..a4c82817148 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -1,6 +1,6 @@ module Boards module Issues - class ListService < BaseService + class ListService < Boards::BaseService def execute issues = IssuesFinder.new(current_user, filter_params).execute issues = without_board_labels(issues) unless movable_list? || closed_list? @@ -11,7 +11,7 @@ module Boards private def board - @board ||= project.boards.find(params[:board_id]) + @board ||= parent.boards.find(params[:board_id]) end def list @@ -33,13 +33,13 @@ module Boards end def filter_params - set_project + set_parent set_state params end - def set_project + def set_parent params[:project_id] = project.id end diff --git a/app/services/boards/issues/move_service.rb b/app/services/boards/issues/move_service.rb index ecabb2a48e4..797d6df7c1a 100644 --- a/app/services/boards/issues/move_service.rb +++ b/app/services/boards/issues/move_service.rb @@ -1,17 +1,17 @@ module Boards module Issues - class MoveService < BaseService + class MoveService < Boards::BaseService def execute(issue) return false unless can?(current_user, :update_issue, issue) return false if issue_params.empty? - update_service.execute(issue) + update(issue) end private def board - @board ||= project.boards.find(params[:board_id]) + @board ||= parent.boards.find(params[:board_id]) end def move_between_lists? @@ -27,8 +27,8 @@ module Boards @moving_to_list ||= board.lists.find_by(id: params[:to_list_id]) end - def update_service - ::Issues::UpdateService.new(project, current_user, issue_params) + def update(issue) + ::Issues::UpdateService.new(issue.project, current_user, issue_params).execute(issue) end def issue_params @@ -42,7 +42,7 @@ module Boards ) end - attrs[:move_between_iids] = move_between_iids if move_between_iids + attrs[:move_between_ids] = move_between_ids if move_between_ids attrs end @@ -61,16 +61,16 @@ module Boards if moving_to_list.movable? moving_from_list.label_id else - Label.on_project_boards(project.id).pluck(:label_id) + Label.on_project_boards(parent.id).pluck(:label_id) end Array(label_ids).compact end - def move_between_iids - return unless params[:move_after_iid] || params[:move_before_iid] + def move_between_ids + return unless params[:move_after_id] || params[:move_before_id] - [params[:move_after_iid], params[:move_before_iid]] + [params[:move_after_id], params[:move_before_id]] end end end diff --git a/app/services/boards/list_service.rb b/app/services/boards/list_service.rb index 84f1fc3a4e2..6d0dd0a9f99 100644 --- a/app/services/boards/list_service.rb +++ b/app/services/boards/list_service.rb @@ -1,14 +1,14 @@ module Boards - class ListService < BaseService + class ListService < Boards::BaseService def execute - create_board! if project.boards.empty? - project.boards + create_board! if parent.boards.empty? + parent.boards end private def create_board! - Boards::CreateService.new(project, current_user).execute + Boards::CreateService.new(parent, current_user).execute end end end diff --git a/app/services/boards/lists/create_service.rb b/app/services/boards/lists/create_service.rb index fe0d762ccd2..dbb6c0694b9 100644 --- a/app/services/boards/lists/create_service.rb +++ b/app/services/boards/lists/create_service.rb @@ -3,17 +3,16 @@ module Boards class CreateService < BaseService def execute(board) List.transaction do - label = available_labels.find(params[:label_id]) + label = available_labels_for(board).find(params[:label_id]) position = next_position(board) - create_list(board, label, position) end end private - def available_labels - LabelsFinder.new(current_user, project_id: project.id).execute + def available_labels_for(board) + LabelsFinder.new(current_user, project_id: parent.id).execute end def next_position(board) diff --git a/app/services/boards/lists/generate_service.rb b/app/services/boards/lists/generate_service.rb index 939f9bfd068..3bf37649787 100644 --- a/app/services/boards/lists/generate_service.rb +++ b/app/services/boards/lists/generate_service.rb @@ -15,11 +15,11 @@ module Boards def create_list(board, params) label = find_or_create_label(params) - Lists::CreateService.new(project, current_user, label_id: label.id).execute(board) + Lists::CreateService.new(parent, current_user, label_id: label.id).execute(board) end def find_or_create_label(params) - ::Labels::FindOrCreateService.new(current_user, project, params).execute + ::Labels::FindOrCreateService.new(current_user, parent, params).execute end def label_params diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 8d918ccc635..69ccb15a0a1 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -3,7 +3,7 @@ module Issues include SpamCheckService def execute(issue) - handle_move_between_iids(issue) + handle_move_between_ids(issue) filter_spam_check_params change_issue_duplicate(issue) update(issue) @@ -55,12 +55,12 @@ module Issues end def handle_move_between_iids(issue) - return unless params[:move_between_iids] + return unless params[:move_between_ids] - after_iid, before_iid = params.delete(:move_between_iids) + after_id, before_id = params.delete(:move_between_ids) - issue_before = get_issue_if_allowed(issue.project, before_iid) if before_iid - issue_after = get_issue_if_allowed(issue.project, after_iid) if after_iid + issue_before = get_issue_if_allowed(issue.project, before_id) if before_id + issue_after = get_issue_if_allowed(issue.project, after_id) if after_id issue.move_between(issue_before, issue_after) end @@ -76,8 +76,8 @@ module Issues private - def get_issue_if_allowed(project, iid) - issue = project.issues.find_by(iid: iid) + def get_issue_if_allowed(project, id) + issue = project.issues.find(id) issue if can?(current_user, :update_issue, issue) end -- cgit v1.2.1 From 8077b728bc26e9ece8055b8301033238ddbdf3f5 Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Thu, 31 Aug 2017 14:48:57 -0300 Subject: Continue BE backport --- app/controllers/boards/issues_controller.rb | 1 + app/controllers/boards/lists_controller.rb | 1 + app/controllers/concerns/boards_responses.rb | 42 +++++++++++++++++++++++++++ app/controllers/projects/boards_controller.rb | 2 +- app/models/label.rb | 1 + app/services/boards/lists/create_service.rb | 2 +- app/services/boards/lists/destroy_service.rb | 2 +- app/services/boards/lists/generate_service.rb | 2 +- app/services/boards/lists/list_service.rb | 2 +- app/services/boards/lists/move_service.rb | 2 +- 10 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 app/controllers/concerns/boards_responses.rb (limited to 'app') diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 7d776d9b591..8ac23faa4b7 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -5,6 +5,7 @@ module Boards before_action :authorize_read_issue, only: [:index] before_action :authorize_create_issue, only: [:create] before_action :authorize_update_issue, only: [:update] + skip_before_action :authenticate_user!, only: [:index] def index issues = Boards::Issues::ListService.new(board_parent, current_user, filter_params).execute diff --git a/app/controllers/boards/lists_controller.rb b/app/controllers/boards/lists_controller.rb index a4ed37dab31..381fd4d7508 100644 --- a/app/controllers/boards/lists_controller.rb +++ b/app/controllers/boards/lists_controller.rb @@ -4,6 +4,7 @@ module Boards before_action :authorize_admin_list, only: [:create, :update, :destroy, :generate] before_action :authorize_read_list, only: [:index] + skip_before_action :authenticate_user!, only: [:index] def index lists = Boards::Lists::ListService.new(board.parent, current_user).execute(board) diff --git a/app/controllers/concerns/boards_responses.rb b/app/controllers/concerns/boards_responses.rb new file mode 100644 index 00000000000..2c9c095a5d7 --- /dev/null +++ b/app/controllers/concerns/boards_responses.rb @@ -0,0 +1,42 @@ +module BoardsResponses + def authorize_read_list + authorize_action_for!(board.parent, :read_list) + end + + def authorize_read_issue + authorize_action_for!(board.parent, :read_issue) + end + + def authorize_update_issue + authorize_action_for!(issue, :admin_issue) + end + + def authorize_create_issue + authorize_action_for!(project, :admin_issue) + end + + def authorize_admin_list + authorize_action_for!(board.parent, :admin_list) + end + + def authorize_action_for!(resource, ability) + return render_403 unless can?(current_user, ability, resource) + end + + def respond_with_boards + respond_with(@boards) + end + + def respond_with_board + respond_with(@board) + end + + def respond_with(resource) + respond_to do |format| + format.html + format.json do + render json: serialize_as_json(resource) + end + end + end +end diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index 88a57749d78..04f2f77faf2 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -1,6 +1,6 @@ class Projects::BoardsController < Projects::ApplicationController - include IssuableCollections include BoardsResponses + include IssuableCollections before_action :authorize_read_board!, only: [:index, :show] before_action :assign_endpoint_vars diff --git a/app/models/label.rb b/app/models/label.rb index 7fb017f9b0c..0298e7b417c 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -173,6 +173,7 @@ class Label < ActiveRecord::Base def as_json(options = {}) super(options).tap do |json| + json[:type] = self.type json[:priority] = priority(options[:project]) if options.key?(:project) end end diff --git a/app/services/boards/lists/create_service.rb b/app/services/boards/lists/create_service.rb index dbb6c0694b9..183556a1d6b 100644 --- a/app/services/boards/lists/create_service.rb +++ b/app/services/boards/lists/create_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class CreateService < BaseService + class CreateService < Boards::BaseService def execute(board) List.transaction do label = available_labels_for(board).find(params[:label_id]) diff --git a/app/services/boards/lists/destroy_service.rb b/app/services/boards/lists/destroy_service.rb index f986e05944c..d75c5fd3dc6 100644 --- a/app/services/boards/lists/destroy_service.rb +++ b/app/services/boards/lists/destroy_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class DestroyService < BaseService + class DestroyService < Boards::BaseService def execute(list) return false unless list.destroyable? diff --git a/app/services/boards/lists/generate_service.rb b/app/services/boards/lists/generate_service.rb index 3bf37649787..05d4ab5dbcc 100644 --- a/app/services/boards/lists/generate_service.rb +++ b/app/services/boards/lists/generate_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class GenerateService < BaseService + class GenerateService < Boards::BaseService def execute(board) return false unless board.lists.movable.empty? diff --git a/app/services/boards/lists/list_service.rb b/app/services/boards/lists/list_service.rb index df2a01a69e5..e57c95294af 100644 --- a/app/services/boards/lists/list_service.rb +++ b/app/services/boards/lists/list_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class ListService < BaseService + class ListService < Boards::BaseService def execute(board) board.lists.create(list_type: :backlog) unless board.lists.backlog.exists? diff --git a/app/services/boards/lists/move_service.rb b/app/services/boards/lists/move_service.rb index f2a68865f7b..7d0730e8332 100644 --- a/app/services/boards/lists/move_service.rb +++ b/app/services/boards/lists/move_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class MoveService < BaseService + class MoveService < Boards::BaseService def execute(list) @board = list.board @old_position = list.position -- cgit v1.2.1 From aa997e4297065cdb4a78b4b629c8820d4d6b0a8e Mon Sep 17 00:00:00 2001 From: Felipe Artur Date: Thu, 31 Aug 2017 16:34:57 -0300 Subject: Small fixes --- app/controllers/boards/issues_controller.rb | 2 +- app/helpers/boards_helper.rb | 1 - app/models/board.rb | 8 ++++++++ app/services/boards/issues/list_service.rb | 2 +- app/services/issues/update_service.rb | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) (limited to 'app') diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 8ac23faa4b7..016059b3a51 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -10,7 +10,7 @@ module Boards def index issues = Boards::Issues::ListService.new(board_parent, current_user, filter_params).execute issues = issues.page(params[:page]).per(params[:per] || 20) - make_sure_position_is_set(issues) unless Gitlab::Geo.secondary? + make_sure_position_is_set(issues) render json: { issues: serialize_as_json(issues.preload(:project)), diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb index 062c3dcf164..3133b716345 100644 --- a/app/helpers/boards_helper.rb +++ b/app/helpers/boards_helper.rb @@ -8,7 +8,6 @@ module BoardsHelper boards_endpoint: @boards_endpoint, lists_endpoint: board_lists_url(board), board_id: board.id, - board_milestone_title: board&.milestone&.title, disabled: "#{!can?(current_user, :admin_list, current_board_parent)}", issue_link_base: build_issue_link_base, root_path: root_path, diff --git a/app/models/board.rb b/app/models/board.rb index 8a6de31ea30..5bb7d3d3722 100644 --- a/app/models/board.rb +++ b/app/models/board.rb @@ -9,6 +9,14 @@ class Board < ActiveRecord::Base true end + def parent + project + end + + def group_board? + false + end + def backlog_list lists.merge(List.backlog).take end diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index a4c82817148..d85d93e251b 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -40,7 +40,7 @@ module Boards end def set_parent - params[:project_id] = project.id + params[:project_id] = parent.id end def set_state diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 69ccb15a0a1..a1f31abd164 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -54,7 +54,7 @@ module Issues end end - def handle_move_between_iids(issue) + def handle_move_between_ids(issue) return unless params[:move_between_ids] after_id, before_id = params.delete(:move_between_ids) -- cgit v1.2.1 From 6ed490401f49a8941dc7a9e3757ec4012f14ef0b Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Thu, 24 Aug 2017 13:01:33 +0200 Subject: Implement the implied CI/CD config for AutoDevOps Behind an application setting, which defaults to false, this commit implements the implied CI/CD config. Which means that in the case we can't find the `.gitlab-ci.yml` on the commit we want to start a pipeline for, we fall back to an implied configuration. For now the Bash template has been copied to `Auto-Devops.gitlab-ci.yml` so the tests actually work. Fixes #34777 --- app/helpers/application_settings_helper.rb | 1 + app/models/ci/pipeline.rb | 22 ++++++++++++++++------ app/models/project.rb | 6 ++++++ app/models/project_auto_devops.rb | 3 +++ .../admin/application_settings/_form.html.haml | 8 +++++++- 5 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 app/models/project_auto_devops.rb (limited to 'app') diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 04955ed625e..f97f7199648 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -103,6 +103,7 @@ module ApplicationSettingsHelper :after_sign_up_text, :akismet_api_key, :akismet_enabled, + :auto_devops_enabled, :clientside_sentry_dsn, :clientside_sentry_enabled, :container_registry_token_expire_delay, diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 2d40f8012a3..53ff42c04f4 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -338,12 +338,10 @@ module Ci def ci_yaml_file return @ci_yaml_file if defined?(@ci_yaml_file) - @ci_yaml_file = begin - project.repository.gitlab_ci_yml_for(sha, ci_yaml_file_path) - rescue Rugged::ReferenceError, GRPC::NotFound, GRPC::Internal - self.yaml_errors = - "Failed to load CI/CD config file at #{ci_yaml_file_path}" - nil + @ci_yaml_file = (ci_yaml_from_repo || implied_ci_yaml_file).tap do |config| + unless config + self.yaml_errors = "Failed to load CI/CD config file for #{sha}" + end end end @@ -430,6 +428,18 @@ module Ci private + def implied_ci_yaml_file + if project.auto_devops_enabled? + Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps').content + end + end + + def ci_yaml_from_repo + project.repository.gitlab_ci_yml_for(sha, ci_yaml_file_path) + rescue GRPC::NotFound, Rugged::ReferenceError, GRPC::Internal + nil + end + def pipeline_data Gitlab::DataBuilder::Pipeline.build(self) end diff --git a/app/models/project.rb b/app/models/project.rb index 5b4904a5c51..56ba2620687 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -186,6 +186,8 @@ class Project < ActiveRecord::Base has_many :active_runners, -> { active }, through: :runner_projects, source: :runner, class_name: 'Ci::Runner' + has_one :auto_devops, class_name: 'ProjectAutoDevops' + accepts_nested_attributes_for :variables, allow_destroy: true accepts_nested_attributes_for :project_feature accepts_nested_attributes_for :import_data @@ -464,6 +466,10 @@ class Project < ActiveRecord::Base self[:lfs_enabled] && Gitlab.config.lfs.enabled end + def auto_devops_enabled? + auto_devops&.enabled? || current_application_settings.auto_devops_enabled? + end + def repository_storage_path Gitlab.config.repositories.storages[repository_storage]['path'] end diff --git a/app/models/project_auto_devops.rb b/app/models/project_auto_devops.rb new file mode 100644 index 00000000000..fe73c6f0a85 --- /dev/null +++ b/app/models/project_auto_devops.rb @@ -0,0 +1,3 @@ +class ProjectAutoDevops < ActiveRecord::Base + belongs_to :project +end diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 734a08c61fa..a487f2b6995 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -217,7 +217,13 @@ .help-block 0 for unlimited %fieldset - %legend Continuous Integration + %legend Continuous Integration and Continuous Deployment + .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :auto_devops_enabled do + = f.check_box :auto_devops_enabled + Allow projects to get automaticly configured to use GitLab CI/CD. .form-group .col-sm-offset-2.col-sm-10 .checkbox -- cgit v1.2.1 From 770bcf71bb85c9eff13f4eb14cbd517986da9056 Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Wed, 30 Aug 2017 20:39:23 +0200 Subject: Form for setting project auto devops settings --- .../projects/pipelines_settings_controller.rb | 12 +++--- .../projects/settings/ci_cd_controller.rb | 5 +++ app/models/project.rb | 1 + .../admin/application_settings/_form.html.haml | 8 +++- .../projects/pipelines_settings/_show.html.haml | 44 +++++++++++++++++++--- 5 files changed, 56 insertions(+), 14 deletions(-) (limited to 'app') diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb index 9d24ebe2138..abab2e2f0c9 100644 --- a/app/controllers/projects/pipelines_settings_controller.rb +++ b/app/controllers/projects/pipelines_settings_controller.rb @@ -6,7 +6,7 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController end def update - if @project.update_attributes(update_params) + if @project.update(update_params) flash[:notice] = "Pipelines settings for '#{@project.name}' were successfully updated." redirect_to project_settings_ci_cd_path(@project) else @@ -16,14 +16,12 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController private - def create_params - params.require(:pipeline).permit(:ref) - end - def update_params params.require(:project).permit( - :runners_token, :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex, - :public_builds, :auto_cancel_pending_pipelines, :ci_config_path + :runners_token, :builds_enabled, :build_allow_git_fetch, + :build_timeout_in_minutes, :build_coverage_regex, :public_builds, + :auto_cancel_pending_pipelines, :ci_config_path, + auto_devops_attributes: [:id, :domain, :enabled] ) end end diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index 15a2ff56b92..b029b31f9af 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -8,6 +8,7 @@ module Projects define_secret_variables define_triggers_variables define_badges_variables + define_auto_devops_variables end private @@ -42,6 +43,10 @@ module Projects badge.new(@project, @ref).metadata end end + + def define_auto_devops_variables + @auto_devops = @project.auto_devops || ProjectAutoDevops.new + end end end end diff --git a/app/models/project.rb b/app/models/project.rb index 56ba2620687..cc9fd215070 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -191,6 +191,7 @@ class Project < ActiveRecord::Base accepts_nested_attributes_for :variables, allow_destroy: true accepts_nested_attributes_for :project_feature accepts_nested_attributes_for :import_data + accepts_nested_attributes_for :auto_devops delegate :name, to: :owner, allow_nil: true, prefix: true delegate :members, to: :team, prefix: true diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index a487f2b6995..a00fc978494 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -217,13 +217,17 @@ .help-block 0 for unlimited %fieldset - %legend Continuous Integration and Continuous Deployment + %legend Continuous Integration and Deployment .form-group .col-sm-offset-2.col-sm-10 .checkbox = f.label :auto_devops_enabled do = f.check_box :auto_devops_enabled - Allow projects to get automaticly configured to use GitLab CI/CD. + Enabled Auto DevOps (Beta) for projects by default + .help-block + It will automatically build, test, and deploy applications based on a predefined CI/CD configuration + - # Fix this link + = link_to icon('question-circle'), help_page_path('user/admin_area/settings/continuous_integration', anchor: 'maximum-artifacts-size') .form-group .col-sm-offset-2.col-sm-10 .checkbox diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml index 255d7ef38e0..f4a6ecde0a4 100644 --- a/app/views/projects/pipelines_settings/_show.html.haml +++ b/app/views/projects/pipelines_settings/_show.html.haml @@ -5,11 +5,45 @@ .col-lg-8 = form_for @project, url: project_pipelines_settings_path(@project) do |f| %fieldset.builds-feature - - unless @repository.gitlab_ci_yml - .form-group - %p Pipelines need to be configured before you can begin using Continuous Integration. - = link_to 'Get started with Pipelines', help_page_path('ci/quick_start/README'), class: 'btn btn-info' - %hr + .form-group + %p Pipelines need to have AutoDevOps enabled or have a .gitlab-ci.yml configured before you can begin using Continious Integration and Delivery. + = f.label :auto_devops_enabled, 'Auto DevOps (Beta)', class: 'label-light' + %p + Auto DevOps will automatically build, test, and deploy your application based on a predefined CI/CD configuration. + = link_to 'Learn more about Auto DevOps', help_page_path('ci/quick_start/README') #TODO fix the link + = f.fields_for :auto_devops_attributes, @auto_devops do |form| + .radio + = form.radio_button :enabled, true + %strong Enable Auto DevOps + %br + %span.descr + The Auto DevOps pipeline configuration will be used when ther is no .gitlab-ci.yml + in the repository. + .radio + = form.radio_button :enabled, false + %strong Disable Auto DevOps + %br + %span.descr + A specific .gitlab-ci.yml file needs to be specified before you can begin using Continious Integration and Delivery + .radio + = form.radio_button :enabled, nil + %strong + Instance default (status: #{current_application_settings.auto_devops_enabled?}) + %br + %span.descr + Follow the instance default to either have Auto DevOps enabled or disabled when there is no .gitlab-ci.yml file specified + %br + %p + Define a domain used by Auto DevOps to deploy towards, this is required for deploys to succeed. + = link_to 'Learn more about deploying with Auto DevOps', help_page_path('ci/quick_start/README') #TODO fix the link + = form.text_field :domain, class: 'form-control', placeholder: 'domain.com' + %br + %p + %strong Project specific pipeline configuration + Define a project specific pipeline configuration by creating a .gitlab-ci.yml file. + = link_to 'Learn more about pipelines', help_page_path('ci/quick_start/README'), class: 'btn btn-info' + + %hr .form-group.append-bottom-default = f.label :runners_token, "Runner token", class: 'label-light' = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89' -- cgit v1.2.1 From 35b9213cd7e378a732991a11bc8b5fa9e711c52b Mon Sep 17 00:00:00 2001 From: Zeger-Jan van de Weg Date: Thu, 31 Aug 2017 13:47:29 +0200 Subject: Add config_source to ci_pipelines Given the user can soon have multiple config sources for CI, we now store what type at the time of the pipeline run we chose. This will give us insight into what triggered the new pipeline so we can display it to the enduser. --- .../javascripts/pipelines/components/pipeline_url.vue | 7 +++++++ app/models/ci/pipeline.rb | 17 +++++++++++++---- app/serializers/pipeline_entity.rb | 1 + app/views/projects/pipelines/index.html.haml | 2 +- 4 files changed, 22 insertions(+), 5 deletions(-) (limited to 'app') diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue index 2ca5ac2912f..3cab411d321 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue @@ -57,6 +57,13 @@ export default { :title="pipeline.yaml_errors"> yaml invalid + + Auto DevOps + diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 53ff42c04f4..5587b19fd69 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -50,6 +50,11 @@ module Ci external: 6 } + enum config_source: { + repository: nil, + auto_devops: 1 + } + state_machine :status, initial: :created do event :enqueue do transition created: :pending @@ -338,10 +343,14 @@ module Ci def ci_yaml_file return @ci_yaml_file if defined?(@ci_yaml_file) - @ci_yaml_file = (ci_yaml_from_repo || implied_ci_yaml_file).tap do |config| - unless config - self.yaml_errors = "Failed to load CI/CD config file for #{sha}" - end + @ci_yaml_file = ci_yaml_from_repo + @ci_yaml_file ||= implied_ci_yaml_file&.tap { self.auto_devops! } + + if @ci_yaml_file + @ci_yaml_file + else + self.yaml_errors = "Failed to load CI/CD config file for #{sha}" + nil end end diff --git a/app/serializers/pipeline_entity.rb b/app/serializers/pipeline_entity.rb index c4f000b0ca3..767f33e11e1 100644 --- a/app/serializers/pipeline_entity.rb +++ b/app/serializers/pipeline_entity.rb @@ -16,6 +16,7 @@ class PipelineEntity < Grape::Entity expose :flags do expose :latest?, as: :latest expose :stuck?, as: :stuck + expose :auto_devops?, as: :auto_devops expose :has_yaml_errors?, as: :yaml_errors expose :can_retry?, as: :retryable expose :can_cancel?, as: :cancelable diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml index c1729850cf4..93c3e016cba 100644 --- a/app/views/projects/pipelines/index.html.haml +++ b/app/views/projects/pipelines/index.html.haml @@ -13,7 +13,7 @@ "finished-path" => project_pipelines_path(@project, scope: :finished), "branches-path" => project_pipelines_path(@project, scope: :branches), "tags-path" => project_pipelines_path(@project, scope: :tags), - "has-ci" => @repository.gitlab_ci_yml, + "has-ci" => @repository.gitlab_ci_yml || @project.auto_devops_enabled?, "ci-lint-path" => ci_lint_path } } = page_specific_javascript_bundle_tag('common_vue') -- cgit v1.2.1 From 1fb2c1ca4ec6bb8b66a4cd06ea5c8374572c525b Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Fri, 1 Sep 2017 10:46:08 +0100 Subject: Adds tooltip for Auto DevOps badge in pipeline table --- .../pipelines/components/pipeline_url.vue | 61 +++++++++++++--------- .../javascripts/vue_shared/directives/popover.js | 24 +++++++++ app/assets/stylesheets/pages/commits.scss | 2 +- app/assets/stylesheets/pages/pipelines.scss | 9 ++++ 4 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 app/assets/javascripts/vue_shared/directives/popover.js (limited to 'app') diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue index 3cab411d321..6988417bd39 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue @@ -1,26 +1,34 @@ diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue index c3f1c426d8a..5b9bb6c3750 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue @@ -25,6 +25,10 @@ export default { required: false, default: false, }, + autoDevopsHelpPath: { + type: String, + required: true, + }, }, components: { asyncButtonComponent, @@ -218,7 +222,10 @@ export default { - +
help_page_path('ci/quick_start/README'), + "help-auto-devops-path" => help_page_path('topics/autodevops/index.md'), } } - content_for :page_specific_javascripts do diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml index 93c3e016cba..3ce20378038 100644 --- a/app/views/projects/pipelines/index.html.haml +++ b/app/views/projects/pipelines/index.html.haml @@ -5,6 +5,7 @@ #pipelines-list-vue{ data: { endpoint: project_pipelines_path(@project, format: :json), "css-class" => container_class, "help-page-path" => help_page_path('ci/quick_start/README'), + "help-auto-devops-path" => help_page_path('topics/autodevops/index.md'), "new-pipeline-path" => new_project_pipeline_path(@project), "can-create-pipeline" => can?(current_user, :create_pipeline, @project).to_s, "all-path" => project_pipelines_path(@project), -- cgit v1.2.1 From 1c4d39c16940795054a886fbc59fc13a00ebfe40 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Fri, 1 Sep 2017 12:24:49 +0100 Subject: Fix documention path --- app/assets/javascripts/pipelines/components/pipelines.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue index 75e40da6d28..5ce4fe58e55 100644 --- a/app/assets/javascripts/pipelines/components/pipelines.vue +++ b/app/assets/javascripts/pipelines/components/pipelines.vue @@ -27,7 +27,7 @@ endpoint: pipelinesData.endpoint, cssClass: pipelinesData.cssClass, helpPagePath: pipelinesData.helpPagePath, - autoDevopsPath: pipelinesData.helpautoDevopsPath, + autoDevopsPath: pipelinesData.helpAutoDevopsPath, newPipelinePath: pipelinesData.newPipelinePath, canCreatePipeline: pipelinesData.canCreatePipeline, allPath: pipelinesData.allPath, -- cgit v1.2.1 From 354df65295028ac09ed7e4a924e39ff567b38a4b Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Fri, 1 Sep 2017 12:18:00 +0100 Subject: Creates auto devops callout --- app/assets/javascripts/dispatcher.js | 10 +++++++ .../javascripts/pipelines/components/pipelines.vue | 5 +--- app/views/projects/merge_requests/index.html.haml | 2 ++ app/views/projects/pipelines/index.html.haml | 35 ++++++++++++---------- app/views/projects/show.html.haml | 3 ++ app/views/projects/tree/show.html.haml | 2 ++ app/views/shared/_auto_devops_callout.html.haml | 17 +++++++++++ app/views/shared/icons/_icon_autodevops.svg | 1 + 8 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 app/views/shared/_auto_devops_callout.html.haml create mode 100644 app/views/shared/icons/_icon_autodevops.svg (limited to 'app') diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index c70a17104fd..2b98bdeb54d 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -155,6 +155,9 @@ import initChangesDropdown from './init_changes_dropdown'; shortcut_handler = new ShortcutsNavigation(); new UsersSelect(); break; + case 'projects:merge_requests:index': + new UserCallout(); + break; case 'projects:merge_requests:index': case 'projects:issues:index': if (filteredSearchEnabled) { @@ -344,6 +347,7 @@ import initChangesDropdown from './init_changes_dropdown'; case 'projects:show': shortcut_handler = new ShortcutsNavigation(); new NotificationsForm(); + new UserCallout(); if ($('#tree-slider').length) new TreeView(); if ($('.blob-viewer').length) new BlobViewer(); @@ -363,6 +367,9 @@ import initChangesDropdown from './init_changes_dropdown'; case 'projects:pipelines:new': new NewBranchForm($('.js-new-pipeline-form')); break; + case 'projects:pipelines:index': + new UserCallout(); + break; case 'projects:pipelines:builds': case 'projects:pipelines:failures': case 'projects:pipelines:show': @@ -378,6 +385,8 @@ import initChangesDropdown from './init_changes_dropdown'; parentEl: '.pipelines-tabs', }, }); + + new UserCallout(); break; case 'groups:activity': new gl.Activities(); @@ -420,6 +429,7 @@ import initChangesDropdown from './init_changes_dropdown'; new TreeView(); new BlobViewer(); new NewCommitForm($('.js-create-dir-form')); + new UserCallout(); $('#tree-slider').waitForImages(function() { gl.utils.ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath); }); diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue index 75e40da6d28..49c87bf5e91 100644 --- a/app/assets/javascripts/pipelines/components/pipelines.vue +++ b/app/assets/javascripts/pipelines/components/pipelines.vue @@ -25,7 +25,6 @@ return { endpoint: pipelinesData.endpoint, - cssClass: pipelinesData.cssClass, helpPagePath: pipelinesData.helpPagePath, autoDevopsPath: pipelinesData.helpautoDevopsPath, newPipelinePath: pipelinesData.newPipelinePath, @@ -140,9 +139,7 @@ };