Merge branch 'breadcrumbs-improvements' into 'master'
Improvements to breadcrumbs Closes #35269 and #36460 See merge request !13582
This commit is contained in:
commit
cdd8f2f345
|
@ -0,0 +1,28 @@
|
|||
export const addTooltipToEl = (el) => {
|
||||
const textEl = el.querySelector('.js-breadcrumb-item-text');
|
||||
|
||||
if (textEl && textEl.scrollWidth > textEl.offsetWidth) {
|
||||
el.setAttribute('title', el.textContent);
|
||||
el.setAttribute('data-container', 'body');
|
||||
el.classList.add('has-tooltip');
|
||||
}
|
||||
};
|
||||
|
||||
export default () => {
|
||||
const breadcrumbs = document.querySelector('.js-breadcrumbs-list');
|
||||
|
||||
if (breadcrumbs) {
|
||||
const topLevelLinks = [...breadcrumbs.children].filter(el => !el.classList.contains('dropdown'))
|
||||
.map(el => el.querySelector('a'))
|
||||
.filter(el => el);
|
||||
const $expander = $('.js-breadcrumbs-collapsed-expander');
|
||||
|
||||
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');
|
||||
});
|
||||
}
|
||||
};
|
|
@ -41,7 +41,6 @@ import Issue from './issue';
|
|||
import BindInOut from './behaviors/bind_in_out';
|
||||
import DeleteModal from './branches/branches_delete_modal';
|
||||
import Group from './group';
|
||||
import GroupName from './group_name';
|
||||
import GroupsList from './groups_list';
|
||||
import ProjectsList from './projects_list';
|
||||
import setupProjectEdit from './project_edit';
|
||||
|
@ -554,9 +553,6 @@ import initChangesDropdown from './init_changes_dropdown';
|
|||
case 'root':
|
||||
new UserCallout();
|
||||
break;
|
||||
case 'groups':
|
||||
new GroupName();
|
||||
break;
|
||||
case 'profiles':
|
||||
new NotificationsForm();
|
||||
new NotificationsDropdown();
|
||||
|
@ -564,7 +560,6 @@ import initChangesDropdown from './init_changes_dropdown';
|
|||
case 'projects':
|
||||
new Project();
|
||||
new ProjectAvatar();
|
||||
new GroupName();
|
||||
switch (path[1]) {
|
||||
case 'compare':
|
||||
new CompareAutocomplete();
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
import _ from 'underscore';
|
||||
|
||||
export default class GroupName {
|
||||
constructor() {
|
||||
this.titleContainer = document.querySelector('.js-title-container');
|
||||
this.title = this.titleContainer.querySelector('.title');
|
||||
|
||||
if (this.title) {
|
||||
this.titleWidth = this.title.offsetWidth;
|
||||
this.groupTitle = this.titleContainer.querySelector('.group-title');
|
||||
this.groups = this.titleContainer.querySelectorAll('.group-path');
|
||||
this.toggle = null;
|
||||
this.isHidden = false;
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.groups.length > 0) {
|
||||
this.groups[this.groups.length - 1].classList.remove('hidable');
|
||||
this.toggleHandler();
|
||||
window.addEventListener('resize', _.debounce(this.toggleHandler.bind(this), 100));
|
||||
}
|
||||
this.render();
|
||||
}
|
||||
|
||||
toggleHandler() {
|
||||
if (this.titleWidth > this.titleContainer.offsetWidth) {
|
||||
if (!this.toggle) this.createToggle();
|
||||
this.showToggle();
|
||||
} else if (this.toggle) {
|
||||
this.hideToggle();
|
||||
}
|
||||
}
|
||||
|
||||
createToggle() {
|
||||
this.toggle = document.createElement('button');
|
||||
this.toggle.setAttribute('type', 'button');
|
||||
this.toggle.className = 'text-expander group-name-toggle';
|
||||
this.toggle.setAttribute('aria-label', 'Toggle full path');
|
||||
this.toggle.innerHTML = '<i class="fa fa-ellipsis-h" aria-hidden="true"></i>';
|
||||
this.toggle.addEventListener('click', this.toggleGroups.bind(this));
|
||||
this.title.insertBefore(this.toggle, this.groupTitle);
|
||||
this.toggleGroups();
|
||||
}
|
||||
|
||||
showToggle() {
|
||||
this.title.classList.add('wrap');
|
||||
this.toggle.classList.remove('hidden');
|
||||
if (this.isHidden) this.groupTitle.classList.add('hidden');
|
||||
}
|
||||
|
||||
hideToggle() {
|
||||
this.title.classList.remove('wrap');
|
||||
this.toggle.classList.add('hidden');
|
||||
if (this.isHidden) this.groupTitle.classList.remove('hidden');
|
||||
}
|
||||
|
||||
toggleGroups() {
|
||||
this.isHidden = !this.isHidden;
|
||||
this.groupTitle.classList.toggle('hidden');
|
||||
}
|
||||
|
||||
render() {
|
||||
this.title.classList.remove('initializing');
|
||||
}
|
||||
}
|
|
@ -144,6 +144,7 @@ import './smart_interval';
|
|||
import './star';
|
||||
import './subscription';
|
||||
import './subscription_select';
|
||||
import initBreadcrumbs from './breadcrumb';
|
||||
|
||||
import './dispatcher';
|
||||
|
||||
|
@ -181,6 +182,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 || '/';
|
||||
|
||||
|
|
|
@ -829,6 +829,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@include new-style-dropdown('.breadcrumbs-list .dropdown ');
|
||||
@include new-style-dropdown('.js-namespace-select + ');
|
||||
|
||||
header.navbar-gitlab-new .header-content .dropdown-menu.projects-dropdown-menu {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@import "framework/variables";
|
||||
@import 'framework/tw_bootstrap_variables';
|
||||
@import "bootstrap/variables";
|
||||
@import "framework/mixins";
|
||||
|
||||
.content-wrapper.page-with-new-nav {
|
||||
margin-top: $new-navbar-height;
|
||||
|
@ -422,109 +423,38 @@ header.navbar-gitlab-new {
|
|||
|
||||
.breadcrumbs {
|
||||
display: flex;
|
||||
min-height: 61px;
|
||||
min-height: 48px;
|
||||
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 {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding-top: $gl-padding;
|
||||
padding-bottom: $gl-padding;
|
||||
align-items: center;
|
||||
|
||||
.dropdown-menu-projects {
|
||||
margin-top: -$gl-padding;
|
||||
margin-left: $gl-padding;
|
||||
}
|
||||
border-bottom: 1px solid $border-color;
|
||||
}
|
||||
|
||||
.breadcrumbs-links {
|
||||
-webkit-flex: 1;
|
||||
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: $gl-font-weight-bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-tile {
|
||||
margin-right: 5px;
|
||||
margin-right: 4px;
|
||||
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;
|
||||
|
@ -533,6 +463,41 @@ header.navbar-gitlab-new {
|
|||
}
|
||||
}
|
||||
|
||||
.breadcrumbs-list {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 0;
|
||||
line-height: 16px;
|
||||
|
||||
> li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
> a {
|
||||
font-size: 12px;
|
||||
color: currentColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb-item-text {
|
||||
@include str-truncated(128px);
|
||||
}
|
||||
|
||||
.breadcrumbs-list-angle {
|
||||
position: absolute;
|
||||
right: -12px;
|
||||
top: 50%;
|
||||
color: $gl-text-color-tertiary;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.breadcrumbs-extra {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
|
@ -540,30 +505,10 @@ header.navbar-gitlab-new {
|
|||
}
|
||||
|
||||
.breadcrumbs-sub-title {
|
||||
margin: 2px 0;
|
||||
font-size: 16px;
|
||||
font-weight: $gl-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: $gl-font-weight-bold;
|
||||
}
|
||||
}
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
|
||||
a {
|
||||
color: $gl-text-color;
|
||||
|
|
|
@ -45,7 +45,6 @@ $new-sidebar-collapsed-width: 50px;
|
|||
margin-right: 2px;
|
||||
|
||||
a {
|
||||
border-bottom: 1px solid $border-color;
|
||||
font-weight: $gl-font-weight-bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -141,17 +141,17 @@
|
|||
display: inline-block;
|
||||
background: $white-light;
|
||||
color: $gl-text-color-secondary;
|
||||
padding: 0 5px;
|
||||
padding: 0 4px;
|
||||
cursor: pointer;
|
||||
border: 1px solid $border-gray-dark;
|
||||
border-radius: $border-radius-default;
|
||||
margin-left: 5px;
|
||||
font-size: $gl-font-size;
|
||||
font-size: 12px;
|
||||
line-height: $gl-font-size;
|
||||
outline: none;
|
||||
|
||||
&.open {
|
||||
background: $gray-light;
|
||||
background-color: darken($gray-light, 10%);
|
||||
box-shadow: inset 0 0 2px rgba($black, 0.2);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,4 +22,16 @@ module BreadcrumbsHelper
|
|||
|
||||
@breadcrumb_title = title
|
||||
end
|
||||
|
||||
def breadcrumb_list_item(link)
|
||||
content_tag "li" do
|
||||
link + icon("angle-right", class: "breadcrumbs-list-angle")
|
||||
end
|
||||
end
|
||||
|
||||
def add_to_breadcrumb_dropdown(link, location: :before)
|
||||
@breadcrumb_dropdown_links ||= {}
|
||||
@breadcrumb_dropdown_links[location] ||= []
|
||||
@breadcrumb_dropdown_links[location] << link
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,19 +15,21 @@ module GroupsHelper
|
|||
@has_group_title = true
|
||||
full_title = ''
|
||||
|
||||
group.ancestors.reverse.each do |parent|
|
||||
full_title += group_title_link(parent, hidable: true)
|
||||
|
||||
full_title += '<span class="hidable"> / </span>'.html_safe
|
||||
group.ancestors.reverse.each_with_index do |parent, index|
|
||||
if index > 0
|
||||
add_to_breadcrumb_dropdown(group_title_link(parent, hidable: false, show_avatar: true), location: :before)
|
||||
else
|
||||
full_title += breadcrumb_list_item group_title_link(parent, hidable: false)
|
||||
end
|
||||
end
|
||||
|
||||
full_title += group_title_link(group)
|
||||
full_title += ' · '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path') if name
|
||||
full_title += render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :before, title: _("Show parent subgroups")
|
||||
|
||||
full_title += breadcrumb_list_item group_title_link(group)
|
||||
full_title += ' · '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path breadcrumb-item-text js-breadcrumb-item-text') if name
|
||||
|
||||
content_tag :span, class: 'group-title' do
|
||||
full_title.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
def projects_lfs_status(group)
|
||||
lfs_status =
|
||||
|
@ -65,11 +67,11 @@ module GroupsHelper
|
|||
|
||||
private
|
||||
|
||||
def group_title_link(group, hidable: false)
|
||||
link_to(group_path(group), class: "group-path #{'hidable' if hidable}") do
|
||||
def group_title_link(group, hidable: false, show_avatar: false)
|
||||
link_to(group_path(group), class: "group-path breadcrumb-item-text js-breadcrumb-item-text #{'hidable' if hidable}") do
|
||||
output =
|
||||
if !Rails.env.test?
|
||||
image_tag(group_icon(group), class: "avatar-tile", width: 16, height: 16)
|
||||
if (group.try(:avatar_url) || show_avatar) && !Rails.env.test?
|
||||
image_tag(group_icon(group), class: "avatar-tile", width: 15, height: 15)
|
||||
else
|
||||
""
|
||||
end
|
||||
|
|
|
@ -126,12 +126,8 @@ module IssuablesHelper
|
|||
end
|
||||
|
||||
def issuable_meta(issuable, project, text)
|
||||
output = content_tag(:strong, class: "identifier") do
|
||||
concat("#{text} ")
|
||||
concat(to_url_reference(issuable))
|
||||
end
|
||||
|
||||
output << " opened #{time_ago_with_tooltip(issuable.created_at)} by ".html_safe
|
||||
output = ""
|
||||
output << "Opened #{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 +137,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)
|
||||
|
|
|
@ -80,7 +80,9 @@ module PageLayoutHelper
|
|||
@header_title = title
|
||||
@header_title_url = title_url
|
||||
else
|
||||
@header_title_url ? link_to(@header_title, @header_title_url) : @header_title
|
||||
return @header_title unless @header_title_url
|
||||
|
||||
breadcrumb_list_item(link_to(@header_title, @header_title_url))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -54,25 +54,28 @@ 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))
|
||||
end
|
||||
|
||||
project_link = link_to project_path(project), { class: "project-item-select-holder" } do
|
||||
project_link = link_to project_path(project) do
|
||||
output =
|
||||
if !Rails.env.test?
|
||||
project_icon(project, alt: project.name, class: 'avatar-tile', width: 16, height: 16)
|
||||
if project.avatar_url && !Rails.env.test?
|
||||
project_icon(project, alt: project.name, class: 'avatar-tile', width: 15, height: 15)
|
||||
else
|
||||
""
|
||||
end
|
||||
|
||||
output << simple_sanitize(project.name)
|
||||
output << content_tag("span", simple_sanitize(project.name), class: "breadcrumb-item-text js-breadcrumb-item-text")
|
||||
output.html_safe
|
||||
end
|
||||
|
||||
"#{namespace_link} / #{project_link}".html_safe
|
||||
namespace_link = breadcrumb_list_item(namespace_link) unless project.group
|
||||
project_link = breadcrumb_list_item project_link
|
||||
|
||||
"#{namespace_link} #{project_link}".html_safe
|
||||
end
|
||||
|
||||
def remove_project_message(project)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "Cohorts"
|
||||
- @no_container = true
|
||||
= render "admin/dashboard/head"
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
- @no_container = true
|
||||
- breadcrumb_title "Dashboard"
|
||||
= render "admin/dashboard/head"
|
||||
|
||||
%div{ class: container_class }
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- add_to_breadcrumbs "System Hooks", admin_hooks_path
|
||||
- page_title 'Edit System Hook'
|
||||
%h3.page-title
|
||||
Edit System Hook
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "Jobs"
|
||||
- @no_container = true
|
||||
= render "admin/dashboard/head"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "Runners"
|
||||
- @no_container = true
|
||||
= render "admin/dashboard/head"
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
- add_to_breadcrumbs "Users", admin_users_path
|
||||
- breadcrumb_title @user.name
|
||||
- page_title @user.name, "Users"
|
||||
= render 'admin/users/head'
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "General Settings"
|
||||
= render "groups/settings_head"
|
||||
.panel.panel-default.prepend-top-default
|
||||
.panel-heading
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "Projects"
|
||||
= render "groups/settings_head"
|
||||
|
||||
.panel.panel-default.prepend-top-default
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
- page_title "Pipelines"
|
||||
- breadcrumb_title "CI / CD Settings"
|
||||
- page_title "CI / CD"
|
||||
= render "groups/settings_head"
|
||||
|
||||
= render 'ci/variables/index'
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "Details"
|
||||
- @no_container = true
|
||||
|
||||
= render 'head'
|
||||
|
|
|
@ -1,28 +1,22 @@
|
|||
- breadcrumb_link = breadcrumb_title_link
|
||||
- container = @no_breadcrumb_container ? 'container-fluid' : container_class
|
||||
- hide_top_links = @hide_top_links || false
|
||||
|
||||
%nav.breadcrumbs{ role: "navigation" }
|
||||
%nav.breadcrumbs{ role: "navigation", class: [container, @content_class] }
|
||||
.breadcrumbs-container{ class: [container, @content_class] }
|
||||
- if defined?(@left_sidebar)
|
||||
= 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.js-breadcrumbs-list
|
||||
- unless hide_top_links
|
||||
.title
|
||||
= link_to "GitLab", root_path
|
||||
\/
|
||||
- if content_for?(:header_title_before)
|
||||
= 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
|
||||
= breadcrumb_list_item link_to(extra[:text], extra[:link])
|
||||
= render "layouts/nav/breadcrumbs/collapsed_dropdown", location: :after
|
||||
%li
|
||||
%h2.breadcrumbs-sub-title= @breadcrumb_title
|
||||
- if content_for?(:breadcrumbs_extra)
|
||||
.breadcrumbs-extra.hidden-xs= yield :breadcrumbs_extra
|
||||
= yield :header_content
|
||||
|
|
|
@ -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 * 16, 60].min}px;" }= link
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "Edit Password"
|
||||
- page_title "Password"
|
||||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "Access Tokens"
|
||||
- page_title "Personal Access Tokens"
|
||||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- breadcrumb_title "Profile"
|
||||
- breadcrumb_title "Edit Profile"
|
||||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
= render 'profiles/head'
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- @no_container = true
|
||||
- add_to_breadcrumbs(_("Project"), project_path(@project))
|
||||
|
||||
- page_title _("Activity")
|
||||
|
||||
= render "projects/head"
|
||||
|
||||
= render 'projects/last_push'
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
- breadcrumb_title _('Artifacts')
|
||||
- page_title @path.presence, 'Artifacts', "#{@build.name} (##{@build.id})", 'Jobs'
|
||||
= render "projects/pipelines/head"
|
||||
|
||||
= render "projects/jobs/header", show_controls: false
|
||||
|
||||
- add_to_breadcrumbs(_('Jobs'), project_jobs_path(@project))
|
||||
- add_to_breadcrumbs("##{@build.id}", project_jobs_path(@project))
|
||||
|
||||
.tree-holder
|
||||
.nav-block
|
||||
%ul.breadcrumb.repo-breadcrumb
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
- @no_breadcrumb_container = true
|
||||
- @no_container = true
|
||||
- @content_class = "issue-boards-content"
|
||||
- breadcrumb_title "Issue Board"
|
||||
- page_title "Boards"
|
||||
- add_to_breadcrumbs("Issues", project_issues_path(@project))
|
||||
|
||||
- content_for :page_specific_javascripts do
|
||||
= webpack_bundle_tag 'common_vue'
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
- @no_container = true
|
||||
- page_title "Branches"
|
||||
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
||||
|
||||
= render "projects/commits/head"
|
||||
|
||||
%div{ class: container_class }
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @no_container = true
|
||||
- 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'
|
||||
- @content_class = limited_container_width
|
||||
|
|
|
@ -5,8 +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")
|
||||
|
||||
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
||||
|
||||
= content_for :sub_nav do
|
||||
= render "head"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- @no_container = true
|
||||
- breadcrumb_title "Compare Revisions"
|
||||
- page_title "Compare"
|
||||
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
||||
= render "projects/commits/head"
|
||||
|
||||
%div{ class: container_class }
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
- @no_container = true
|
||||
- breadcrumb_title "Compare"
|
||||
- add_to_breadcrumbs "Compare Revisions", project_compare_index_path(@project)
|
||||
- page_title "#{params[:from]}...#{params[:to]}"
|
||||
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
||||
= render "projects/commits/head"
|
||||
|
||||
%div{ class: container_class }
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
- @no_container = true
|
||||
- page_title "Cycle Analytics"
|
||||
- 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')
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
- breadcrumb_title "General Settings"
|
||||
- page_title "General"
|
||||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
- expanded = Rails.env.test?
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
- @no_container = true
|
||||
- breadcrumb_title "Details"
|
||||
|
||||
= render partial: 'flash_messages', locals: { project: @project }
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @no_container = true
|
||||
- add_to_breadcrumbs "Environments", project_environments_path(@project)
|
||||
- breadcrumb_title @environment.name
|
||||
- page_title "Environments"
|
||||
= render "projects/pipelines/head"
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
- @no_container = true
|
||||
- page_title "Charts"
|
||||
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
||||
- content_for :page_specific_javascripts do
|
||||
= webpack_bundle_tag('common_d3')
|
||||
= webpack_bundle_tag('graphs')
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
= webpack_bundle_tag('graphs')
|
||||
= webpack_bundle_tag('graphs_show')
|
||||
|
||||
- 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) }
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
- 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
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
- page_title "Jobs"
|
||||
= render "projects/pipelines/head"
|
||||
|
||||
- add_to_breadcrumbs("Pipelines", project_pipelines_path(@project))
|
||||
|
||||
%div{ class: container_class }
|
||||
.top-area
|
||||
- build_path_proc = ->(scope) { project_jobs_path(@project, scope: scope) }
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @no_container = true
|
||||
- add_to_breadcrumbs "Jobs", project_jobs_path(@project)
|
||||
- breadcrumb_title "##{@build.id}"
|
||||
- page_title "#{@build.name} (##{@build.id})", "Jobs"
|
||||
= render "projects/pipelines/head"
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
- 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
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @no_container = true
|
||||
- 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"
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
- page_title "Graph", @ref
|
||||
- content_for :page_specific_javascripts do
|
||||
= page_specific_javascript_bundle_tag('network')
|
||||
- add_to_breadcrumbs("Repository", project_tree_path(@project))
|
||||
= render "projects/commits/head"
|
||||
= render "head"
|
||||
%div{ class: container_class }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- breadcrumb_title "Schedules"
|
||||
- breadcrumb_title _("Schedules")
|
||||
|
||||
- content_for :page_specific_javascripts do
|
||||
= webpack_bundle_tag 'common_vue'
|
||||
|
@ -11,8 +11,6 @@
|
|||
- content_for :breadcrumbs_extra do
|
||||
= link_to _('New schedule'), new_namespace_project_pipeline_schedule_path(@project.namespace, @project), class: 'btn btn-create'
|
||||
|
||||
- add_to_breadcrumbs("Pipelines", project_pipelines_path(@project))
|
||||
|
||||
= render "projects/pipelines/head"
|
||||
|
||||
%div{ class: container_class }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- @no_container = true
|
||||
- breadcrumb_title "CI / CD Charts"
|
||||
- page_title _("Charts"), _("Pipelines")
|
||||
- add_to_breadcrumbs("Pipelines", project_pipelines_path(@project))
|
||||
- content_for :page_specific_javascripts do
|
||||
= page_specific_javascript_bundle_tag('common_d3')
|
||||
= page_specific_javascript_bundle_tag('graphs')
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @no_container = true
|
||||
- add_to_breadcrumbs "Pipelines", project_pipelines_path(@project)
|
||||
- breadcrumb_title "##{@pipeline.id}"
|
||||
- page_title "Pipeline"
|
||||
= render "projects/pipelines/head"
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
- page_title "Members"
|
||||
|
||||
- add_to_breadcrumbs("Settings", edit_project_path(@project))
|
||||
|
||||
.row.prepend-top-default
|
||||
.col-lg-12
|
||||
%h4
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
- page_title "Pipelines"
|
||||
- add_to_breadcrumbs("Settings", edit_project_path(@project))
|
||||
- page_title "CI / CD Settings"
|
||||
- page_title "CI / CD"
|
||||
|
||||
= render "projects/settings/head"
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
- breadcrumb_title "Integrations Settings"
|
||||
- page_title 'Integrations'
|
||||
- add_to_breadcrumbs("Settings", edit_project_path(@project))
|
||||
= render "projects/settings/head"
|
||||
= render 'projects/hooks/index'
|
||||
= render 'projects/services/index'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- breadcrumb_title "Repository Settings"
|
||||
- page_title "Repository"
|
||||
- @content_class = "limit-container-width" unless fluid_layout
|
||||
- add_to_breadcrumbs("Settings", edit_project_path(@project))
|
||||
|
||||
= render "projects/settings/head"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
- add_to_breadcrumbs "Snippets", project_snippets_path(@project)
|
||||
- breadcrumb_title "New"
|
||||
- page_title "New Snippets"
|
||||
|
||||
%h3.page-title
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @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'
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
- @no_container = true
|
||||
- add_to_breadcrumbs "Tags", project_tags_path(@project)
|
||||
- breadcrumb_title @tag.name
|
||||
- page_title @tag.name, "Tags"
|
||||
= render "projects/commits/head"
|
||||
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
- @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"
|
||||
- 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)
|
||||
|
||||
.nav-text
|
||||
%h2.wiki-page-title= @page.title.capitalize
|
||||
%span.wiki-last-edit-by
|
||||
|
|
|
@ -3,10 +3,8 @@
|
|||
%span.sr-only
|
||||
= visibility_level_label(@snippet.visibility_level)
|
||||
= visibility_level_icon(@snippet.visibility_level, fw: false)
|
||||
%strong.item-title
|
||||
Snippet #{@snippet.to_reference}
|
||||
%span.creator
|
||||
authored
|
||||
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")}
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -36,13 +36,13 @@ class Spinach::Features::ExploreProjects < Spinach::FeatureSteps
|
|||
end
|
||||
|
||||
step 'I should see project "Community" home page' do
|
||||
page.within '.breadcrumbs .title' do
|
||||
page.within '.breadcrumbs .breadcrumb-item-text' do
|
||||
expect(page).to have_content 'Community'
|
||||
end
|
||||
end
|
||||
|
||||
step 'I should see project "Internal" home page' do
|
||||
page.within '.breadcrumbs .title' do
|
||||
page.within '.breadcrumbs .breadcrumb-item-text' do
|
||||
expect(page).to have_content 'Internal'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps
|
|||
|
||||
step 'I should see project "Community" home page' do
|
||||
Gitlab.config.gitlab.should_receive(:host).and_return("www.example.com")
|
||||
page.within '.breadcrumbs .title' do
|
||||
page.within '.breadcrumbs .breadcrumb-item-text' do
|
||||
expect(page).to have_content 'Community'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -166,12 +166,10 @@ describe 'New/edit issue', :js do
|
|||
end
|
||||
end
|
||||
|
||||
page.within '.issuable-meta' do
|
||||
page.within '.breadcrumbs' do
|
||||
issue = Issue.find_by(title: 'title')
|
||||
|
||||
expect(page).to have_text("Issue #{issue.to_reference}")
|
||||
# compare paths because the host differ in test
|
||||
expect(find_link(issue.to_reference)[:href]).to end_with(issue_path(issue))
|
||||
expect(page).to have_text("Issues #{issue.to_reference}")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -84,13 +84,10 @@ describe 'New/edit merge request', :js do
|
|||
end
|
||||
end
|
||||
|
||||
page.within '.issuable-meta' do
|
||||
page.within '.breadcrumbs' do
|
||||
merge_request = MergeRequest.find_by(source_branch: 'fix')
|
||||
|
||||
expect(page).to have_text("Merge request #{merge_request.to_reference}")
|
||||
# compare paths because the host differ in test
|
||||
expect(find_link(merge_request.to_reference)[:href])
|
||||
.to end_with(merge_request_path(merge_request))
|
||||
expect(page).to have_text("Merge Requests #{merge_request.to_reference}")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ describe 'Subgroup Issuables', :js, :nested_groups do
|
|||
def expect_to_have_full_subgroup_title
|
||||
title = find('.breadcrumbs-links')
|
||||
|
||||
expect(title).not_to have_selector '.initializing'
|
||||
expect(title).to have_content 'group / subgroup / project'
|
||||
expect(title).to have_content 'group subgroup project'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -91,7 +91,8 @@ describe GroupsHelper do
|
|||
let!(:very_deep_nested_group) { create(:group, parent: deep_nested_group) }
|
||||
|
||||
it 'outputs the groups in the correct order' do
|
||||
expect(helper.group_title(very_deep_nested_group)).to match(/>#{group.name}<\/a>.*>#{nested_group.name}<\/a>.*>#{deep_nested_group.name}<\/a>/)
|
||||
expect(helper.group_title(very_deep_nested_group))
|
||||
.to match(/<li style="text-indent: 16px;"><a.*>#{deep_nested_group.name}.*<\/li>.*<a.*>#{very_deep_nested_group.name}<\/a>/m)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue