summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2017-09-06 21:00:47 +0200
committerKamil Trzcinski <ayufan@ayufan.eu>2017-09-06 21:00:47 +0200
commitcd8ea329f0d64c04e5dee00fb8916268dae7a6f7 (patch)
treea77f550a9acfce3c64484ff9f300a560b6587bd0 /app
parent632f6ba267bc09a658defc3721d2b52de05cf7e6 (diff)
parentbb1ad6edcd62d8e8b8a1a37ed0782bdf7bf2bbd1 (diff)
downloadgitlab-ce-cd8ea329f0d64c04e5dee00fb8916268dae7a6f7.tar.gz
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into zj/gitlab-ce-zj-auto-devops-table
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/breadcrumb.js28
-rw-r--r--app/assets/javascripts/dispatcher.js7
-rw-r--r--app/assets/javascripts/group_name.js67
-rw-r--r--app/assets/javascripts/main.js3
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss1
-rw-r--r--app/assets/stylesheets/new_nav.scss153
-rw-r--r--app/assets/stylesheets/new_sidebar.scss5
-rw-r--r--app/assets/stylesheets/pages/commits.scss6
-rw-r--r--app/assets/stylesheets/pages/notes.scss18
-rw-r--r--app/controllers/admin/logs_controller.rb9
-rw-r--r--app/controllers/concerns/renders_commits.rb7
-rw-r--r--app/controllers/concerns/renders_notes.rb9
-rw-r--r--app/controllers/profiles_controller.rb2
-rw-r--r--app/controllers/projects/artifacts_controller.rb12
-rw-r--r--app/controllers/projects/commit_controller.rb2
-rw-r--r--app/controllers/projects/commits_controller.rb3
-rw-r--r--app/controllers/projects/compare_controller.rb3
-rw-r--r--app/controllers/projects/issues_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb3
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb9
-rw-r--r--app/controllers/projects/snippets_controller.rb2
-rw-r--r--app/controllers/search_controller.rb7
-rw-r--r--app/controllers/snippets_controller.rb2
-rw-r--r--app/helpers/blame_helper.rb16
-rw-r--r--app/helpers/breadcrumbs_helper.rb12
-rw-r--r--app/helpers/groups_helper.rb28
-rw-r--r--app/helpers/issuables_helper.rb19
-rw-r--r--app/helpers/markup_helper.rb30
-rw-r--r--app/helpers/notes_helper.rb2
-rw-r--r--app/helpers/page_layout_helper.rb4
-rw-r--r--app/helpers/profiles_helper.rb13
-rw-r--r--app/helpers/projects_helper.rb15
-rw-r--r--app/helpers/wiki_helper.rb11
-rw-r--r--app/models/ci/build.rb1
-rw-r--r--app/models/ci/pipeline.rb1
-rw-r--r--app/models/commit.rb9
-rw-r--r--app/models/concerns/issuable.rb7
-rw-r--r--app/models/merge_request.rb6
-rw-r--r--app/models/note.rb35
-rw-r--r--app/models/project_team.rb2
-rw-r--r--app/models/user.rb22
-rw-r--r--app/models/user_synced_attributes_metadata.rb25
-rw-r--r--app/services/users/update_service.rb4
-rw-r--r--app/views/admin/applications/edit.html.haml2
-rw-r--r--app/views/admin/cohorts/index.html.haml1
-rw-r--r--app/views/admin/dashboard/index.html.haml1
-rw-r--r--app/views/admin/groups/show.html.haml2
-rw-r--r--app/views/admin/hooks/edit.html.haml1
-rw-r--r--app/views/admin/jobs/index.html.haml1
-rw-r--r--app/views/admin/labels/edit.html.haml2
-rw-r--r--app/views/admin/projects/show.html.haml2
-rw-r--r--app/views/admin/runners/index.html.haml1
-rw-r--r--app/views/admin/services/edit.html.haml2
-rw-r--r--app/views/admin/users/show.html.haml2
-rw-r--r--app/views/ci/variables/_content.html.haml12
-rw-r--r--app/views/ci/variables/_index.html.haml4
-rw-r--r--app/views/ci/variables/_show.html.haml2
-rw-r--r--app/views/groups/edit.html.haml1
-rw-r--r--app/views/groups/projects.html.haml1
-rw-r--r--app/views/groups/settings/ci_cd/show.html.haml3
-rw-r--r--app/views/groups/show.html.haml2
-rw-r--r--app/views/groups/subgroups.html.haml1
-rw-r--r--app/views/layouts/nav/_breadcrumbs.html.haml24
-rw-r--r--app/views/layouts/nav/breadcrumbs/_collapsed_dropdown.html.haml11
-rw-r--r--app/views/profiles/passwords/edit.html.haml1
-rw-r--r--app/views/profiles/personal_access_tokens/index.html.haml1
-rw-r--r--app/views/profiles/show.html.haml18
-rw-r--r--app/views/projects/activity.html.haml2
-rw-r--r--app/views/projects/artifacts/browse.html.haml4
-rw-r--r--app/views/projects/blame/show.html.haml2
-rw-r--r--app/views/projects/boards/_show.html.haml2
-rw-r--r--app/views/projects/branches/_commit.html.haml2
-rw-r--r--app/views/projects/branches/index.html.haml2
-rw-r--r--app/views/projects/commit/show.html.haml2
-rw-r--r--app/views/projects/commits/_commit.html.haml5
-rw-r--r--app/views/projects/commits/_inline_commit.html.haml2
-rw-r--r--app/views/projects/commits/show.html.haml2
-rw-r--r--app/views/projects/compare/index.html.haml2
-rw-r--r--app/views/projects/compare/show.html.haml3
-rw-r--r--app/views/projects/cycle_analytics/show.html.haml1
-rw-r--r--app/views/projects/deployments/_commit.html.haml2
-rw-r--r--app/views/projects/edit.html.haml1
-rw-r--r--app/views/projects/empty.html.haml1
-rw-r--r--app/views/projects/environments/show.html.haml2
-rw-r--r--app/views/projects/graphs/charts.html.haml1
-rw-r--r--app/views/projects/graphs/show.html.haml2
-rw-r--r--app/views/projects/issues/show.html.haml2
-rw-r--r--app/views/projects/jobs/index.html.haml2
-rw-r--r--app/views/projects/jobs/show.html.haml2
-rw-r--r--app/views/projects/merge_requests/show.html.haml2
-rw-r--r--app/views/projects/milestones/show.html.haml2
-rw-r--r--app/views/projects/network/show.html.haml1
-rw-r--r--app/views/projects/notes/_actions.html.haml8
-rw-r--r--app/views/projects/notes/_more_actions_dropdown.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/edit.html.haml2
-rw-r--r--app/views/projects/pipeline_schedules/index.html.haml4
-rw-r--r--app/views/projects/pipelines/charts.html.haml2
-rw-r--r--app/views/projects/pipelines/show.html.haml2
-rw-r--r--app/views/projects/pipelines_settings/_badge.html.haml62
-rw-r--r--app/views/projects/pipelines_settings/_show.html.haml5
-rw-r--r--app/views/projects/project_members/index.html.haml2
-rw-r--r--app/views/projects/releases/edit.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/show.html.haml56
-rw-r--r--app/views/projects/settings/integrations/show.html.haml2
-rw-r--r--app/views/projects/settings/repository/show.html.haml2
-rw-r--r--app/views/projects/show.html.haml2
-rw-r--r--app/views/projects/snippets/edit.html.haml2
-rw-r--r--app/views/projects/snippets/new.html.haml2
-rw-r--r--app/views/projects/snippets/show.html.haml2
-rw-r--r--app/views/projects/tags/show.html.haml2
-rw-r--r--app/views/projects/tree/_tree_commit_column.html.haml2
-rw-r--r--app/views/projects/triggers/_content.html.haml10
-rw-r--r--app/views/projects/triggers/_index.html.haml3
-rw-r--r--app/views/projects/wikis/pages.html.haml2
-rw-r--r--app/views/projects/wikis/show.html.haml7
-rw-r--r--app/views/shared/notes/_note.html.haml4
-rw-r--r--app/views/shared/projects/_project.html.haml3
-rw-r--r--app/views/shared/snippets/_header.html.haml4
-rw-r--r--app/views/snippets/show.html.haml2
120 files changed, 577 insertions, 394 deletions
diff --git a/app/assets/javascripts/breadcrumb.js b/app/assets/javascripts/breadcrumb.js
new file mode 100644
index 00000000000..10fbcfe96cf
--- /dev/null
+++ b/app/assets/javascripts/breadcrumb.js
@@ -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');
+ });
+ }
+};
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 3dec4de06ec..6db0b18ae5a 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -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';
@@ -489,6 +488,8 @@ import initChangesDropdown from './init_changes_dropdown';
initSettingsPanels();
break;
case 'projects:settings:ci_cd:show':
+ // Initialize expandable settings panels
+ initSettingsPanels();
case 'groups:settings:ci_cd:show':
new gl.ProjectVariables();
break;
@@ -554,9 +555,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 +562,6 @@ import initChangesDropdown from './init_changes_dropdown';
case 'projects':
new Project();
new ProjectAvatar();
- new GroupName();
switch (path[1]) {
case 'compare':
new CompareAutocomplete();
diff --git a/app/assets/javascripts/group_name.js b/app/assets/javascripts/group_name.js
deleted file mode 100644
index 6677391c689..00000000000
--- a/app/assets/javascripts/group_name.js
+++ /dev/null
@@ -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');
- }
-}
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index f14458c8d41..0bc31a56684 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -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 || '/';
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 6b21def33a6..5f397f08936 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -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 {
diff --git a/app/assets/stylesheets/new_nav.scss b/app/assets/stylesheets/new_nav.scss
index 4deb7431284..e4b52ab480d 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";
.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;
- }
- }
- }
+ color: $gl-text-color-secondary;
.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,37 +463,52 @@ header.navbar-gitlab-new {
}
}
-.breadcrumbs-extra {
+.breadcrumbs-list {
+ display: -webkit-flex;
display: flex;
- flex: 0 0 auto;
- margin-left: auto;
-}
+ flex-wrap: wrap;
+ margin-bottom: 0;
+ line-height: 16px;
-.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;
+ > li {
+ display: flex;
+ align-items: center;
+ position: relative;
&:not(:last-child) {
- &::after {
- content: "/";
- margin: 0 2px 0 5px;
- color: rgba($black, .65);
- }
+ margin-right: 20px;
}
- &:last-child a {
- font-weight: $gl-font-weight-bold;
+ > 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;
+ margin-left: auto;
+}
+
+.breadcrumbs-sub-title {
+ margin: 0;
+ font-size: 12px;
+ font-weight: 600;
+ line-height: 1;
a {
color: $gl-text-color;
diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss
index 90b0a543c5c..fd5e344d8c9 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: $gl-font-weight-bold;
display: flex;
align-items: center;
@@ -389,6 +388,10 @@ $new-sidebar-collapsed-width: 50px;
}
}
+ .nav-icon-container {
+ margin-right: 0;
+ }
+
.toggle-sidebar-button {
width: $new-sidebar-collapsed-width - 2px;
padding: 16px 18px;
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index bfa2a155cdf..994707422bb 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -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);
}
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index 45f2aed1531..e437bad4912 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -516,7 +516,7 @@ ul.notes {
}
.note-actions-item {
- margin-left: 15px;
+ margin-left: 12px;
display: flex;
align-items: center;
@@ -620,15 +620,25 @@ ul.notes {
.note-role {
position: relative;
- padding: 0 7px;
+ display: inline-block;
color: $notes-role-color;
font-size: 12px;
line-height: 20px;
- border: 1px solid $border-color;
- border-radius: $label-border-radius;
+ margin: 0 3px;
+
+ &.note-role-access {
+ padding: 0 7px;
+ border: 1px solid $border-color;
+ border-radius: $label-border-radius;
+ }
+
+ &.note-role-special {
+ text-shadow: 0 0 15px $gl-text-color-inverted;
+ }
}
+
/**
* Line note button on the side of diffs
*/
diff --git a/app/controllers/admin/logs_controller.rb b/app/controllers/admin/logs_controller.rb
index bdc4332ae69..12a27cede75 100644
--- a/app/controllers/admin/logs_controller.rb
+++ b/app/controllers/admin/logs_controller.rb
@@ -1,6 +1,13 @@
class Admin::LogsController < Admin::ApplicationController
+ before_action :loggers
+
def show
- @loggers = [
+ end
+
+ private
+
+ def loggers
+ @loggers ||= [
Gitlab::AppLogger,
Gitlab::GitLogger,
Gitlab::EnvironmentLogger,
diff --git a/app/controllers/concerns/renders_commits.rb b/app/controllers/concerns/renders_commits.rb
new file mode 100644
index 00000000000..bb2c1dfa00a
--- /dev/null
+++ b/app/controllers/concerns/renders_commits.rb
@@ -0,0 +1,7 @@
+module RendersCommits
+ def prepare_commits_for_rendering(commits)
+ Banzai::CommitRenderer.render(commits, @project, current_user)
+
+ commits
+ end
+end
diff --git a/app/controllers/concerns/renders_notes.rb b/app/controllers/concerns/renders_notes.rb
index 41c3114ad1e..4791bc561a4 100644
--- a/app/controllers/concerns/renders_notes.rb
+++ b/app/controllers/concerns/renders_notes.rb
@@ -1,7 +1,8 @@
module RendersNotes
- def prepare_notes_for_rendering(notes)
+ def prepare_notes_for_rendering(notes, noteable = nil)
preload_noteable_for_regular_notes(notes)
preload_max_access_for_authors(notes, @project)
+ preload_first_time_contribution_for_authors(noteable, notes)
Banzai::NoteRenderer.render(notes, @project, current_user)
notes
@@ -19,4 +20,10 @@ module RendersNotes
def preload_noteable_for_regular_notes(notes)
ActiveRecord::Associations::Preloader.new.preload(notes.reject(&:for_commit?), :noteable)
end
+
+ def preload_first_time_contribution_for_authors(noteable, notes)
+ return unless noteable.is_a?(Issuable) && noteable.first_contribution?
+
+ notes.each {|n| n.specialize_for_first_contribution!(noteable)}
+ end
end
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index 076076fd1b3..d83824fef06 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -9,8 +9,6 @@ class ProfilesController < Profiles::ApplicationController
end
def update
- user_params.except!(:email) if @user.external_email?
-
respond_to do |format|
result = Users::UpdateService.new(@user, user_params).execute
diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb
index f637a9a803b..eb010923466 100644
--- a/app/controllers/projects/artifacts_controller.rb
+++ b/app/controllers/projects/artifacts_controller.rb
@@ -7,7 +7,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
before_action :authorize_update_build!, only: [:keep]
before_action :extract_ref_name_and_path
before_action :validate_artifacts!
- before_action :set_path_and_entry, only: [:file, :raw]
+ before_action :entry, only: [:file]
def download
if artifacts_file.file_storage?
@@ -41,7 +41,10 @@ class Projects::ArtifactsController < Projects::ApplicationController
end
def raw
- send_artifacts_entry(build, @entry)
+ path = Gitlab::Ci::Build::Artifacts::Path
+ .new(params[:path])
+
+ send_artifacts_entry(build, path)
end
def keep
@@ -93,9 +96,8 @@ class Projects::ArtifactsController < Projects::ApplicationController
@artifacts_file ||= build.artifacts_file
end
- def set_path_and_entry
- @path = params[:path]
- @entry = build.artifacts_metadata_entry(@path)
+ def entry
+ @entry = build.artifacts_metadata_entry(params[:path])
render_404 unless @entry.exists?
end
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 6de125e7e80..1a775def506 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -127,7 +127,7 @@ class Projects::CommitController < Projects::ApplicationController
@discussions = commit.discussions
@notes = (@grouped_diff_discussions.values.flatten + @discussions).flat_map(&:notes)
- @notes = prepare_notes_for_rendering(@notes)
+ @notes = prepare_notes_for_rendering(@notes, @commit)
end
def assign_change_commit_vars
diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb
index 2de9900d449..4a841bf2073 100644
--- a/app/controllers/projects/commits_controller.rb
+++ b/app/controllers/projects/commits_controller.rb
@@ -2,6 +2,7 @@ require "base64"
class Projects::CommitsController < Projects::ApplicationController
include ExtractsPath
+ include RendersCommits
before_action :require_non_empty_project
before_action :assign_ref_vars
@@ -56,5 +57,7 @@ class Projects::CommitsController < Projects::ApplicationController
else
@repository.commits(@ref, path: @path, limit: @limit, offset: @offset)
end
+
+ @commits = prepare_commits_for_rendering(@commits)
end
end
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index c8613c0d634..193549663ac 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -3,6 +3,7 @@ require 'addressable/uri'
class Projects::CompareController < Projects::ApplicationController
include DiffForPath
include DiffHelper
+ include RendersCommits
# Authorize
before_action :require_non_empty_project
@@ -50,7 +51,7 @@ class Projects::CompareController < Projects::ApplicationController
.execute(@project, @start_ref)
if @compare
- @commits = @compare.commits
+ @commits = prepare_commits_for_rendering(@compare.commits)
@diffs = @compare.diffs(diff_options)
environment_params = @repository.branch_exists?(@head_ref) ? { ref: @head_ref } : { commit: @compare.commit }
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index dc9e6f71152..ab9f132b502 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -85,7 +85,7 @@ class Projects::IssuesController < Projects::ApplicationController
@note = @project.notes.new(noteable: @issue)
@discussions = @issue.discussions
- @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
+ @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
respond_to do |format|
format.html
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index f35d53896ba..1096afbb798 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -1,6 +1,7 @@
class Projects::MergeRequests::CreationsController < Projects::MergeRequests::ApplicationController
include DiffForPath
include DiffHelper
+ include RendersCommits
skip_before_action :merge_request
skip_before_action :ensure_ref_fetched
@@ -107,7 +108,7 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
@target_project = @merge_request.target_project
@source_project = @merge_request.source_project
- @commits = @merge_request.commits
+ @commits = prepare_commits_for_rendering(@merge_request.commits)
@commit = @merge_request.diff_head_commit
@note_counts = Note.where(commit_id: @commits.map(&:id))
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 330b7df4541..109418c73f7 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -61,6 +61,6 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
@use_legacy_diff_notes = !@merge_request.has_complete_diff_refs?
@grouped_diff_discussions = @merge_request.grouped_diff_discussions(@compare.diff_refs)
- @notes = prepare_notes_for_rendering(@grouped_diff_discussions.values.flatten.flat_map(&:notes))
+ @notes = prepare_notes_for_rendering(@grouped_diff_discussions.values.flatten.flat_map(&:notes), @merge_request)
end
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 5095d7fd445..3aa5dadb5ca 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -2,6 +2,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
include ToggleSubscriptionAction
include IssuableActions
include RendersNotes
+ include RendersCommits
include ToggleAwardEmoji
include IssuableCollections
@@ -60,12 +61,12 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
# Build a note object for comment form
@note = @project.notes.new(noteable: @merge_request)
- @discussions = @merge_request.discussions
- @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
-
@noteable = @merge_request
@commits_count = @merge_request.commits_count
+ @discussions = @merge_request.discussions
+ @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
+
labels
set_pipeline_variables
@@ -94,7 +95,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
def commits
# Get commits from repository
# or from cache if already merged
- @commits = @merge_request.commits
+ @commits = prepare_commits_for_rendering(@merge_request.commits)
@note_counts = Note.where(commit_id: @commits.map(&:id))
.group(:commit_id).count
diff --git a/app/controllers/projects/snippets_controller.rb b/app/controllers/projects/snippets_controller.rb
index d07143d294f..7c19aa7bb23 100644
--- a/app/controllers/projects/snippets_controller.rb
+++ b/app/controllers/projects/snippets_controller.rb
@@ -64,7 +64,7 @@ class Projects::SnippetsController < Projects::ApplicationController
@noteable = @snippet
@discussions = @snippet.discussions
- @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
+ @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
render 'show'
end
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index d58c8d14a75..fbad9ba7db8 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -2,6 +2,7 @@ class SearchController < ApplicationController
skip_before_action :authenticate_user!
include SearchHelper
+ include RendersCommits
layout 'search'
@@ -20,6 +21,8 @@ class SearchController < ApplicationController
@search_results = search_service.search_results
@search_objects = search_service.search_objects
+ render_commits if @scope == 'commits'
+
check_single_commit_result
end
@@ -38,6 +41,10 @@ class SearchController < ApplicationController
private
+ def render_commits
+ @search_objects = prepare_commits_for_rendering(@search_objects)
+ end
+
def check_single_commit_result
if @search_results.single_commit_result?
only_commit = @search_results.objects('commits').first
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index 8c3abd0a085..c1cdc7c9831 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -66,7 +66,7 @@ class SnippetsController < ApplicationController
@noteable = @snippet
@discussions = @snippet.discussions
- @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes))
+ @notes = prepare_notes_for_rendering(@discussions.flat_map(&:notes), @noteable)
respond_to do |format|
format.html do
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
diff --git a/app/helpers/breadcrumbs_helper.rb b/app/helpers/breadcrumbs_helper.rb
index abe8edd6a8c..ee1b7ed083e 100644
--- a/app/helpers/breadcrumbs_helper.rb
+++ b/app/helpers/breadcrumbs_helper.rb
@@ -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
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index c4c41eac5db..eab1feb8a1f 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -15,18 +15,20 @@ 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 += ' &middot; '.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")
- content_tag :span, class: 'group-title' do
- full_title.html_safe
- end
+ full_title += breadcrumb_list_item group_title_link(group)
+ full_title += ' &middot; '.html_safe + link_to(simple_sanitize(name), url, class: 'group-path breadcrumb-item-text js-breadcrumb-item-text') if name
+
+ full_title.html_safe
end
def projects_lfs_status(group)
@@ -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
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 717abf2082d..ce2999e6696 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -126,22 +126,20 @@ 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")
end
output << "&ensp;".html_safe
+ output << content_tag(:span, (issuable_first_contribution_icon if issuable.first_contribution?), class: 'has-tooltip', title: _('1st contribution!'))
+
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)
@@ -173,6 +171,13 @@ module IssuablesHelper
html.html_safe
end
+ def issuable_first_contribution_icon
+ content_tag(:span, class: 'fa-stack') do
+ concat(icon('certificate', class: "fa-stack-2x"))
+ concat(content_tag(:strong, '1', class: 'fa-inverse fa-stack-1x'))
+ end
+ end
+
def assigned_issuables_count(issuable_type)
case issuable_type
when :issues
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index 941cfce8370..46bced00c72 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -21,25 +21,28 @@ module MarkupHelper
end
# Use this in places where you would normally use link_to(gfm(...), ...).
- #
+ def link_to_markdown(body, url, html_options = {})
+ return '' if body.blank?
+
+ link_to_html(markdown(body, pipeline: :single_line), url, html_options)
+ end
+
+ def link_to_markdown_field(object, field, url, html_options = {})
+ rendered_field = markdown_field(object, field)
+
+ link_to_html(rendered_field, url, html_options)
+ end
+
# It solves a problem occurring with nested links (i.e.
# "<a>outer text <a>gfm ref</a> more outer text</a>"). This will not be
# interpreted as intended. Browsers will parse something like
# "<a>outer text </a><a>gfm ref</a> more outer text" (notice the last part is
- # not linked any more). link_to_gfm corrects that. It wraps all parts to
+ # not linked any more). link_to_html corrects that. It wraps all parts to
# explicitly produce the correct linking behavior (i.e.
# "<a>outer text </a><a>gfm ref</a><a> more outer text</a>").
- def link_to_gfm(body, url, html_options = {})
- return '' if body.blank?
+ def link_to_html(redacted, url, html_options = {})
+ fragment = Nokogiri::HTML::DocumentFragment.parse(redacted)
- context = {
- project: @project,
- current_user: (current_user if defined?(current_user)),
- pipeline: :single_line
- }
- gfm_body = Banzai.render(body, context)
-
- fragment = Nokogiri::HTML::DocumentFragment.parse(gfm_body)
if fragment.children.size == 1 && fragment.children[0].name == 'a'
# Fragment has only one node, and it's a link generated by `gfm`.
# Replace it with our requested link.
@@ -82,7 +85,10 @@ module MarkupHelper
def markdown_field(object, field)
object = object.for_display if object.respond_to?(:for_display)
+ redacted_field_html = object.try(:"redacted_#{field}_html")
+
return '' unless object.present?
+ return redacted_field_html if redacted_field_html
html = Banzai.render_field(object, field)
prepare_for_rendering(html, object.banzai_render_context(field))
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 083ace65b09..ce028195e51 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -73,7 +73,7 @@ module NotesHelper
end
def note_max_access_for_user(note)
- note.project.team.human_max_access(note.author_id)
+ note.project.team.max_member_access(note.author_id)
end
def discussion_path(discussion)
diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb
index d83c7411c9d..5946c475835 100644
--- a/app/helpers/page_layout_helper.rb
+++ b/app/helpers/page_layout_helper.rb
@@ -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
diff --git a/app/helpers/profiles_helper.rb b/app/helpers/profiles_helper.rb
index 45238f12ac7..5a4fda0724c 100644
--- a/app/helpers/profiles_helper.rb
+++ b/app/helpers/profiles_helper.rb
@@ -1,7 +1,12 @@
module ProfilesHelper
- def email_provider_label
- return unless current_user.external_email?
-
- current_user.email_provider.present? ? Gitlab::OAuth::Provider.label_for(current_user.email_provider) : "LDAP"
+ def attribute_provider_label(attribute)
+ user_synced_attributes_metadata = current_user.user_synced_attributes_metadata
+ if user_synced_attributes_metadata&.synced?(attribute)
+ if user_synced_attributes_metadata.provider
+ Gitlab::OAuth::Provider.label_for(user_synced_attributes_metadata.provider)
+ else
+ 'LDAP'
+ end
+ end
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index cec7656773c..86665ea2aec 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -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)
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index 99212a3438f..815fab9e061 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/models/ci/build.rb b/app/models/ci/build.rb
index c439997d636..5ebe6f180e6 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -27,7 +27,6 @@ module Ci
validates :coverage, numericality: true, allow_blank: true
validates :ref, presence: true
- validates :protected, inclusion: { in: [true, false], unless: :importing? }, on: :create
scope :unstarted, ->() { where(runner_id: nil) }
scope :ignore_failures, ->() { where(allow_failure: false) }
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 0e1b3b29e07..871c76fbad3 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -36,7 +36,6 @@ module Ci
validates :sha, presence: { unless: :importing? }
validates :ref, presence: { unless: :importing? }
validates :status, presence: { unless: :importing? }
- validates :protected, inclusion: { in: [true, false], unless: :importing? }, on: :create
validate :valid_commit_sha, unless: :importing?
after_initialize :set_config_source, if: :new_record?
diff --git a/app/models/commit.rb b/app/models/commit.rb
index ba3845df867..2ae8890c1b3 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -16,6 +16,8 @@ class Commit
participant :notes_with_associations
attr_accessor :project, :author
+ attr_accessor :redacted_description_html
+ attr_accessor :redacted_title_html
DIFF_SAFE_LINES = Gitlab::Git::DiffCollection::DEFAULT_LIMITS[:max_lines]
@@ -26,6 +28,13 @@ class Commit
# The SHA can be between 7 and 40 hex characters.
COMMIT_SHA_PATTERN = '\h{7,40}'.freeze
+ def banzai_render_context(field)
+ context = { pipeline: :single_line, project: self.project }
+ context[:author] = self.author if self.author
+
+ context
+ end
+
class << self
def decorate(commits, project)
commits.map do |commit|
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 681c3241dbb..265f6e48540 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -334,4 +334,11 @@ module Issuable
metrics = self.metrics || create_metrics
metrics.record!
end
+
+ ##
+ # Override in issuable specialization
+ #
+ def first_contribution?
+ false
+ end
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index b82f49d7073..2a56bab48a3 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -960,6 +960,12 @@ class MergeRequest < ActiveRecord::Base
Projects::OpenMergeRequestsCountService.new(target_project).refresh_cache
end
+ def first_contribution?
+ return false if project.team.max_member_access(author_id) > Gitlab::Access::GUEST
+
+ project.merge_requests.merged.where(author_id: author_id).empty?
+ end
+
private
def write_ref
diff --git a/app/models/note.rb b/app/models/note.rb
index 1073c115630..f44590e2144 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -15,6 +15,16 @@ class Note < ActiveRecord::Base
include IgnorableColumn
include Editable
+ module SpecialRole
+ FIRST_TIME_CONTRIBUTOR = :first_time_contributor
+
+ class << self
+ def values
+ constants.map {|const| self.const_get(const)}
+ end
+ end
+ end
+
ignore_column :original_discussion_id
cache_markdown_field :note, pipeline: :note, issuable_state_filter_enabled: true
@@ -32,9 +42,12 @@ class Note < ActiveRecord::Base
# Banzai::ObjectRenderer
attr_accessor :user_visible_reference_count
- # Attribute used to store the attributes that have ben changed by quick actions.
+ # Attribute used to store the attributes that have been changed by quick actions.
attr_accessor :commands_changes
+ # A special role that may be displayed on issuable's discussions
+ attr_accessor :special_role
+
default_value_for :system, false
attr_mentionable :note, pipeline: :note
@@ -141,6 +154,10 @@ class Note < ActiveRecord::Base
.group(:noteable_id)
.where(noteable_type: type, noteable_id: ids)
end
+
+ def has_special_role?(role, note)
+ note.special_role == role
+ end
end
def cross_reference?
@@ -206,6 +223,22 @@ class Note < ActiveRecord::Base
super(noteable_type.to_s.classify.constantize.base_class.to_s)
end
+ def special_role=(role)
+ raise "Role is undefined, #{role} not found in #{SpecialRole.values}" unless SpecialRole.values.include?(role)
+
+ @special_role = role
+ end
+
+ def has_special_role?(role)
+ self.class.has_special_role?(role, self)
+ end
+
+ def specialize_for_first_contribution!(noteable)
+ return unless noteable.author_id == self.author_id
+
+ self.special_role = Note::SpecialRole::FIRST_TIME_CONTRIBUTOR
+ end
+
def editable?
!system?
end
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index 674eacd28e8..09049824ff7 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -150,7 +150,7 @@ class ProjectTeam
end
def human_max_access(user_id)
- Gitlab::Access.options_with_owner.key(max_member_access(user_id))
+ Gitlab::Access.human_access(max_member_access(user_id))
end
# Determine the maximum access level for a group of users in bulk.
diff --git a/app/models/user.rb b/app/models/user.rb
index c5b5f09722f..105eb62f1fa 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -15,10 +15,12 @@ class User < ActiveRecord::Base
include IgnorableColumn
include FeatureGate
include CreatedAtFilterable
+ include IgnorableColumn
DEFAULT_NOTIFICATION_LEVEL = :participating
- ignore_column :authorized_projects_populated
+ ignore_column :external_email
+ ignore_column :email_provider
add_authentication_token_field :authentication_token
add_authentication_token_field :incoming_email_token
@@ -85,6 +87,7 @@ class User < ActiveRecord::Base
has_many :identities, dependent: :destroy, autosave: true # rubocop:disable Cop/ActiveRecordDependent
has_many :u2f_registrations, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :chat_names, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
+ has_one :user_synced_attributes_metadata, autosave: true
# Groups
has_many :members, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
@@ -161,6 +164,7 @@ class User < ActiveRecord::Base
after_update :update_emails_with_primary_email, if: :email_changed?
before_save :ensure_authentication_token, :ensure_incoming_email_token
before_save :ensure_user_rights_and_limits, if: :external_changed?
+ before_save :skip_reconfirmation!, if: ->(user) { user.email_changed? && user.read_only_attribute?(:email) }
after_save :ensure_namespace_correct
after_commit :update_invalid_gpg_signatures, on: :update, if: -> { previous_changes.key?('email') }
after_initialize :set_projects_limit
@@ -1045,6 +1049,22 @@ class User < ActiveRecord::Base
self.email == email
end
+ def sync_attribute?(attribute)
+ return true if ldap_user? && attribute == :email
+
+ attributes = Gitlab.config.omniauth.sync_profile_attributes
+
+ if attributes.is_a?(Array)
+ attributes.include?(attribute.to_s)
+ else
+ attributes
+ end
+ end
+
+ def read_only_attribute?(attribute)
+ user_synced_attributes_metadata&.read_only?(attribute)
+ end
+
protected
# override, from Devise::Validatable
diff --git a/app/models/user_synced_attributes_metadata.rb b/app/models/user_synced_attributes_metadata.rb
new file mode 100644
index 00000000000..9f374304164
--- /dev/null
+++ b/app/models/user_synced_attributes_metadata.rb
@@ -0,0 +1,25 @@
+class UserSyncedAttributesMetadata < ActiveRecord::Base
+ belongs_to :user
+
+ validates :user, presence: true
+
+ SYNCABLE_ATTRIBUTES = %i[name email location].freeze
+
+ def read_only?(attribute)
+ Gitlab.config.omniauth.sync_profile_from_provider && synced?(attribute)
+ end
+
+ def read_only_attributes
+ return [] unless Gitlab.config.omniauth.sync_profile_from_provider
+
+ SYNCABLE_ATTRIBUTES.select { |key| synced?(key) }
+ end
+
+ def synced?(attribute)
+ read_attribute("#{attribute}_synced")
+ end
+
+ def set_attribute_synced(attribute, value)
+ write_attribute("#{attribute}_synced", value)
+ end
+end
diff --git a/app/services/users/update_service.rb b/app/services/users/update_service.rb
index 2f9855273dc..6188b8a4349 100644
--- a/app/services/users/update_service.rb
+++ b/app/services/users/update_service.rb
@@ -34,6 +34,10 @@ module Users
private
def assign_attributes(&block)
+ if @user.user_synced_attributes_metadata
+ params.except!(*@user.user_synced_attributes_metadata.read_only_attributes)
+ end
+
@user.assign_attributes(params) if params.any?
end
end
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/ci/variables/_content.html.haml b/app/views/ci/variables/_content.html.haml
index 98f618ca3b8..fbfe3e56588 100644
--- a/app/views/ci/variables/_content.html.haml
+++ b/app/views/ci/variables/_content.html.haml
@@ -1,9 +1,3 @@
-%h4.prepend-top-0
- Secret variables
- = link_to icon('question-circle'), help_page_path('ci/variables/README', anchor: 'secret-variables'), target: '_blank'
-%p
- These variables will be set to environment by the runner, and could be protected by exposing only to protected branches or tags.
-%p
- So you can use them for passwords, secret keys or whatever you want.
-%p
- The value of the variable can be visible in job log if explicitly asked to do so.
+%p.append-bottom-default
+ Variables are applied to environments via the runner. They can be protected by only exposing them to protected branches or tags.
+ You can use variables for passwords, secret keys, or whatever you want.
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index 007c2344b5a..2bac69bc536 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -1,7 +1,5 @@
.row.prepend-top-default.append-bottom-default
- .col-lg-4
- = render "ci/variables/content"
- .col-lg-8
+ .col-lg-12
%h5.prepend-top-0
Add a variable
= render "ci/variables/form", btn_text: "Add new variable"
diff --git a/app/views/ci/variables/_show.html.haml b/app/views/ci/variables/_show.html.haml
index 2bfb290629d..6d75ae96124 100644
--- a/app/views/ci/variables/_show.html.haml
+++ b/app/views/ci/variables/_show.html.haml
@@ -4,6 +4,6 @@
.col-lg-3
= render "ci/variables/content"
.col-lg-9
- %h5.prepend-top-0
+ %h4.prepend-top-0
Update variable
= render "ci/variables/form", btn_text: "Save variable"
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/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 ff0f6489861..feffd7707dc 100644
--- a/app/views/layouts/nav/_breadcrumbs.html.haml
+++ b/app/views/layouts/nav/_breadcrumbs.html.haml
@@ -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
- - unless hide_top_links
- .title
- = link_to "GitLab", root_path
- \/
- - if content_for?(:header_title_before)
- = yield :header_title_before
- \/
+ %ul.list-unstyled.breadcrumbs-list.js-breadcrumbs-list
+ - unless hide_top_links
= 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
+ - 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= @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..28022eebb19
--- /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 * 16, 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/profiles/show.html.haml b/app/views/profiles/show.html.haml
index a8ae0b92334..35ad280b037 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'
@@ -45,12 +45,15 @@
Some options are unavailable for LDAP accounts
.col-lg-8
.row
- = f.text_field :name, required: true, wrapper: { class: 'col-md-9' },
- help: 'Enter your name, so people you know can recognize you.'
+ - if @user.read_only_attribute?(:name)
+ = f.text_field :name, required: true, readonly: true, wrapper: { class: 'col-md-9' },
+ help: "Your name was automatically set based on your #{ attribute_provider_label(:name) } account, so people you know can recognize you."
+ - else
+ = f.text_field :name, required: true, wrapper: { class: 'col-md-9' }, help: "Enter your name, so people you know can recognize you."
= f.text_field :id, readonly: true, label: 'User ID', wrapper: { class: 'col-md-3' }
- - if @user.external_email?
- = f.text_field :email, required: true, readonly: true, help: "Your email address was automatically set based on your #{email_provider_label} account."
+ - if @user.read_only_attribute?(:email)
+ = f.text_field :email, required: true, readonly: true, help: "Your email address was automatically set based on your #{ attribute_provider_label(:email) } account."
- else
= f.text_field :email, required: true, value: (@user.email unless @user.temp_oauth_email?),
help: user_email_help_text(@user)
@@ -64,7 +67,10 @@
= f.text_field :linkedin
= f.text_field :twitter
= f.text_field :website_url, label: 'Website'
- = f.text_field :location
+ - if @user.read_only_attribute?(:location)
+ = f.text_field :location, readonly: true, help: "Your location was automatically set based on your #{ attribute_provider_label(:location) } account."
+ - else
+ = f.text_field :location
= f.text_field :organization
= f.text_area :bio, rows: 4, maxlength: 250, help: 'Tell us about yourself in fewer than 250 characters.'
.prepend-top-default.append-bottom-default
diff --git a/app/views/projects/activity.html.haml b/app/views/projects/activity.html.haml
index 2897c955c78..f80dadb8037 100644
--- a/app/views/projects/activity.html.haml
+++ b/app/views/projects/activity.html.haml
@@ -1,7 +1,7 @@
- @no_container = true
-- add_to_breadcrumbs(_("Project"), project_path(@project))
- page_title _("Activity")
+
= render "projects/head"
= render 'projects/last_push'
diff --git a/app/views/projects/artifacts/browse.html.haml b/app/views/projects/artifacts/browse.html.haml
index a33743c2f57..4cc3218d967 100644
--- a/app/views/projects/artifacts/browse.html.haml
+++ b/app/views/projects/artifacts/browse.html.haml
@@ -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
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index c7359d873d9..60ac202bde0 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -22,7 +22,7 @@
= author_avatar(commit, size: 36)
.commit-row-title
%span.item-title.str-truncated-100
- = link_to_gfm commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
+ = link_to_markdown commit.title, project_commit_path(@project, commit.id), class: "cdark", title: commit.title
.pull-right
= link_to commit.short_id, project_commit_path(@project, commit), class: "commit-sha"
&nbsp;
diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml
index 67d9db9aefe..303e20e8780 100644
--- a/app/views/projects/boards/_show.html.haml
+++ b/app/views/projects/boards/_show.html.haml
@@ -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'
diff --git a/app/views/projects/branches/_commit.html.haml b/app/views/projects/branches/_commit.html.haml
index 18fbb81c167..7892019bb15 100644
--- a/app/views/projects/branches/_commit.html.haml
+++ b/app/views/projects/branches/_commit.html.haml
@@ -4,6 +4,6 @@
= link_to commit.short_id, project_commit_path(project, commit.id), class: "commit-sha"
&middot;
%span.str-truncated
- = link_to_gfm commit.title, project_commit_path(project, commit.id), class: "commit-row-message"
+ = link_to_markdown commit.title, project_commit_path(project, commit.id), class: "commit-row-message"
&middot;
#{time_ago_with_tooltip(commit.committed_date)}
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index b1834de0bad..73583c6bbc2 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -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 }
diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml
index 07c83c0a590..717de85c5d2 100644
--- a/app/views/projects/commit/show.html.haml
+++ b/app/views/projects/commit/show.html.haml
@@ -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
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 1214aabe837..b8655808d89 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -16,7 +16,7 @@
.commit-detail
.commit-content
- = link_to_gfm commit.title, project_commit_path(project, commit.id), class: "commit-row-message item-title"
+ = link_to_markdown_field(commit, :title, project_commit_path(project, commit.id), class: "commit-row-message item-title")
%span.commit-row-message.visible-xs-inline
&middot;
= commit.short_id
@@ -28,7 +28,8 @@
- if commit.description?
%pre.commit-row-description.js-toggle-content
- = preserve(markdown(commit.description, pipeline: :single_line, author: commit.author))
+ = preserve(markdown_field(commit, :description))
+
.commiter
- commit_author_link = commit_author_link(commit, avatar: false, size: 24)
- commit_timeago = time_ago_with_tooltip(commit.committed_date)
diff --git a/app/views/projects/commits/_inline_commit.html.haml b/app/views/projects/commits/_inline_commit.html.haml
index 48cefbe45f2..26385d2f534 100644
--- a/app/views/projects/commits/_inline_commit.html.haml
+++ b/app/views/projects/commits/_inline_commit.html.haml
@@ -3,6 +3,6 @@
= link_to commit.short_id, project_commit_path(project, commit), class: "commit-sha"
&nbsp;
%span.str-truncated
- = link_to_gfm commit.title, project_commit_path(project, commit.id), class: "commit-row-message"
+ = link_to_markdown_field(commit, :title, project_commit_path(project, commit.id), class: "commit-row-message")
.pull-right
#{time_ago_with_tooltip(commit.committed_date)}
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index 0f048079ef5..e873b931683 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -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"
diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml
index ecef91855af..2632fea6eba 100644
--- a/app/views/projects/compare/index.html.haml
+++ b/app/views/projects/compare/index.html.haml
@@ -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 }
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index eca733a933a..7cc42455394 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -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 }
diff --git a/app/views/projects/cycle_analytics/show.html.haml b/app/views/projects/cycle_analytics/show.html.haml
index 5691024b997..8d008be5aae 100644
--- a/app/views/projects/cycle_analytics/show.html.haml
+++ b/app/views/projects/cycle_analytics/show.html.haml
@@ -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')
diff --git a/app/views/projects/deployments/_commit.html.haml b/app/views/projects/deployments/_commit.html.haml
index 4c22166c256..014486be868 100644
--- a/app/views/projects/deployments/_commit.html.haml
+++ b/app/views/projects/deployments/_commit.html.haml
@@ -12,6 +12,6 @@
%span.flex-truncate-child
- if commit_title = deployment.commit_title
= author_avatar(deployment.commit, size: 20)
- = link_to_gfm commit_title, project_commit_path(@project, deployment.sha), class: "commit-row-message"
+ = link_to_markdown commit_title, project_commit_path(@project, deployment.sha), class: "commit-row-message"
- else
Cant find HEAD commit for this branch
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 9e26bdecd31..994119051d2 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/show.html.haml b/app/views/projects/environments/show.html.haml
index 0ce0f5465fc..c35d1b5aaee 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -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"
diff --git a/app/views/projects/graphs/charts.html.haml b/app/views/projects/graphs/charts.html.haml
index 44bd8d1f9ad..f0ef647ddb3 100644
--- a/app/views/projects/graphs/charts.html.haml
+++ b/app/views/projects/graphs/charts.html.haml
@@ -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')
diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml
index 2f60078796e..08b38428b50 100644
--- a/app/views/projects/graphs/show.html.haml
+++ b/app/views/projects/graphs/show.html.haml
@@ -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) }
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 04b4ed95a2d..fbaf88356bf 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -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
diff --git a/app/views/projects/jobs/index.html.haml b/app/views/projects/jobs/index.html.haml
index 9751de0f938..8604c7d3ea4 100644
--- a/app/views/projects/jobs/index.html.haml
+++ b/app/views/projects/jobs/index.html.haml
@@ -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) }
diff --git a/app/views/projects/jobs/show.html.haml b/app/views/projects/jobs/show.html.haml
index fa086413fbe..975c08c06e6 100644
--- a/app/views/projects/jobs/show.html.haml
+++ b/app/views/projects/jobs/show.html.haml
@@ -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"
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index d27e121beb4..c2d16f7e731 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -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
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 0bf0e11c107..1f5f18801ad 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -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"
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index 2defd45a0b2..e29cb277389 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -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 }
diff --git a/app/views/projects/notes/_actions.html.haml b/app/views/projects/notes/_actions.html.haml
index fb07141d2ac..de76832331a 100644
--- a/app/views/projects/notes/_actions.html.haml
+++ b/app/views/projects/notes/_actions.html.haml
@@ -1,6 +1,8 @@
-- access = note_max_access_for_user(note)
-- if access
- %span.note-role= access
+- if note.has_special_role?(Note::SpecialRole::FIRST_TIME_CONTRIBUTOR)
+ %span.note-role.note-role-special.has-tooltip{ title: _("This is the author's first Merge Request to this project. Handle with care.") }
+ = issuable_first_contribution_icon
+- if access = note_max_access_for_user(note)
+ %span.note-role.note-role-access= Gitlab::Access.human_access(access)
- if note.resolvable?
- can_resolve = can?(current_user, :resolve_note, note)
diff --git a/app/views/projects/notes/_more_actions_dropdown.html.haml b/app/views/projects/notes/_more_actions_dropdown.html.haml
index 7e854186973..88085c7185b 100644
--- a/app/views/projects/notes/_more_actions_dropdown.html.haml
+++ b/app/views/projects/notes/_more_actions_dropdown.html.haml
@@ -7,7 +7,7 @@
= custom_icon('ellipsis_v')
%ul.dropdown-menu.more-actions-dropdown.dropdown-open-left
%li
- = clipboard_button(text: noteable_note_url(note), title: "Copy reference to clipboard", button_text: 'Copy link', hide_tooltip: true, hide_button_icon: true)
+ = clipboard_button(text: noteable_note_url(note), title: 'Copy reference to clipboard', button_text: 'Copy link', class: 'btn-clipboard', hide_tooltip: true, hide_button_icon: true)
- unless is_current_user
%li
= link_to new_abuse_report_path(user_id: note.author.id, ref_url: noteable_note_url(note)) do
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 83b51bae73d..d9957b54a4d 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'
@@ -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 }
diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml
index d710ba92cdd..487ac87186d 100644
--- a/app/views/projects/pipelines/charts.html.haml
+++ b/app/views/projects/pipelines/charts.html.haml
@@ -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')
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index 63f85fc69a2..7cc9fe79afd 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -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"
diff --git a/app/views/projects/pipelines_settings/_badge.html.haml b/app/views/projects/pipelines_settings/_badge.html.haml
index 3de518c8b9a..e8028059487 100644
--- a/app/views/projects/pipelines_settings/_badge.html.haml
+++ b/app/views/projects/pipelines_settings/_badge.html.haml
@@ -1,34 +1,32 @@
%div{ class: badge.title.gsub(' ', '-') }
- .col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
+ .col-lg-12
+ %h4
= badge.title.capitalize
- .col-lg-8
- .prepend-top-10
- .panel.panel-default
- .panel-heading
- %b
- = badge.title.capitalize
- &middot;
- = badge.to_html
- .pull-right
- = render 'shared/ref_switcher', destination: 'badges', align_right: true
- .panel-body
- .row
- .col-md-2.text-center
- Markdown
- .col-md-10.code.js-syntax-highlight
- = highlight('.md', badge.to_markdown)
- .row
- %hr
- .row
- .col-md-2.text-center
- HTML
- .col-md-10.code.js-syntax-highlight
- = highlight('.html', badge.to_html)
- .row
- %hr
- .row
- .col-md-2.text-center
- AsciiDoc
- .col-md-10.code.js-syntax-highlight
- = highlight('.adoc', badge.to_asciidoc)
+ .panel.panel-default
+ .panel-heading
+ %b
+ = badge.title.capitalize
+ &middot;
+ = badge.to_html
+ .pull-right
+ = render 'shared/ref_switcher', destination: 'badges', align_right: true
+ .panel-body
+ .row
+ .col-md-2.text-center
+ Markdown
+ .col-md-10.code.js-syntax-highlight
+ = highlight('.md', badge.to_markdown)
+ .row
+ %hr
+ .row
+ .col-md-2.text-center
+ HTML
+ .col-md-10.code.js-syntax-highlight
+ = highlight('.html', badge.to_html)
+ .row
+ %hr
+ .row
+ .col-md-2.text-center
+ AsciiDoc
+ .col-md-10.code.js-syntax-highlight
+ = highlight('.adoc', badge.to_asciidoc)
diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml
index c0a368dc475..324cd423ede 100644
--- a/app/views/projects/pipelines_settings/_show.html.haml
+++ b/app/views/projects/pipelines_settings/_show.html.haml
@@ -1,8 +1,5 @@
.row.prepend-top-default
- .col-lg-4.profile-settings-sidebar
- %h4.prepend-top-0
- Pipelines
- .col-lg-8
+ .col-lg-12
= form_for @project, url: project_pipelines_settings_path(@project) do |f|
%fieldset.builds-feature
.form-group
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index 5c3339cc749..25153fd0b6f 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -1,7 +1,5 @@
- page_title "Members"
-- add_to_breadcrumbs("Settings", edit_project_path(@project))
-
.row.prepend-top-default
.col-lg-12
%h4
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/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml
index 2a829cd6c3d..eaf374bcb83 100644
--- a/app/views/projects/settings/ci_cd/show.html.haml
+++ b/app/views/projects/settings/ci_cd/show.html.haml
@@ -1,10 +1,54 @@
- @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"
-= render 'projects/runners/index'
-= render 'ci/variables/index'
-= render 'projects/triggers/index'
-= render 'projects/pipelines_settings/show'
+- expanded = Rails.env.test?
+
+%section.settings
+ .settings-header
+ %h4
+ General pipelines settings
+ %button.btn.js-settings-toggle
+ = expanded ? 'Collapse' : 'Expand'
+ %p
+ Update your CI/CD configuration, like job timeout.
+ .settings-content.no-animate{ class: ('expanded' if expanded) }
+ = render 'projects/pipelines_settings/show'
+
+%section.settings
+ .settings-header
+ %h4
+ Runners settings
+ %button.btn.js-settings-toggle
+ = expanded ? 'Collapse' : 'Expand'
+ %p
+ Register and see your runners for this project.
+ .settings-content.no-animate{ class: ('expanded' if expanded) }
+ = render 'projects/runners/index'
+
+%section.settings
+ .settings-header
+ %h4
+ Secret variables
+ = link_to icon('question-circle'), help_page_path('ci/variables/README', anchor: 'secret-variables'), target: '_blank'
+ %button.btn.js-settings-toggle
+ = expanded ? 'Collapse' : 'Expand'
+ %p
+ = render "ci/variables/content"
+ .settings-content.no-animate{ class: ('expanded' if expanded) }
+ = render 'ci/variables/index'
+
+%section.settings
+ .settings-header
+ %h4
+ Pipeline triggers
+ %button.btn.js-settings-toggle
+ = expanded ? 'Collapse' : 'Expand'
+ %p
+ Triggers can force a specific branch or tag to get rebuilt with an API call. These tokens will
+ impersonate their associated user including their access to projects and their project
+ permissions.
+ .settings-content.no-animate{ class: ('expanded' if expanded) }
+ = render 'projects/triggers/index'
diff --git a/app/views/projects/settings/integrations/show.html.haml b/app/views/projects/settings/integrations/show.html.haml
index 1efa5907b3a..933daa7f549 100644
--- a/app/views/projects/settings/integrations/show.html.haml
+++ b/app/views/projects/settings/integrations/show.html.haml
@@ -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'
diff --git a/app/views/projects/settings/repository/show.html.haml b/app/views/projects/settings/repository/show.html.haml
index d4d461f6f22..6d4af72b8ea 100644
--- a/app/views/projects/settings/repository/show.html.haml
+++ b/app/views/projects/settings/repository/show.html.haml
@@ -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"
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/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
diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml
index d8e448dd2af..fda068f08c2 100644
--- a/app/views/projects/snippets/show.html.haml
+++ b/app/views/projects/snippets/show.html.haml
@@ -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'
diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml
index d02cd70f4c3..5d6eb4f4026 100644
--- a/app/views/projects/tags/show.html.haml
+++ b/app/views/projects/tags/show.html.haml
@@ -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"
diff --git a/app/views/projects/tree/_tree_commit_column.html.haml b/app/views/projects/tree/_tree_commit_column.html.haml
index f3d4706809f..abb3e918e87 100644
--- a/app/views/projects/tree/_tree_commit_column.html.haml
+++ b/app/views/projects/tree/_tree_commit_column.html.haml
@@ -1,2 +1,2 @@
%span.str-truncated
- = link_to_gfm commit.full_title, project_commit_path(@project, commit.id), class: "tree-commit-link"
+ = link_to_markdown commit.full_title, project_commit_path(@project, commit.id), class: "tree-commit-link"
diff --git a/app/views/projects/triggers/_content.html.haml b/app/views/projects/triggers/_content.html.haml
index ea32eac2ae2..6c2d603d95d 100644
--- a/app/views/projects/triggers/_content.html.haml
+++ b/app/views/projects/triggers/_content.html.haml
@@ -1,14 +1,8 @@
-%h4.prepend-top-0
- Triggers
-%p.prepend-top-20
- Triggers can force a specific branch or tag to get rebuilt with an API call. These tokens will
- impersonate their associated user including their access to projects and their project
- permissions.
-%p.prepend-top-20
+%p.append-bottom-default
Triggers with the
%span.label.label-primary legacy
label do not have an associated user and only have access to the current project.
-%p.append-bottom-0
+ %br
= succeed '.' do
Learn more in the
= link_to 'triggers documentation', help_page_path('ci/triggers/README'), target: '_blank'
diff --git a/app/views/projects/triggers/_index.html.haml b/app/views/projects/triggers/_index.html.haml
index e9a2f803edd..0f655e4ed83 100644
--- a/app/views/projects/triggers/_index.html.haml
+++ b/app/views/projects/triggers/_index.html.haml
@@ -1,7 +1,6 @@
.row.prepend-top-default.append-bottom-default.triggers-container
- .col-lg-4
+ .col-lg-12
= render "projects/triggers/content"
- .col-lg-8
.panel.panel-default
.panel-heading
%h4.panel-title
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 }
diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml
index 9dadd685ea2..b066a812ec8 100644
--- a/app/views/projects/wikis/show.html.haml
+++ b/app/views/projects/wikis/show.html.haml
@@ -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
diff --git a/app/views/shared/notes/_note.html.haml b/app/views/shared/notes/_note.html.haml
index 7174855e176..4f00a9f2759 100644
--- a/app/views/shared/notes/_note.html.haml
+++ b/app/views/shared/notes/_note.html.haml
@@ -28,7 +28,7 @@
commented
- if note.system
%span.system-note-message
- = note.redacted_note_html
+ = markdown_field(note, :note)
%a{ href: "##{dom_id(note)}" }
= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
- unless note.system?
@@ -39,7 +39,7 @@
= render 'projects/notes/actions', note: note, note_editable: note_editable
.note-body{ class: note_editable ? 'js-task-list-container' : '' }
.note-text.md
- = note.redacted_note_html
+ = markdown_field(note, :note)
= edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago')
.original-note-content.hidden{ data: { post_url: note_url(note), target_id: note.noteable.id, target_type: note.noteable.class.name.underscore } }
#{note.note}
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index f4f155c8d94..52a8fe8bb67 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -31,8 +31,7 @@
- if show_last_commit_as_description
.description.prepend-top-5
- = link_to_gfm project.commit.title, project_commit_path(project, project.commit),
- class: "commit-row-message"
+ = link_to_markdown(project.commit.title, project_commit_path(project, project.commit), class: "commit-row-message")
- elsif project.description.present?
.description.prepend-top-5
= markdown_field(project, :description)
diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml
index 17b34c5eeb3..119d189f21d 100644
--- a/app/views/shared/snippets/_header.html.haml
+++ b/app/views/shared/snippets/_header.html.haml
@@ -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")}
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'