Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/images/mailers/gitlab_header_logo.pngbin0 -> 7096 bytes
-rw-r--r--app/assets/images/mailers/gitlab_tanuki_2x.pngbin0 -> 2545 bytes
-rw-r--r--app/assets/javascripts/application.js.coffee42
-rw-r--r--app/assets/javascripts/calendar.js.coffee34
-rw-r--r--app/assets/javascripts/ci/build.coffee7
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee1
-rw-r--r--app/assets/javascripts/graphs/application.js.coffee7
-rw-r--r--app/assets/javascripts/graphs/stat_graph.js.coffee (renamed from app/assets/javascripts/stat_graph.js.coffee)0
-rw-r--r--app/assets/javascripts/graphs/stat_graph_contributors.js.coffee (renamed from app/assets/javascripts/stat_graph_contributors.js.coffee)1
-rw-r--r--app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee (renamed from app/assets/javascripts/stat_graph_contributors_graph.js.coffee)2
-rw-r--r--app/assets/javascripts/graphs/stat_graph_contributors_util.js.coffee (renamed from app/assets/javascripts/stat_graph_contributors_util.js.coffee)0
-rw-r--r--app/assets/javascripts/issuable.js.coffee48
-rw-r--r--app/assets/javascripts/issuable_form.js.coffee17
-rw-r--r--app/assets/javascripts/issues.js.coffee38
-rw-r--r--app/assets/javascripts/layout_nav.js.coffee14
-rw-r--r--app/assets/javascripts/lib/url_utility.js.coffee11
-rw-r--r--app/assets/javascripts/merge_request_tabs.js.coffee3
-rw-r--r--app/assets/javascripts/merge_request_widget.js.coffee13
-rw-r--r--app/assets/javascripts/notes.js.coffee10
-rw-r--r--app/assets/javascripts/right_sidebar.js.coffee36
-rw-r--r--app/assets/javascripts/users/application.js.coffee8
-rw-r--r--app/assets/javascripts/users/calendar.js.coffee198
-rw-r--r--app/assets/javascripts/users_select.js.coffee12
-rw-r--r--app/assets/stylesheets/application.scss1
-rw-r--r--app/assets/stylesheets/framework/buttons.scss18
-rw-r--r--app/assets/stylesheets/framework/calendar.scss72
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss6
-rw-r--r--app/assets/stylesheets/framework/files.scss15
-rw-r--r--app/assets/stylesheets/framework/nav.scss114
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss2
-rw-r--r--app/assets/stylesheets/framework/variables.scss5
-rw-r--r--app/assets/stylesheets/mailers/devise.scss134
-rw-r--r--app/assets/stylesheets/pages/commit.scss24
-rw-r--r--app/assets/stylesheets/pages/issues.scss10
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss31
-rw-r--r--app/assets/stylesheets/pages/pipelines.scss26
-rw-r--r--app/assets/stylesheets/pages/profile.scss14
-rw-r--r--app/assets/stylesheets/pages/projects.scss2
-rw-r--r--app/assets/stylesheets/pages/settings.scss8
-rw-r--r--app/assets/stylesheets/pages/snippets.scss44
-rw-r--r--app/assets/stylesheets/pages/todos.scss14
-rw-r--r--app/assets/stylesheets/pages/tree.scss13
-rw-r--r--app/controllers/admin/application_settings_controller.rb1
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/autocomplete_controller.rb18
-rw-r--r--app/controllers/jwt_controller.rb2
-rw-r--r--app/controllers/omniauth_callbacks_controller.rb2
-rw-r--r--app/controllers/projects/application_controller.rb2
-rw-r--r--app/controllers/projects/find_file_controller.rb52
-rw-r--r--app/controllers/projects/hooks_controller.rb3
-rw-r--r--app/controllers/projects/merge_requests_controller.rb6
-rw-r--r--app/controllers/projects/wikis_controller.rb4
-rw-r--r--app/controllers/projects_controller.rb4
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/controllers/users_controller.rb2
-rw-r--r--app/finders/group_projects_finder.rb2
-rw-r--r--app/finders/issuable_finder.rb8
-rw-r--r--app/helpers/application_helper.rb17
-rw-r--r--app/helpers/button_helper.rb2
-rw-r--r--app/helpers/commits_helper.rb19
-rw-r--r--app/helpers/diff_helper.rb4
-rw-r--r--app/helpers/events_helper.rb22
-rw-r--r--app/helpers/groups_helper.rb2
-rw-r--r--app/helpers/issuables_helper.rb10
-rw-r--r--app/helpers/issues_helper.rb21
-rw-r--r--app/helpers/javascript_helper.rb7
-rw-r--r--app/helpers/nav_helper.rb4
-rw-r--r--app/helpers/todos_helper.rb16
-rw-r--r--app/mailers/devise_mailer.rb2
-rw-r--r--app/models/ability.rb35
-rw-r--r--app/models/application_setting.rb11
-rw-r--r--app/models/ci/build.rb2
-rw-r--r--app/models/ci/commit.rb4
-rw-r--r--app/models/ci/runner.rb2
-rw-r--r--app/models/ci/variable.rb5
-rw-r--r--app/models/commit.rb23
-rw-r--r--app/models/commit_range.rb2
-rw-r--r--app/models/concerns/issuable.rb39
-rw-r--r--app/models/concerns/mentionable.rb19
-rw-r--r--app/models/concerns/participable.rb94
-rw-r--r--app/models/issue.rb23
-rw-r--r--app/models/key.rb2
-rw-r--r--app/models/members/project_member.rb7
-rw-r--r--app/models/network/graph.rb33
-rw-r--r--app/models/note.rb35
-rw-r--r--app/models/project.rb22
-rw-r--r--app/models/project_import_data.rb3
-rw-r--r--app/models/project_services/irker_service.rb2
-rw-r--r--app/models/project_services/slack_service/build_message.rb4
-rw-r--r--app/models/project_snippet.rb3
-rw-r--r--app/models/project_wiki.rb14
-rw-r--r--app/models/repository.rb6
-rw-r--r--app/models/snippet.rb7
-rw-r--r--app/models/user.rb7
-rw-r--r--app/services/auth/container_registry_authentication_service.rb12
-rw-r--r--app/services/git_push_service.rb17
-rw-r--r--app/services/git_tag_push_service.rb2
-rw-r--r--app/services/notes/create_service.rb11
-rw-r--r--app/services/projects/fork_service.rb14
-rw-r--r--app/services/projects/housekeeping_service.rb2
-rw-r--r--app/services/wiki_pages/base_service.rb5
-rw-r--r--app/views/admin/abuse_reports/_abuse_report.html.haml2
-rw-r--r--app/views/admin/application_settings/_form.html.haml8
-rw-r--r--app/views/admin/builds/index.html.haml1
-rw-r--r--app/views/dashboard/issues.atom.builder5
-rw-r--r--app/views/dashboard/projects/index.atom.builder4
-rw-r--r--app/views/dashboard/todos/_todo.html.haml2
-rw-r--r--app/views/devise/mailer/confirmation_instructions.html.erb9
-rw-r--r--app/views/devise/mailer/confirmation_instructions.html.haml16
-rw-r--r--app/views/devise/mailer/confirmation_instructions.text.erb9
-rw-r--r--app/views/devise/sessions/two_factor.html.haml1
-rw-r--r--app/views/doorkeeper/authorizations/new.html.haml2
-rw-r--r--app/views/events/_commit.html.haml2
-rw-r--r--app/views/events/_event.atom.builder20
-rw-r--r--app/views/events/_event_issue.atom.haml2
-rw-r--r--app/views/events/_event_merge_request.atom.haml2
-rw-r--r--app/views/events/_event_note.atom.haml2
-rw-r--r--app/views/events/_event_push.atom.haml2
-rw-r--r--app/views/events/event/_common.html.haml2
-rw-r--r--app/views/events/event/_push.html.haml2
-rw-r--r--app/views/groups/issues.atom.builder5
-rw-r--r--app/views/groups/show.atom.builder4
-rw-r--r--app/views/import/gitlab/status.html.haml2
-rw-r--r--app/views/issues/_issue.atom.builder14
-rw-r--r--app/views/kaminari/gitlab/_first_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_gap.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_last_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_next_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_page.html.haml2
-rw-r--r--app/views/kaminari/gitlab/_paginator.html.haml6
-rw-r--r--app/views/kaminari/gitlab/_prev_page.html.haml2
-rw-r--r--app/views/layouts/_head.html.haml3
-rw-r--r--app/views/layouts/_page.html.haml2
-rw-r--r--app/views/layouts/devise_mailer.html.haml34
-rw-r--r--app/views/layouts/nav/_group.html.haml75
-rw-r--r--app/views/layouts/nav/_profile.html.haml4
-rw-r--r--app/views/layouts/nav/_project.html.haml191
-rw-r--r--app/views/notify/_note_message.html.haml2
-rw-r--r--app/views/notify/new_issue_email.html.haml2
-rw-r--r--app/views/notify/new_merge_request_email.html.haml2
-rw-r--r--app/views/profiles/accounts/show.html.haml4
-rw-r--r--app/views/profiles/preferences/show.html.haml2
-rw-r--r--app/views/projects/_builds_settings.html.haml119
-rw-r--r--app/views/projects/activity.html.haml1
-rw-r--r--app/views/projects/artifacts/browse.html.haml1
-rw-r--r--app/views/projects/badges/index.html.haml1
-rw-r--r--app/views/projects/blame/show.html.haml1
-rw-r--r--app/views/projects/blob/_header_title.html.haml1
-rw-r--r--app/views/projects/blob/edit.html.haml1
-rw-r--r--app/views/projects/blob/new.html.haml1
-rw-r--r--app/views/projects/blob/show.html.haml1
-rw-r--r--app/views/projects/branches/index.html.haml1
-rw-r--r--app/views/projects/branches/new.html.haml1
-rw-r--r--app/views/projects/builds/_header_title.html.haml1
-rw-r--r--app/views/projects/builds/index.html.haml5
-rw-r--r--app/views/projects/builds/show.html.haml1
-rw-r--r--app/views/projects/ci/builds/_build.html.haml4
-rw-r--r--app/views/projects/ci/commits/_commit.html.haml40
-rw-r--r--app/views/projects/commit/_ci_commit.html.haml16
-rw-r--r--app/views/projects/commit/_ci_stage.html.haml1
-rw-r--r--app/views/projects/commit/_commit_box.html.haml60
-rw-r--r--app/views/projects/commit/builds.html.haml4
-rw-r--r--app/views/projects/commit/show.html.haml2
-rw-r--r--app/views/projects/commits/_commit.atom.builder14
-rw-r--r--app/views/projects/commits/_commit.html.haml2
-rw-r--r--app/views/projects/commits/_header_title.html.haml1
-rw-r--r--app/views/projects/commits/show.atom.builder15
-rw-r--r--app/views/projects/commits/show.html.haml1
-rw-r--r--app/views/projects/compare/index.html.haml1
-rw-r--r--app/views/projects/compare/show.html.haml1
-rw-r--r--app/views/projects/container_registry/_header_title.html.haml1
-rw-r--r--app/views/projects/container_registry/index.html.haml3
-rw-r--r--app/views/projects/edit.html.haml455
-rw-r--r--app/views/projects/find_file/show.html.haml1
-rw-r--r--app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml18
-rw-r--r--app/views/projects/graphs/_head.html.haml1
-rw-r--r--app/views/projects/graphs/_header_title.html.haml1
-rw-r--r--app/views/projects/graphs/ci.html.haml1
-rw-r--r--app/views/projects/graphs/commits.html.haml1
-rw-r--r--app/views/projects/graphs/languages.html.haml1
-rw-r--r--app/views/projects/graphs/show.html.haml3
-rw-r--r--app/views/projects/hooks/_project_hook.html.haml2
-rw-r--r--app/views/projects/hooks/index.html.haml7
-rw-r--r--app/views/projects/issues/_header_title.html.haml1
-rw-r--r--app/views/projects/issues/_issue.html.haml2
-rw-r--r--app/views/projects/issues/_merge_requests.html.haml5
-rw-r--r--app/views/projects/issues/edit.html.haml1
-rw-r--r--app/views/projects/issues/index.atom.builder4
-rw-r--r--app/views/projects/issues/index.html.haml1
-rw-r--r--app/views/projects/issues/new.html.haml1
-rw-r--r--app/views/projects/issues/show.html.haml5
-rw-r--r--app/views/projects/labels/_header_title.html.haml1
-rw-r--r--app/views/projects/labels/edit.html.haml1
-rw-r--r--app/views/projects/labels/index.html.haml3
-rw-r--r--app/views/projects/labels/new.html.haml1
-rw-r--r--app/views/projects/merge_requests/_header_title.html.haml1
-rw-r--r--app/views/projects/merge_requests/_merge_request.html.haml2
-rw-r--r--app/views/projects/merge_requests/_show.html.haml1
-rw-r--r--app/views/projects/merge_requests/dropdowns/_branch.html.haml2
-rw-r--r--app/views/projects/merge_requests/edit.html.haml1
-rw-r--r--app/views/projects/merge_requests/index.html.haml1
-rw-r--r--app/views/projects/merge_requests/invalid.html.haml1
-rw-r--r--app/views/projects/merge_requests/new.html.haml1
-rw-r--r--app/views/projects/merge_requests/show/_mr_box.html.haml4
-rw-r--r--app/views/projects/merge_requests/widget/_open.html.haml2
-rw-r--r--app/views/projects/merge_requests/widget/_show.html.haml8
-rw-r--r--app/views/projects/milestones/_header_title.html.haml1
-rw-r--r--app/views/projects/milestones/edit.html.haml1
-rw-r--r--app/views/projects/milestones/index.html.haml2
-rw-r--r--app/views/projects/milestones/new.html.haml1
-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/new.html.haml2
-rw-r--r--app/views/projects/notes/_note.html.haml2
-rw-r--r--app/views/projects/pipelines/_head.html.haml14
-rw-r--r--app/views/projects/pipelines/_header_title.html.haml1
-rw-r--r--app/views/projects/pipelines/index.html.haml18
-rw-r--r--app/views/projects/pipelines/new.html.haml1
-rw-r--r--app/views/projects/pipelines/show.html.haml1
-rw-r--r--app/views/projects/project_members/_header_title.html.haml1
-rw-r--r--app/views/projects/project_members/import.html.haml1
-rw-r--r--app/views/projects/project_members/index.html.haml1
-rw-r--r--app/views/projects/releases/edit.html.haml1
-rw-r--r--app/views/projects/repositories/_feed.html.haml2
-rw-r--r--app/views/projects/runners/_specific_runners.html.haml2
-rw-r--r--app/views/projects/services/_form.html.haml32
-rw-r--r--app/views/projects/services/index.html.haml52
-rw-r--r--app/views/projects/show.atom.builder4
-rw-r--r--app/views/projects/snippets/_actions.html.haml38
-rw-r--r--app/views/projects/snippets/_header_title.html.haml1
-rw-r--r--app/views/projects/snippets/edit.html.haml1
-rw-r--r--app/views/projects/snippets/index.html.haml1
-rw-r--r--app/views/projects/snippets/new.html.haml1
-rw-r--r--app/views/projects/snippets/show.html.haml9
-rw-r--r--app/views/projects/tags/index.html.haml1
-rw-r--r--app/views/projects/tags/new.html.haml1
-rw-r--r--app/views/projects/tags/show.html.haml1
-rw-r--r--app/views/projects/tree/show.html.haml1
-rw-r--r--app/views/projects/triggers/index.html.haml20
-rw-r--r--app/views/projects/wikis/_header_title.html.haml1
-rw-r--r--app/views/projects/wikis/edit.html.haml1
-rw-r--r--app/views/projects/wikis/empty.html.haml1
-rw-r--r--app/views/projects/wikis/git_access.html.haml1
-rw-r--r--app/views/projects/wikis/history.html.haml1
-rw-r--r--app/views/projects/wikis/pages.html.haml1
-rw-r--r--app/views/projects/wikis/show.html.haml1
-rw-r--r--app/views/search/results/_issue.html.haml2
-rw-r--r--app/views/search/results/_merge_request.html.haml2
-rw-r--r--app/views/search/results/_note.html.haml2
-rw-r--r--app/views/shared/_event_filter.html.haml4
-rw-r--r--app/views/shared/_sort_dropdown.html.haml2
-rw-r--r--app/views/shared/issuable/_filter.html.haml6
-rw-r--r--app/views/shared/issuable/_form.html.haml4
-rw-r--r--app/views/shared/issuable/_search_form.html.haml6
-rw-r--r--app/views/shared/projects/_project.html.haml3
-rw-r--r--app/views/shared/snippets/_header.html.haml23
-rw-r--r--app/views/snippets/_actions.html.haml38
-rw-r--r--app/views/snippets/show.html.haml7
-rw-r--r--app/views/users/calendar.html.haml19
-rw-r--r--app/views/users/calendar_activities.html.haml42
-rw-r--r--app/views/users/show.atom.builder4
-rw-r--r--app/views/users/show.html.haml8
-rw-r--r--app/workers/emails_on_push_worker.rb1
263 files changed, 2063 insertions, 1395 deletions
diff --git a/app/assets/images/mailers/gitlab_header_logo.png b/app/assets/images/mailers/gitlab_header_logo.png
new file mode 100644
index 00000000000..35ca1860887
--- /dev/null
+++ b/app/assets/images/mailers/gitlab_header_logo.png
Binary files differ
diff --git a/app/assets/images/mailers/gitlab_tanuki_2x.png b/app/assets/images/mailers/gitlab_tanuki_2x.png
new file mode 100644
index 00000000000..551dd6ce2ce
--- /dev/null
+++ b/app/assets/images/mailers/gitlab_tanuki_2x.png
Binary files differ
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index bffce5a0c0f..18c1aa0d4e2 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -18,8 +18,6 @@
#= require jquery.atwho
#= require jquery.scrollTo
#= require jquery.turbolinks
-#= require d3
-#= require cal-heatmap
#= require turbolinks
#= require autosave
#= require bootstrap/affix
@@ -52,7 +50,13 @@
#= require shortcuts_network
#= require jquery.nicescroll
#= require date.format
-#= require_tree .
+#= require_directory ./behaviors
+#= require_directory ./blob
+#= require_directory ./ci
+#= require_directory ./commit
+#= require_directory ./extensions
+#= require_directory ./lib
+#= require_directory .
#= require fuzzaldrin-plus
#= require cropper
@@ -246,38 +250,6 @@ $ ->
if $navIcon.hasClass('fa-angle-left')
$navIconToggle.trigger('click')
- $(document)
- .off 'click', '.js-sidebar-toggle'
- .on 'click', '.js-sidebar-toggle', (e, triggered) ->
- e.preventDefault()
- $this = $(this)
- $thisIcon = $this.find 'i'
- $allGutterToggleIcons = $('.js-sidebar-toggle i')
- if $thisIcon.hasClass('fa-angle-double-right')
- $allGutterToggleIcons
- .removeClass('fa-angle-double-right')
- .addClass('fa-angle-double-left')
- $('aside.right-sidebar')
- .removeClass('right-sidebar-expanded')
- .addClass('right-sidebar-collapsed')
- $('.page-with-sidebar')
- .removeClass('right-sidebar-expanded')
- .addClass('right-sidebar-collapsed')
- else
- $allGutterToggleIcons
- .removeClass('fa-angle-double-left')
- .addClass('fa-angle-double-right')
- $('aside.right-sidebar')
- .removeClass('right-sidebar-collapsed')
- .addClass('right-sidebar-expanded')
- $('.page-with-sidebar')
- .removeClass('right-sidebar-collapsed')
- .addClass('right-sidebar-expanded')
- if not triggered
- $.cookie("collapsed_gutter",
- $('.right-sidebar')
- .hasClass('right-sidebar-collapsed'), { path: '/' })
-
fitSidebarForSize = ->
oldBootstrapBreakpoint = bootstrapBreakpoint
bootstrapBreakpoint = bp.getBreakpointSize()
diff --git a/app/assets/javascripts/calendar.js.coffee b/app/assets/javascripts/calendar.js.coffee
deleted file mode 100644
index d80e0e716ce..00000000000
--- a/app/assets/javascripts/calendar.js.coffee
+++ /dev/null
@@ -1,34 +0,0 @@
-class @Calendar
- constructor: (timestamps, starting_year, starting_month, calendar_activities_path) ->
- cal = new CalHeatMap()
- cal.init
- itemName: ["contribution"]
- data: timestamps
- start: new Date(starting_year, starting_month)
- domainLabelFormat: "%b"
- id: "cal-heatmap"
- domain: "month"
- subDomain: "day"
- range: 12
- tooltip: true
- label:
- position: "top"
- legend: [
- 0
- 10
- 20
- 30
- ]
- legendCellPadding: 3
- cellSize: $('.user-calendar').width() / 73
- onClick: (date, count) ->
- formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate()
- $.ajax
- url: calendar_activities_path
- data:
- date: formated_date
- cache: false
- dataType: "html"
- success: (data) ->
- $(".user-calendar-activities").html data
-
diff --git a/app/assets/javascripts/ci/build.coffee b/app/assets/javascripts/ci/build.coffee
index fca0c3bae5c..98d05e41273 100644
--- a/app/assets/javascripts/ci/build.coffee
+++ b/app/assets/javascripts/ci/build.coffee
@@ -28,12 +28,15 @@ class CiBuild
#
CiBuild.interval = setInterval =>
if window.location.href.split("#").first() is build_url
+ last_state = @state
$.ajax
url: build_url + "/trace.json?state=" + encodeURIComponent(@state)
dataType: "json"
success: (log) =>
- @state = log.state
- if log.status is "running"
+ return unless last_state is @state
+
+ if log.state and log.status is "running"
+ @state = log.state
if log.append
$('.fa-refresh').before log.html
else
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index 12c143fdf76..a3185f87640 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -16,7 +16,6 @@ class Dispatcher
shortcut_handler = null
switch page
when 'projects:issues:index'
- Issues.init()
Issuable.init()
shortcut_handler = new ShortcutsNavigation()
when 'projects:issues:show'
diff --git a/app/assets/javascripts/graphs/application.js.coffee b/app/assets/javascripts/graphs/application.js.coffee
new file mode 100644
index 00000000000..e0f681acf0b
--- /dev/null
+++ b/app/assets/javascripts/graphs/application.js.coffee
@@ -0,0 +1,7 @@
+# This is a manifest file that'll be compiled into including all the files listed below.
+# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
+# be included in the compiled file accessible from http://example.com/assets/application.js
+# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+# the compiled file.
+#
+#= require_tree .
diff --git a/app/assets/javascripts/stat_graph.js.coffee b/app/assets/javascripts/graphs/stat_graph.js.coffee
index f36c71fd25e..f36c71fd25e 100644
--- a/app/assets/javascripts/stat_graph.js.coffee
+++ b/app/assets/javascripts/graphs/stat_graph.js.coffee
diff --git a/app/assets/javascripts/stat_graph_contributors.js.coffee b/app/assets/javascripts/graphs/stat_graph_contributors.js.coffee
index 3be14cb43dd..1d9fae7cf79 100644
--- a/app/assets/javascripts/stat_graph_contributors.js.coffee
+++ b/app/assets/javascripts/graphs/stat_graph_contributors.js.coffee
@@ -1,5 +1,4 @@
#= require d3
-#= require stat_graph_contributors_util
class @ContributorsStatGraph
init: (log) ->
diff --git a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee b/app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee
index b7a0e073766..584d281a510 100644
--- a/app/assets/javascripts/stat_graph_contributors_graph.js.coffee
+++ b/app/assets/javascripts/graphs/stat_graph_contributors_graph.js.coffee
@@ -1,6 +1,4 @@
#= require d3
-#= require jquery
-#= require underscore
class @ContributorsGraph
MARGIN:
diff --git a/app/assets/javascripts/stat_graph_contributors_util.js.coffee b/app/assets/javascripts/graphs/stat_graph_contributors_util.js.coffee
index 31617c88b4a..31617c88b4a 100644
--- a/app/assets/javascripts/stat_graph_contributors_util.js.coffee
+++ b/app/assets/javascripts/graphs/stat_graph_contributors_util.js.coffee
diff --git a/app/assets/javascripts/issuable.js.coffee b/app/assets/javascripts/issuable.js.coffee
index afffed63ac5..6504e481102 100644
--- a/app/assets/javascripts/issuable.js.coffee
+++ b/app/assets/javascripts/issuable.js.coffee
@@ -1,7 +1,11 @@
+issuable_created = false
@Issuable =
init: ->
- Issuable.initTemplates()
- Issuable.initSearch()
+ unless issuable_created
+ issuable_created = true
+ Issuable.initTemplates()
+ Issuable.initSearch()
+ Issuable.initChecks()
initTemplates: ->
Issuable.labelRow = _.template(
@@ -19,7 +23,16 @@
.on 'keyup', ->
clearTimeout(@timer)
@timer = setTimeout( ->
- Issuable.filterResults $('#issue_search_form')
+ $search = $('#issue_search')
+ $form = $('.js-filter-form')
+ $input = $("input[name='#{$search.attr('name')}']", $form)
+
+ if $input.length is 0
+ $form.append "<input type='hidden' name='#{$search.attr('name')}' value='#{_.escape($search.val())}'/>"
+ else
+ $input.val $search.val()
+
+ Issuable.filterResults $form
, 500)
toggleLabelFilters: ->
@@ -59,15 +72,22 @@
dataType: "json"
reload: ->
- if Issues.created
- Issues.initChecks()
+ if Issuable.created
+ Issuable.initChecks()
$('#filter_issue_search').val($('#issue_search').val())
+ initChecks: ->
+ $('.check_all_issues').on 'click', ->
+ $('.selected_issue').prop('checked', @checked)
+ Issuable.checkChanged()
+
+ $('.selected_issue').on 'change', Issuable.checkChanged
+
updateStateFilters: ->
- stateFilters = $('.issues-state-filters')
+ stateFilters = $('.issues-state-filters, .dropdown-menu-sort')
newParams = {}
- paramKeys = ['author_id', 'milestone_title', 'assignee_id', 'issue_search']
+ paramKeys = ['author_id', 'milestone_title', 'assignee_id', 'issue_search', 'issue_search']
for paramKey in paramKeys
newParams[paramKey] = gl.utils.getParameterValues(paramKey)[0] or ''
@@ -82,3 +102,17 @@
else
newUrl = gl.utils.mergeUrlParams(newParams, initialUrl)
$(this).attr 'href', newUrl
+
+ checkChanged: ->
+ checked_issues = $('.selected_issue:checked')
+ if checked_issues.length > 0
+ ids = $.map checked_issues, (value) ->
+ $(value).data('id')
+
+ $('#update_issues_ids').val ids
+ $('.issues-other-filters').hide()
+ $('.issues_bulk_update').show()
+ else
+ $('#update_issues_ids').val []
+ $('.issues_bulk_update').hide()
+ $('.issues-other-filters').show()
diff --git a/app/assets/javascripts/issuable_form.js.coffee b/app/assets/javascripts/issuable_form.js.coffee
index 72ae3bde81e..898506fde32 100644
--- a/app/assets/javascripts/issuable_form.js.coffee
+++ b/app/assets/javascripts/issuable_form.js.coffee
@@ -19,6 +19,7 @@ class @IssuableForm
@form.on "click", ".btn-cancel", @resetAutosave
@initWip()
+ @initMoveDropdown()
$issuableDueDate = $('#issuable-due-date')
@@ -89,3 +90,19 @@ class @IssuableForm
addWip: ->
@titleField.val "WIP: #{@titleField.val()}"
+
+ initMoveDropdown: ->
+ $moveDropdown = $('.js-move-dropdown')
+
+ if $moveDropdown.length
+ $('.js-move-dropdown').select2
+ ajax:
+ url: $moveDropdown.data('projects-url')
+ results: (data) ->
+ return {
+ results: data
+ }
+ formatResult: (project) ->
+ project.name_with_namespace
+ formatSelection: (project) ->
+ project.name_with_namespace
diff --git a/app/assets/javascripts/issues.js.coffee b/app/assets/javascripts/issues.js.coffee
deleted file mode 100644
index 3330e6c68ad..00000000000
--- a/app/assets/javascripts/issues.js.coffee
+++ /dev/null
@@ -1,38 +0,0 @@
-@Issues =
- init: ->
- Issues.created = true
- Issues.initChecks()
-
- $("body").on "ajax:success", ".close_issue, .reopen_issue", ->
- t = $(this)
- totalIssues = undefined
- reopen = t.hasClass("reopen_issue")
- $(".issue_counter").each ->
- issue = $(this)
- totalIssues = parseInt($(this).html(), 10)
- if reopen and issue.closest(".main_menu").length
- $(this).html totalIssues + 1
- else
- $(this).html totalIssues - 1
-
- initChecks: ->
- $(".check_all_issues").click ->
- $(".selected_issue").prop("checked", @checked)
- Issues.checkChanged()
-
- $(".selected_issue").bind "change", Issues.checkChanged
-
- checkChanged: ->
- checked_issues = $(".selected_issue:checked")
- if checked_issues.length > 0
- ids = []
- $.each checked_issues, (index, value) ->
- ids.push $(value).attr("data-id")
-
- $("#update_issues_ids").val ids
- $(".issues-other-filters").hide()
- $(".issues_bulk_update").show()
- else
- $("#update_issues_ids").val []
- $(".issues_bulk_update").hide()
- $(".issues-other-filters").show()
diff --git a/app/assets/javascripts/layout_nav.js.coffee b/app/assets/javascripts/layout_nav.js.coffee
new file mode 100644
index 00000000000..6adac6dac97
--- /dev/null
+++ b/app/assets/javascripts/layout_nav.js.coffee
@@ -0,0 +1,14 @@
+class @LayoutNav
+ $ ->
+ $('.fade-left').addClass('end-scroll')
+ $('.scrolling-tabs').on 'scroll', (event) ->
+ $this = $(this)
+ $el = $(event.target)
+ currentPosition = $this.scrollLeft()
+ size = bp.getBreakpointSize()
+ controlBtnWidth = $('.controls').width()
+ maxPosition = $this.get(0).scrollWidth - $this.parent().width()
+ maxPosition += controlBtnWidth if size isnt 'xs' and $('.nav-control').length
+
+ $el.find('.fade-left').toggleClass('end-scroll', currentPosition is 0)
+ $el.find('.fade-right').toggleClass('end-scroll', currentPosition is maxPosition)
diff --git a/app/assets/javascripts/lib/url_utility.js.coffee b/app/assets/javascripts/lib/url_utility.js.coffee
index 6a00932c028..e8085e1c2e4 100644
--- a/app/assets/javascripts/lib/url_utility.js.coffee
+++ b/app/assets/javascripts/lib/url_utility.js.coffee
@@ -26,10 +26,19 @@
newUrl = decodeURIComponent(url)
for paramName, paramValue of params
pattern = new RegExp "\\b(#{paramName}=).*?(&|$)"
- if url.search(pattern) >= 0
+ if not paramValue?
+ newUrl = newUrl.replace pattern, ''
+ else if url.search(pattern) isnt -1
newUrl = newUrl.replace pattern, "$1#{paramValue}$2"
else
newUrl = "#{newUrl}#{(if newUrl.indexOf('?') > 0 then '&' else '?')}#{paramName}=#{paramValue}"
+
+ # Remove a trailing ampersand
+ lastChar = newUrl[newUrl.length - 1]
+
+ if lastChar is '&'
+ newUrl = newUrl.slice 0, -1
+
newUrl
# removes parameter query string from url. returns the modified url
diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee
index 372732d0aac..49a4727205a 100644
--- a/app/assets/javascripts/merge_request_tabs.js.coffee
+++ b/app/assets/javascripts/merge_request_tabs.js.coffee
@@ -75,6 +75,9 @@ class @MergeRequestTabs
@loadDiff($target.attr('href'))
if bp? and bp.getBreakpointSize() isnt 'lg'
@shrinkView()
+
+ navBarHeight = $('.navbar-gitlab').outerHeight()
+ $.scrollTo(".merge-request-details .merge-request-tabs", offset: -navBarHeight)
else if action == 'builds'
@loadBuilds($target.attr('href'))
@expandView()
diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee
index b6d590f681c..779f536d9f0 100644
--- a/app/assets/javascripts/merge_request_widget.js.coffee
+++ b/app/assets/javascripts/merge_request_widget.js.coffee
@@ -10,6 +10,7 @@ class @MergeRequestWidget
$('#modal_merge_info').modal(show: false)
@firstCICheck = true
@readyForCICheck = false
+ @cancel = false
clearInterval @fetchBuildStatusInterval
@clearEventListeners()
@@ -21,10 +22,16 @@ class @MergeRequestWidget
clearEventListeners: ->
$(document).off 'page:change.merge_request'
+ cancelPolling: ->
+ @cancel = true
+
addEventListeners: ->
+ allowedPages = ['show', 'commits', 'builds', 'changes']
$(document).on 'page:change.merge_request', =>
- if $('body').data('page') isnt 'projects:merge_requests:show'
+ page = $('body').data('page').split(':').last()
+ if allowedPages.indexOf(page) < 0
clearInterval @fetchBuildStatusInterval
+ @cancelPolling()
@clearEventListeners()
mergeInProgress: (deleteSourceBranch = false)->
@@ -67,6 +74,7 @@ class @MergeRequestWidget
$('.ci-widget-fetching').show()
$.getJSON @opts.ci_status_url, (data) =>
+ return if @cancel
@readyForCICheck = true
if data.status is ''
@@ -106,6 +114,7 @@ class @MergeRequestWidget
@firstCICheck = false
showCIStatus: (state) ->
+ return if not state?
$('.ci_widget').hide()
allowed_states = ["failed", "canceled", "running", "pending", "success", "skipped", "not_found"]
if state in allowed_states
@@ -126,6 +135,6 @@ class @MergeRequestWidget
$('.ci_widget:visible .ci-coverage').text(text)
setMergeButtonClass: (css_class) ->
- $('.js-merge-button')
+ $('.js-merge-button,.accept-action .dropdown-toggle')
.removeClass('btn-danger btn-warning btn-create')
.addClass(css_class)
diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee
index 6d9d6528f45..f8151963fa7 100644
--- a/app/assets/javascripts/notes.js.coffee
+++ b/app/assets/javascripts/notes.js.coffee
@@ -114,9 +114,9 @@ class @Notes
@refresh()
, @pollingInterval
- refresh: ->
+ refresh: =>
return if @refreshing is true
- refreshing = true
+ @refreshing = true
if not document.hidden and document.URL.indexOf(@noteable_url) is 0
@getContent()
@@ -134,8 +134,8 @@ class @Notes
@renderDiscussionNote(note)
else
@renderNote(note)
- always: =>
- @refreshing = false
+ .always () =>
+ @refreshing = false
###
Increase @pollingInterval up to 120 seconds on every function call,
@@ -329,7 +329,7 @@ class @Notes
@renderDiscussionNote(note)
# cleanup after successfully creating a diff/discussion note
- @removeDiscussionNoteForm($("#new-discussion-note-form-#{note.discussion_id}"))
+ @removeDiscussionNoteForm($(xhr.target))
###
Called in response to the edit note form being submitted
diff --git a/app/assets/javascripts/right_sidebar.js.coffee b/app/assets/javascripts/right_sidebar.js.coffee
index 2d084b76cfe..c9cb0f4bb32 100644
--- a/app/assets/javascripts/right_sidebar.js.coffee
+++ b/app/assets/javascripts/right_sidebar.js.coffee
@@ -10,6 +10,40 @@ class @Sidebar
$('.dropdown').on('loading.gl.dropdown', @sidebarDropdownLoading)
$('.dropdown').on('loaded.gl.dropdown', @sidebarDropdownLoaded)
+
+ $(document)
+ .off 'click', '.js-sidebar-toggle'
+ .on 'click', '.js-sidebar-toggle', (e, triggered) ->
+ e.preventDefault()
+ $this = $(this)
+ $thisIcon = $this.find 'i'
+ $allGutterToggleIcons = $('.js-sidebar-toggle i')
+ if $thisIcon.hasClass('fa-angle-double-right')
+ $allGutterToggleIcons
+ .removeClass('fa-angle-double-right')
+ .addClass('fa-angle-double-left')
+ $('aside.right-sidebar')
+ .removeClass('right-sidebar-expanded')
+ .addClass('right-sidebar-collapsed')
+ $('.page-with-sidebar')
+ .removeClass('right-sidebar-expanded')
+ .addClass('right-sidebar-collapsed')
+ else
+ $allGutterToggleIcons
+ .removeClass('fa-angle-double-left')
+ .addClass('fa-angle-double-right')
+ $('aside.right-sidebar')
+ .removeClass('right-sidebar-collapsed')
+ .addClass('right-sidebar-expanded')
+ $('.page-with-sidebar')
+ .removeClass('right-sidebar-collapsed')
+ .addClass('right-sidebar-expanded')
+ if not triggered
+ $.cookie("collapsed_gutter",
+ $('.right-sidebar')
+ .hasClass('right-sidebar-collapsed'), { path: '/' })
+
+
sidebarDropdownLoading: (e) ->
$sidebarCollapsedIcon = $(@).closest('.block').find('.sidebar-collapsed-icon')
img = $sidebarCollapsedIcon.find('img')
@@ -76,7 +110,7 @@ class @Sidebar
@triggerOpenSidebar() if not @isOpen()
if action is 'hide'
- @triggerOpenSidebar() is @isOpen()
+ @triggerOpenSidebar() if @isOpen()
isOpen: ->
@sidebar.is('.right-sidebar-expanded')
diff --git a/app/assets/javascripts/users/application.js.coffee b/app/assets/javascripts/users/application.js.coffee
new file mode 100644
index 00000000000..647ffbf5f45
--- /dev/null
+++ b/app/assets/javascripts/users/application.js.coffee
@@ -0,0 +1,8 @@
+# This is a manifest file that'll be compiled into including all the files listed below.
+# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
+# be included in the compiled file accessible from http://example.com/assets/application.js
+# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+# the compiled file.
+#
+#= require d3
+#= require_tree .
diff --git a/app/assets/javascripts/users/calendar.js.coffee b/app/assets/javascripts/users/calendar.js.coffee
new file mode 100644
index 00000000000..26a26061539
--- /dev/null
+++ b/app/assets/javascripts/users/calendar.js.coffee
@@ -0,0 +1,198 @@
+class @Calendar
+ constructor: (timestamps, @calendar_activities_path) ->
+ @currentSelectedDate = ''
+ @daySpace = 1
+ @daySize = 15
+ @daySizeWithSpace = @daySize + (@daySpace * 2)
+ @monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+ @months = []
+ @highestValue = 0
+
+ # Get the highest value from the timestampes
+ _.each timestamps, (count) =>
+ if count > @highestValue
+ @highestValue = count
+
+ # Loop through the timestamps to create a group of objects
+ # The group of objects will be grouped based on the day of the week they are
+ @timestampsTmp = []
+ i = 0
+ group = 0
+ _.each timestamps, (count, date) =>
+ newDate = new Date parseInt(date) * 1000
+ day = newDate.getDay()
+
+ # Create a new group array if this is the first day of the week
+ # or if is first object
+ if (day is 0 and i isnt 0) or i is 0
+ @timestampsTmp.push []
+ group++
+
+ innerArray = @timestampsTmp[group-1]
+
+ # Push to the inner array the values that will be used to render map
+ innerArray.push
+ count: count
+ date: newDate
+ day: day
+
+ i++
+
+ # Init color functions
+ @color = @initColor()
+ @colorKey = @initColorKey()
+
+ # Init the svg element
+ @renderSvg(group)
+ @renderDays()
+ @renderMonths()
+ @renderDayTitles()
+ @renderKey()
+
+ @initTooltips()
+
+ renderSvg: (group) ->
+ @svg = d3.select '.js-contrib-calendar'
+ .append 'svg'
+ .attr 'width', (group + 1) * @daySizeWithSpace
+ .attr 'height', 167
+ .attr 'class', 'contrib-calendar'
+
+ renderDays: ->
+ @svg.selectAll 'g'
+ .data @timestampsTmp
+ .enter()
+ .append 'g'
+ .attr 'transform', (group, i) =>
+ _.each group, (stamp, a) =>
+ if a is 0 and stamp.day is 0
+ month = stamp.date.getMonth()
+ x = (@daySizeWithSpace * i + 1) + @daySizeWithSpace
+ lastMonth = _.last(@months)
+ if lastMonth?
+ lastMonthX = lastMonth.x
+
+ if !lastMonth?
+ @months.push
+ month: month
+ x: x
+ else if month isnt lastMonth.month and x - @daySizeWithSpace isnt lastMonthX
+ @months.push
+ month: month
+ x: x
+
+ "translate(#{(@daySizeWithSpace * i + 1) + @daySizeWithSpace}, 18)"
+ .selectAll 'rect'
+ .data (stamp) ->
+ stamp
+ .enter()
+ .append 'rect'
+ .attr 'x', '0'
+ .attr 'y', (stamp, i) =>
+ (@daySizeWithSpace * stamp.day)
+ .attr 'width', @daySize
+ .attr 'height', @daySize
+ .attr 'title', (stamp) =>
+ contribText = 'No contributions'
+
+ if stamp.count > 0
+ contribText = "#{stamp.count} contribution#{if stamp.count > 1 then 's' else ''}"
+
+ date = dateFormat(stamp.date, 'mmm d, yyyy')
+
+ "#{contribText}<br />#{date}"
+ .attr 'class', 'user-contrib-cell js-tooltip'
+ .attr 'fill', (stamp) =>
+ if stamp.count isnt 0
+ @color(stamp.count)
+ else
+ '#ededed'
+ .attr 'data-container', 'body'
+ .on 'click', @clickDay
+
+ renderDayTitles: ->
+ days = [{
+ text: 'M'
+ y: 29 + (@daySizeWithSpace * 1)
+ }, {
+ text: 'W'
+ y: 29 + (@daySizeWithSpace * 3)
+ }, {
+ text: 'F'
+ y: 29 + (@daySizeWithSpace * 5)
+ }]
+ @svg.append 'g'
+ .selectAll 'text'
+ .data days
+ .enter()
+ .append 'text'
+ .attr 'text-anchor', 'middle'
+ .attr 'x', 8
+ .attr 'y', (day) ->
+ day.y
+ .text (day) ->
+ day.text
+ .attr 'class', 'user-contrib-text'
+
+ renderMonths: ->
+ @svg.append 'g'
+ .selectAll 'text'
+ .data @months
+ .enter()
+ .append 'text'
+ .attr 'x', (date) ->
+ date.x
+ .attr 'y', 10
+ .attr 'class', 'user-contrib-text'
+ .text (date) =>
+ @monthNames[date.month]
+
+ renderKey: ->
+ keyColors = ['#ededed', @colorKey(0), @colorKey(1), @colorKey(2), @colorKey(3)]
+ @svg.append 'g'
+ .attr 'transform', "translate(18, #{@daySizeWithSpace * 8 + 16})"
+ .selectAll 'rect'
+ .data keyColors
+ .enter()
+ .append 'rect'
+ .attr 'width', @daySize
+ .attr 'height', @daySize
+ .attr 'x', (color, i) =>
+ @daySizeWithSpace * i
+ .attr 'y', 0
+ .attr 'fill', (color) ->
+ color
+
+ initColor: ->
+ d3.scale
+ .linear()
+ .range(['#acd5f2', '#254e77'])
+ .domain([0, @highestValue])
+
+ initColorKey: ->
+ d3.scale
+ .linear()
+ .range(['#acd5f2', '#254e77'])
+ .domain([0, 3])
+
+ clickDay: (stamp) =>
+ if @currentSelectedDate isnt stamp.date
+ @currentSelectedDate = stamp.date
+ formatted_date = @currentSelectedDate.getFullYear() + "-" + (@currentSelectedDate.getMonth()+1) + "-" + @currentSelectedDate.getDate()
+
+ $.ajax
+ url: @calendar_activities_path
+ data:
+ date: formatted_date
+ cache: false
+ dataType: 'html'
+ beforeSend: ->
+ $('.user-calendar-activities').html '<div class="text-center"><i class="fa fa-spinner fa-spin user-calendar-activities-loading"></i></div>'
+ success: (data) ->
+ $('.user-calendar-activities').html data
+ else
+ $('.user-calendar-activities').html ''
+
+ initTooltips: ->
+ $('.js-contrib-calendar .js-tooltip').tooltip
+ html: true
diff --git a/app/assets/javascripts/users_select.js.coffee b/app/assets/javascripts/users_select.js.coffee
index b80b1b861cc..519618aa617 100644
--- a/app/assets/javascripts/users_select.js.coffee
+++ b/app/assets/javascripts/users_select.js.coffee
@@ -93,7 +93,9 @@ class @UsersSelect
$dropdown.glDropdown(
data: (term, callback) =>
- @users term, (users) =>
+ isAuthorFilter = $('.js-author-search')
+
+ @users term, term is '' and isAuthorFilter, (users) =>
if term.length is 0
showDivider = 0
@@ -138,7 +140,7 @@ class @UsersSelect
toggleLabel: (selected) ->
if selected && 'id' of selected
- selected.name
+ if selected.text then selected.text else selected.name
else
defaultLabel
@@ -219,7 +221,7 @@ class @UsersSelect
multiple: $(select).hasClass('multiselect')
minimumInputLength: 0
query: (query) =>
- @users query.term, (users) =>
+ @users query.term, @projectId?, (users) =>
data = { results: users }
if query.term.length == 0
@@ -302,7 +304,7 @@ class @UsersSelect
# Return users list. Filtered by query
# Only active users retrieved
- users: (query, callback) =>
+ users: (query, fromProject, callback) =>
url = @buildUrl(@usersPath)
$.ajax(
@@ -311,7 +313,7 @@ class @UsersSelect
search: query
per_page: 20
active: true
- project_id: @projectId
+ project_id: @projectId if fromProject
group_id: @groupId
current_user: @showCurrentUser
author_id: @authorId
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index e2d590f4df4..8b93665d085 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -8,7 +8,6 @@
*= require select2
*= require_self
*= require dropzone/basic
- *= require cal-heatmap
*= require cropper.css
*/
diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss
index eaf85bb17ca..467f3b35d74 100644
--- a/app/assets/stylesheets/framework/buttons.scss
+++ b/app/assets/stylesheets/framework/buttons.scss
@@ -16,6 +16,19 @@
@include btn-default;
}
+@mixin btn-outline($background, $text, $border, $hover-background, $hover-text, $hover-border) {
+ background-color: $background;
+ color: $text;
+ border-color: $border;
+
+ &:hover,
+ &:focus {
+ background-color: $hover-background;
+ color: $hover-text;
+ border-color: $hover-border;;
+ }
+}
+
@mixin btn-color($light, $border-light, $normal, $border-normal, $dark, $border-dark, $color) {
background-color: $light;
border-color: $border-light;
@@ -106,11 +119,14 @@
@include btn-blue;
}
- &.btn-close,
&.btn-warning {
@include btn-orange;
}
+ &.btn-close {
+ @include btn-outline($white-light, $orange-normal, $orange-normal, $orange-light, $white-light, $orange-light);
+ }
+
&.btn-danger,
&.btn-remove,
&.btn-red {
diff --git a/app/assets/stylesheets/framework/calendar.scss b/app/assets/stylesheets/framework/calendar.scss
index 11f39d583bd..8642b7530e2 100644
--- a/app/assets/stylesheets/framework/calendar.scss
+++ b/app/assets/stylesheets/framework/calendar.scss
@@ -1,70 +1,44 @@
.calender-block {
+ padding-left: 0;
+ padding-right: 0;
+
@media (min-width: $screen-sm-min) and (max-width: $screen-lg-min) {
overflow-x: scroll;
}
}
.user-calendar-activities {
- .calendar_onclick_hr {
- padding: 0;
- margin: 10px 0;
- }
-
.str-truncated {
max-width: 70%;
}
- .text-expander {
- background: #eee;
- color: #555;
- padding: 0 5px;
- cursor: pointer;
- margin-left: 4px;
- &:hover {
- background-color: #ddd;
- }
+ .user-calendar-activities-loading {
+ font-size: 24px;
}
}
-/**
-* This overwrites the default values of the cal-heatmap gem
-*/
-.calendar {
- .qi {
- fill: #fff;
- }
-
- .q1 {
- fill: #ededed !important;
- }
+.user-calendar {
+ text-align: center;
- .q2 {
- fill: #acd5f2 !important;
- }
-
- .q3 {
- fill: #7fa8d1 !important;
- }
-
- .q4 {
- fill: #49729b !important;
- }
-
- .q5 {
- fill: #254e77 !important;
+ .calendar {
+ display: inline-block;
}
+}
- .future {
- visibility: hidden;
+.user-contrib-cell {
+ &:hover {
+ cursor: pointer;
+ stroke: #000;
}
+}
- .domain-background {
- fill: none;
- shape-rendering: crispedges;
- }
+.user-contrib-text {
+ font-size: 12px;
+ fill: #959494;
+}
- .ch-tooltip {
- padding: 3px;
- font-weight: 550;
- }
+.calendar-hint {
+ margin-top: -23px;
+ float: right;
+ font-size: 12px;
}
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index 4bf3a050403..93c63c69843 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -154,7 +154,7 @@
color: $dropdown-header-color;
font-size: 13px;
line-height: 22px;
- padding: 0 10px 10px;
+ padding: 0 10px;
}
.separator + .dropdown-header {
@@ -162,6 +162,10 @@
}
}
+.dropdown-menu-full-width {
+ width: 100%;
+}
+
.dropdown-menu-paging {
.dropdown-page-two,
.dropdown-menu-back {
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index 8c96c7a9c31..71a9f79be3e 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -5,6 +5,10 @@
.file-holder {
border: 1px solid $border-color;
+ &.file-holder-no-border {
+ border: 0;
+ }
+
&.readme-holder {
margin: $gl-padding-top 0;
}
@@ -23,8 +27,17 @@
word-wrap: break-word;
border-radius: 3px 3px 0 0;
+ &.file-title-clear {
+ padding-left: 0;
+ padding-right: 0;
+ background-color: transparent;
+
+ .file-actions {
+ right: 0;
+ }
+ }
+
.file-actions {
- float: right;
position: absolute;
top: 5px;
right: 15px;
diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss
index c70be58f48f..7eb7a8e4544 100644
--- a/app/assets/stylesheets/framework/nav.scss
+++ b/app/assets/stylesheets/framework/nav.scss
@@ -1,3 +1,34 @@
+@mixin fade($gradient-direction, $rgba, $gradient-color) {
+ visibility: visible;
+ opacity: 1;
+ position: absolute;
+ bottom: 12px;
+ width: 43px;
+ height: 30px;
+ transition-duration: .3s;
+ -webkit-transform: translateZ(0);
+ background: -webkit-linear-gradient($gradient-direction, $rgba, $gradient-color 45%);
+ background: -o-linear-gradient($gradient-direction, $rgba, $gradient-color 45%);
+ background: -moz-linear-gradient($gradient-direction, $rgba, $gradient-color 45%);
+ background: linear-gradient($gradient-direction, $rgba, $gradient-color 45%);
+
+ &.end-scroll {
+ visibility: hidden;
+ opacity: 0;
+ transition-duration: .3s;
+ }
+}
+
+@mixin scrolling-links() {
+ white-space: nowrap;
+ overflow-x: auto;
+ overflow-y: hidden;
+ -webkit-overflow-scrolling: touch;
+ &::-webkit-scrollbar {
+ display: none;
+ }
+}
+
.nav-links {
padding: 0;
margin: 0;
@@ -119,7 +150,7 @@
}
input {
- height: 34px;
+ height: 35px;
display: inline-block;
position: relative;
top: 2px;
@@ -196,7 +227,7 @@
position: fixed;
top: $header-height;
width: 100%;
- z-index: 3;
+ z-index: 11;
background: $background-color;
border-bottom: 1px solid $border-color;
transition-duration: .3s;
@@ -209,13 +240,8 @@
float: right;
padding: 7px 0 0;
- @media (max-width: $screen-xs-min) {
- float: none;
- padding: 0 9px;
-
- .dropdown-new {
- width: 100%;
- }
+ @media (max-width: $screen-xs-max) {
+ display: none;
}
i {
@@ -246,14 +272,18 @@
}
.nav-links {
+ @include scrolling-links();
border-bottom: none;
height: 51px;
- white-space: nowrap;
- overflow-x: auto;
- overflow-y: hidden;
- -webkit-overflow-scrolling: touch;
- &::-webkit-scrollbar {
- display: none;
+
+ .fade-right {
+ @include fade(left, rgba(250, 250, 250, 0.4), $background-color);
+ right: 0;
+ }
+
+ .fade-left {
+ @include fade(right, rgba(250, 250, 250, 0.4), $background-color);
+ left: 0;
}
li {
@@ -278,18 +308,62 @@
}
}
+ .nav-control {
+ .fade-right {
+
+ @media (min-width: $screen-xs-max) {
+ right: 67px;
+ }
+ @media (max-width: $screen-xs-min) {
+ right: 0;
+ }
+ }
+ }
}
-.page-with-layout-nav {
- margin-top: 50px;
+.nav-block {
+ position: relative;
- &.controls-dropdown-visible {
- @media (max-width: $screen-xs-min) {
- margin-top: 96px;
+ .nav-links {
+ @include scrolling-links();
+
+ .fade-right {
+ @include fade(left, rgba(255, 255, 255, 0.4), $white-light);
+ right: 0;
+ }
+
+ .fade-left {
+ @include fade(right, rgba(255, 255, 255, 0.4), $white-light);
+ left: 0;
+ }
+
+ &.event-filter {
+ .fade-right {
+ visibility: hidden;
+
+ @media (max-width: $screen-xs-max) {
+ visibility: visible;
+ }
+ }
}
}
+}
+
+.page-with-layout-nav {
+ margin-top: $header-height + 2;
.right-sidebar {
top: ($header-height * 2) + 2;
}
}
+
+.activities {
+
+ .nav-block {
+ border-bottom: 1px solid $border-color;
+
+ .nav-links {
+ border-bottom: none;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index f90d7a806d3..67f491b6d9c 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -324,7 +324,7 @@
.layout-nav {
@media (max-width: $screen-xs-min) {
- padding-right: 0;;
+ padding-right: 0;
}
@media (min-width: $screen-xs-min) and (max-width: $screen-md-min) {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index c7784e15844..f253da814bc 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -63,7 +63,8 @@ $gl-padding-top: 10px;
/*
* Misc
*/
-$row-hover: #f4f8fe;
+$row-hover: #f7faff;
+$row-hover-border: #b2d7ff;
$progress-color: #c0392b;
$avatar_radius: 50%;
$header-height: 50px;
@@ -104,7 +105,7 @@ $blue-medium-light: #3498cb;
$blue-medium: #2f8ebf;
$blue-medium-dark: #2d86b4;
-$orange-light: rgba(252, 109, 38, 0.80);
+$orange-light: #fc8a51;
$orange-normal: #e75e40;
$orange-dark: #ce5237;
diff --git a/app/assets/stylesheets/mailers/devise.scss b/app/assets/stylesheets/mailers/devise.scss
new file mode 100644
index 00000000000..28611a5ec81
--- /dev/null
+++ b/app/assets/stylesheets/mailers/devise.scss
@@ -0,0 +1,134 @@
+// NOTE: This stylesheet is for the exclusive use of the `devise_mailer` layout
+// used for Devise email templates, and _should not_ be included in any
+// application stylesheets.
+//
+// Styles defined here are embedded directly into the resulting email HTML via
+// the `premailer` gem.
+
+$body-background-color: #363636;
+$message-background-color: #fafafa;
+
+$header-color: #6b4fbb;
+$body-color: #444;
+$cta-color: #e14329;
+$footer-link-color: #7e7e7e;
+
+$font-family: Helvetica, Arial, sans-serif;
+
+body {
+ background-color: $body-background-color;
+ font-family: $font-family;
+ margin: 0;
+ padding: 0;
+}
+
+table {
+ -premailer-cellpadding: 0;
+ -premailer-cellspacing: 0;
+
+ border: 0;
+ border-collapse: separate;
+
+ &#wrapper {
+ background-color: $body-background-color;
+ width: 100%;
+ }
+
+ &#header {
+ margin: 0 auto;
+ text-align: left;
+ width: 600px;
+ }
+
+ &#body {
+ background-color: $message-background-color;
+ border: 1px solid #000;
+ border-radius: 4px;
+ margin: 0 auto;
+ width: 600px;
+ }
+
+ &#footer {
+ color: $footer-link-color;
+ font-size: 14px;
+ text-align: center;
+ width: 100%;
+ }
+
+ td {
+ &#body-container {
+ padding: 20px 40px;
+ }
+ }
+}
+
+.center {
+ text-align: center;
+}
+
+#logo {
+ border: none;
+ outline: none;
+ min-height: 88px;
+ width: 134px;
+}
+
+#content {
+ h2 {
+ color: $header-color;
+ font-size: 30px;
+ font-weight: 400;
+ line-height: 34px;
+ margin-top: 0;
+ }
+
+ p {
+ color: $body-color;
+ font-size: 17px;
+ line-height: 24px;
+ margin-bottom: 0;
+ }
+}
+
+#cta {
+ border: 1px solid $cta-color;
+ border-radius: 3px;
+ display: inline-block;
+ margin: 20px 0;
+ padding: 12px 24px;
+
+ a {
+ background-color: $message-background-color;
+ color: $cta-color;
+ display: inline-block;
+ text-decoration: none;
+ }
+}
+
+#tanuki {
+ padding: 40px 0 0;
+
+ img {
+ border: none;
+ outline: none;
+ width: 37px;
+ min-height: 36px;
+ }
+}
+
+#tagline {
+ font-size: 22px;
+ font-weight: 100;
+ padding: 4px 0 40px;
+}
+
+#social {
+ padding: 0 10px 20px;
+ width: 600px;
+ word-spacing: 20px;
+
+ a {
+ color: $footer-link-color;
+ text-decoration: none;
+ }
+}
diff --git a/app/assets/stylesheets/pages/commit.scss b/app/assets/stylesheets/pages/commit.scss
index c2cd227571f..fc3f214aba5 100644
--- a/app/assets/stylesheets/pages/commit.scss
+++ b/app/assets/stylesheets/pages/commit.scss
@@ -26,8 +26,28 @@
.commit-info-row {
margin-bottom: 10px;
+
+ &.commit-info-row-header {
+ line-height: 34px;
+
+ @media (min-width: $screen-sm-min) {
+ margin-bottom: 0;
+ }
+
+ .commit-options-dropdown-caret {
+ @media (max-width: $screen-sm) {
+ margin-left: 0;
+ }
+ }
+ }
+
.avatar {
@extend .avatar-inline;
+ margin-left: 0;
+
+ @media (min-width: $screen-sm-min) {
+ margin-left: 4px;
+ }
}
.commit-committer-link,
.commit-author-link {
@@ -35,10 +55,6 @@
font-weight: bold;
}
- .time_ago {
- margin-left: 8px;
- }
-
.fa-clipboard {
color: $dropdown-title-btn-color;
}
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index fc9db97132d..4e35ca329e4 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -40,11 +40,6 @@
}
}
-.issue-search-form {
- margin: 0;
- height: 24px;
-}
-
form.edit-issue {
margin: 0;
}
@@ -96,8 +91,3 @@ form.edit-issue {
.issue-form .select2-container {
width: 250px !important;
}
-
-.issue-closed-by-widget {
- color: $gl-text-color;
- margin-left: 52px;
-}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index c4005ba1e69..8046e203a99 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -41,7 +41,7 @@
margin: 0;
margin-left: 20px;
padding: 5px;
- padding-top: 12px;
+ padding-top: 8px;
line-height: 20px;
&.right {
@@ -110,6 +110,29 @@
p:last-child {
margin-bottom: 0;
}
+
+ @media (max-width: $screen-sm-max) {
+ h4 {
+ font-size: 15px;
+ }
+
+ p {
+ font-size: 13px;
+ }
+
+ .btn,
+ .btn-group,
+ .accept-action {
+ width: 100%;
+ margin-bottom: 4px;
+ }
+
+ .accept-control {
+ width: 100%;
+ text-align: center;
+ margin: 0;
+ }
+ }
}
.mr-widget-footer {
@@ -280,11 +303,5 @@
background-color: $white-light;
color: $gl-placeholder-color;
}
-
- th,
- td {
- padding: 16px;
- }
}
}
-
diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss
index 546176b65e4..6128868b670 100644
--- a/app/assets/stylesheets/pages/pipelines.scss
+++ b/app/assets/stylesheets/pages/pipelines.scss
@@ -1,4 +1,24 @@
-.pipeline-stage {
- overflow: hidden;
- text-overflow: ellipsis;
+.pipelines {
+ .stage {
+ max-width: 100px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .duration, .finished_at {
+ margin: 4px 0;
+ }
+
+ .commit-title {
+ margin: 0;
+ }
+
+ .controls {
+ white-space: nowrap;
+ }
+
+ .btn {
+ margin: 4px;
+ }
}
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index 843379a3f54..167ab40d881 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -66,12 +66,6 @@
}
}
-.calendar-hint {
- margin-top: -12px;
- float: right;
- font-size: 12px;
-}
-
.profile-link-holder {
display: inline;
@@ -134,14 +128,6 @@
}
}
-.change-username-title {
- color: $gl-warning;
-}
-
-.remove-account-title {
- color: $gl-danger;
-}
-
.provider-btn-group {
display: inline-block;
margin-right: 10px;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index b7653a833ec..edef336481d 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -10,7 +10,7 @@
margin-bottom: 0;
}
.new_project,
-.edit_project {
+.edit-project {
fieldset.features {
.control-label {
font-weight: normal;
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss
index 3fb70085713..2e8f356298d 100644
--- a/app/assets/stylesheets/pages/settings.scss
+++ b/app/assets/stylesheets/pages/settings.scss
@@ -12,3 +12,11 @@
border: 1px solid $warning-message-border;
border-radius: $border-radius-base;
}
+
+.warning-title {
+ color: $gl-warning;
+}
+
+.danger-title {
+ color: $gl-danger;
+}
diff --git a/app/assets/stylesheets/pages/snippets.scss b/app/assets/stylesheets/pages/snippets.scss
index 639d639d5b0..2aa939b7dc3 100644
--- a/app/assets/stylesheets/pages/snippets.scss
+++ b/app/assets/stylesheets/pages/snippets.scss
@@ -16,19 +16,6 @@
}
}
-.snippet-box {
- @include border-radius(2px);
-
- display: block;
- float: left;
- padding: 0 $gl-padding;
- font-weight: normal;
- margin-right: 10px;
- font-size: $gl-font-size;
- border: 1px solid;
- line-height: 32px;
-}
-
.markdown-snippet-copy {
position: fixed;
top: -10px;
@@ -36,3 +23,34 @@
max-height: 0;
max-width: 0;
}
+
+.file-holder.snippet-file-content {
+ padding-bottom: $gl-padding;
+ border-bottom: 1px solid $border-color;
+
+ .file-title {
+ padding-top: $gl-padding;
+ padding-bottom: $gl-padding;
+ }
+
+ .file-actions {
+ top: 12px;
+ }
+
+ .file-content {
+ border-left: 1px solid $border-color;
+ border-right: 1px solid $border-color;
+ border-bottom: 1px solid $border-color;
+ }
+}
+
+.snippet-title {
+ font-size: 24px;
+ font-weight: normal;
+}
+
+.snippet-actions {
+ @media (min-width: $screen-sm-min) {
+ float: right;
+ }
+}
diff --git a/app/assets/stylesheets/pages/todos.scss b/app/assets/stylesheets/pages/todos.scss
index e51c3491dae..afc00a68572 100644
--- a/app/assets/stylesheets/pages/todos.scss
+++ b/app/assets/stylesheets/pages/todos.scss
@@ -29,6 +29,17 @@
.todo-item {
.todo-title {
@include str-truncated(calc(100% - 174px));
+ overflow: visible;
+ }
+
+ .status-box {
+ margin: 0;
+ float: none;
+ display: inline-block;
+ font-weight: normal;
+ padding: 0 5px;
+ line-height: inherit;
+ font-size: 14px;
}
.todo-body {
@@ -76,12 +87,11 @@
@media (max-width: $screen-xs-max) {
.todo-item {
- padding-left: $gl-padding;
-
.todo-title {
white-space: normal;
overflow: visible;
max-width: 100%;
+ margin-bottom: 10px;
}
.avatar {
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index a84fc2e0318..f16fc7f388f 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -15,16 +15,23 @@
margin-bottom: 0;
tr {
- > td, > th {
+ border-bottom: 1px solid $table-border-gray;
+ border-top: 1px solid $table-border-gray;
+
+ td, th {
line-height: 23px;
}
&:hover {
+ cursor: pointer;
+
td {
- background: $row-hover;
+ background-color: $row-hover;
+ border-top: 1px solid $row-hover-border;
+ border-bottom: 1px solid $row-hover-border;
}
- cursor: pointer;
}
+
&.selected {
td {
background: $gray-dark;
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index ff7a5cad2fb..0a34a12e2a7 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -107,6 +107,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:repository_checks_enabled,
:metrics_packet_size,
:send_user_confirmation_email,
+ :container_registry_token_expire_delay,
restricted_visibility_levels: [],
import_sources: [],
disabled_oauth_sign_in_sources: []
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 1429ee40bb7..c28d1ca9e3b 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -232,7 +232,7 @@ class ApplicationController < ActionController::Base
end
def configure_permitted_parameters
- devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password, :login, :remember_me, :otp_attempt) }
+ devise_parameter_sanitizer.permit(:sign_in, keys: [:username, :email, :password, :login, :remember_me, :otp_attempt])
end
def hexdigest(string)
@@ -263,7 +263,7 @@ class ApplicationController < ActionController::Base
# internal repos where you are not a member. Enable this filter
# or improve current implementation to filter only issues you
# created or assigned or mentioned
- #@filter_params[:authorized_only] = true
+ # @filter_params[:authorized_only] = true
end
@filter_params
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index eb0abc80ab4..3865b2d61fd 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -31,6 +31,24 @@ class AutocompleteController < ApplicationController
render json: @user, only: [:name, :username, :id], methods: [:avatar_url]
end
+ def projects
+ project = Project.find_by_id(params[:project_id])
+
+ projects = current_user.authorized_projects
+ projects = projects.select do |project|
+ current_user.can?(:admin_issue, project)
+ end
+
+ no_project = {
+ id: 0,
+ name_with_namespace: 'No project',
+ }
+ projects.unshift(no_project)
+ projects.delete(project)
+
+ render json: projects.to_json(only: [:id, :name_with_namespace], methods: :name_with_namespace)
+ end
+
private
def find_users
diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb
index 156ab2811d6..cee3b6c43e7 100644
--- a/app/controllers/jwt_controller.rb
+++ b/app/controllers/jwt_controller.rb
@@ -32,7 +32,7 @@ class JwtController < ApplicationController
end
def auth_params
- params.permit(:service, :scope, :offline_token, :account, :client_id)
+ params.permit(:service, :scope, :account, :client_id)
end
def authenticate_project(login, password)
diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb
index df98f56a1cd..f35d631df0c 100644
--- a/app/controllers/omniauth_callbacks_controller.rb
+++ b/app/controllers/omniauth_callbacks_controller.rb
@@ -97,7 +97,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
handle_signup_error
end
- def handle_service_ticket provider, ticket
+ def handle_service_ticket(provider, ticket)
Gitlab::OAuth::Session.create provider, ticket
session[:service_tickets] ||= {}
session[:service_tickets][provider] = ticket
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index be872a93fee..776ba92c9ab 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -26,7 +26,7 @@ class Projects::ApplicationController < ApplicationController
project_path = "#{namespace}/#{id}"
@project = Project.find_with_namespace(project_path)
- if @project && can?(current_user, :read_project, @project)
+ if can?(current_user, :read_project, @project) && !@project.pending_delete?
if @project.path_with_namespace != project_path
redirect_to request.original_url.gsub(project_path, @project.path_with_namespace)
end
diff --git a/app/controllers/projects/find_file_controller.rb b/app/controllers/projects/find_file_controller.rb
index 54a0c447aee..cf53ad0a670 100644
--- a/app/controllers/projects/find_file_controller.rb
+++ b/app/controllers/projects/find_file_controller.rb
@@ -1,26 +1,26 @@
-# Controller for viewing a repository's file structure
-class Projects::FindFileController < Projects::ApplicationController
- include ExtractsPath
- include ActionView::Helpers::SanitizeHelper
- include TreeHelper
-
- before_action :require_non_empty_project
- before_action :assign_ref_vars
- before_action :authorize_download_code!
-
- def show
- return render_404 unless @repository.commit(@ref)
-
- respond_to do |format|
- format.html
- end
- end
-
- def list
- file_paths = @repo.ls_files(@ref)
-
- respond_to do |format|
- format.json { render json: file_paths }
- end
- end
-end
+# Controller for viewing a repository's file structure
+class Projects::FindFileController < Projects::ApplicationController
+ include ExtractsPath
+ include ActionView::Helpers::SanitizeHelper
+ include TreeHelper
+
+ before_action :require_non_empty_project
+ before_action :assign_ref_vars
+ before_action :authorize_download_code!
+
+ def show
+ return render_404 unless @repository.commit(@ref)
+
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ def list
+ file_paths = @repo.ls_files(@ref)
+
+ respond_to do |format|
+ format.json { render json: file_paths }
+ end
+ end
+end
diff --git a/app/controllers/projects/hooks_controller.rb b/app/controllers/projects/hooks_controller.rb
index 47524b1cf0b..a60027ff477 100644
--- a/app/controllers/projects/hooks_controller.rb
+++ b/app/controllers/projects/hooks_controller.rb
@@ -63,7 +63,8 @@ class Projects::HooksController < Projects::ApplicationController
:push_events,
:tag_push_events,
:token,
- :url
+ :url,
+ :wiki_page_events
)
end
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index f137c12d215..d54284d7b20 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -205,7 +205,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def branch_from
- #This is always source
+ # This is always source
@source_project = @merge_request.nil? ? @project : @merge_request.source_project
@commit = @repository.commit(params[:ref]) if params[:ref].present?
render layout: false
@@ -229,6 +229,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
if ci_commit
status = ci_commit.status
coverage = ci_commit.try(:coverage)
+
+ status ||= "preparing"
else
ci_service = @merge_request.source_project.ci_service
status = ci_service.commit_status(merge_request.last_commit.sha, merge_request.source_branch) if ci_service
@@ -238,8 +240,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
- status = "preparing" if status.nil?
-
response = {
title: merge_request.title,
sha: merge_request.last_commit_short_sha,
diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb
index 0d6c32fabd2..4b404eb03fa 100644
--- a/app/controllers/projects/wikis_controller.rb
+++ b/app/controllers/projects/wikis_controller.rb
@@ -91,8 +91,8 @@ class Projects::WikisController < Projects::ApplicationController
def markdown_preview
text = params[:text]
- ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user)
- ext.analyze(text)
+ ext = Gitlab::ReferenceExtractor.new(@project, current_user)
+ ext.analyze(text, author: current_user)
render json: {
body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki),
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 9697b88c032..f94e2a84fa2 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -197,8 +197,8 @@ class ProjectsController < Projects::ApplicationController
def markdown_preview
text = params[:text]
- ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user)
- ext.analyze(text)
+ ext = Gitlab::ReferenceExtractor.new(@project, current_user)
+ ext.analyze(text, author: current_user)
render json: {
body: view_context.markdown(text),
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index c29f4609e93..d68c2a708e3 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -1,5 +1,6 @@
class SessionsController < Devise::SessionsController
include AuthenticatesWithTwoFactor
+ include Devise::Controllers::Rememberable
include Recaptcha::ClientHelper
skip_before_action :check_2fa_requirement, only: [:destroy]
@@ -96,6 +97,7 @@ class SessionsController < Devise::SessionsController
# Remove any lingering user data from login
session.delete(:otp_user_id)
+ remember_me(user) if user_params[:remember_me] == '1'
sign_in(user) and return
else
flash.now[:alert] = 'Invalid two-factor code.'
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 799421c185b..a99632454d9 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -74,8 +74,6 @@ class UsersController < ApplicationController
def calendar
calendar = contributions_calendar
@timestamps = calendar.timestamps
- @starting_year = calendar.starting_year
- @starting_month = calendar.starting_month
render 'calendar', layout: false
end
diff --git a/app/finders/group_projects_finder.rb b/app/finders/group_projects_finder.rb
index 3b9a421b118..aa8f4c1d0e4 100644
--- a/app/finders/group_projects_finder.rb
+++ b/app/finders/group_projects_finder.rb
@@ -18,7 +18,7 @@ class GroupProjectsFinder < UnionFinder
projects = []
if current_user
- if @group.users.include?(current_user)
+ if @group.users.include?(current_user) || current_user.admin?
projects << @group.projects unless only_shared
projects << @group.shared_projects unless only_owned
else
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 5849e00662b..7d8c56f4c22 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -250,12 +250,12 @@ class IssuableFinder
def by_milestone(items)
if milestones?
if filter_by_no_milestone?
- items = items.where(milestone_id: [-1, nil])
+ items = items.left_joins_milestones.where(milestone_id: [-1, nil])
elsif filter_by_upcoming_milestone?
upcoming_ids = Milestone.upcoming_ids_by_projects(projects)
- items = items.joins(:milestone).where(milestone_id: upcoming_ids)
+ items = items.left_joins_milestones.where(milestone_id: upcoming_ids)
else
- items = items.joins(:milestone).where(milestones: { title: params[:milestone_title] })
+ items = items.with_milestone(params[:milestone_title])
if projects
items = items.where(milestones: { project_id: projects })
@@ -271,7 +271,7 @@ class IssuableFinder
if filter_by_no_label?
items = items.without_label
else
- items = items.with_label(label_names)
+ items = items.with_label(label_names, params[:sort])
if projects
items = items.where(labels: { project_id: projects })
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index e6e2546b92f..439b015b3b8 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -262,6 +262,8 @@ module ApplicationHelper
assignee_id: params[:assignee_id],
author_id: params[:author_id],
sort: params[:sort],
+ issue_search: params[:issue_search],
+ label_name: params[:label_name]
}
options = exist_opts.merge(options)
@@ -272,16 +274,11 @@ module ApplicationHelper
end
end
- path = request.path
- path << "?#{options.to_param}"
- if add_label
- if params[:label_name].present? and params[:label_name].respond_to?('any?')
- params[:label_name].each do |label|
- path << "&label_name[]=#{label}"
- end
- end
- end
- path
+ params = options.compact
+
+ params.delete(:label_name) unless add_label
+
+ "#{request.path}?#{params.to_param}"
end
def outdated_browser?
diff --git a/app/helpers/button_helper.rb b/app/helpers/button_helper.rb
index a9047ede8c5..f742922d926 100644
--- a/app/helpers/button_helper.rb
+++ b/app/helpers/button_helper.rb
@@ -30,7 +30,7 @@ module ButtonHelper
content_tag :a, protocol,
class: klass,
- href: @project.http_url_to_repo,
+ href: project.http_url_to_repo,
data: {
html: true,
placement: 'right',
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index b59c3982edd..d328f56c80c 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -123,13 +123,14 @@ module CommitsHelper
)
end
- def revert_commit_link(commit, continue_to_path, btn_class: nil)
+ def revert_commit_link(commit, continue_to_path, btn_class: nil, has_tooltip: true)
return unless current_user
- tooltip = "Revert this #{commit.change_type_title} in a new merge request"
+ tooltip = "Revert this #{commit.change_type_title} in a new merge request" if has_tooltip
if can_collaborate_with_project?
- link_to 'Revert', '#modal-revert-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class} has-tooltip"
+ btn_class = "btn btn-grouped btn-close btn-#{btn_class}" unless btn_class.nil?
+ link_to 'Revert', '#modal-revert-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: (tooltip if has_tooltip), class: "#{btn_class} #{'has-tooltip' if has_tooltip}"
elsif can?(current_user, :fork_project, @project)
continue_params = {
to: continue_to_path,
@@ -140,17 +141,20 @@ module CommitsHelper
namespace_key: current_user.namespace.id,
continue: continue_params)
- link_to 'Revert', fork_path, class: 'btn btn-grouped btn-close', method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: tooltip
+ btn_class = "btn btn-grouped btn-close" unless btn_class.nil?
+
+ link_to 'Revert', fork_path, class: btn_class, method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: (tooltip if has_tooltip)
end
end
- def cherry_pick_commit_link(commit, continue_to_path, btn_class: nil)
+ def cherry_pick_commit_link(commit, continue_to_path, btn_class: nil, has_tooltip: true)
return unless current_user
tooltip = "Cherry-pick this #{commit.change_type_title} in a new merge request"
if can_collaborate_with_project?
- link_to 'Cherry-pick', '#modal-cherry-pick-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class} has-tooltip"
+ btn_class = "btn btn-default btn-grouped btn-#{btn_class}" unless btn_class.nil?
+ link_to 'Cherry-pick', '#modal-cherry-pick-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: (tooltip if has_tooltip), class: "#{btn_class} #{'has-tooltip' if has_tooltip}"
elsif can?(current_user, :fork_project, @project)
continue_params = {
to: continue_to_path,
@@ -161,7 +165,8 @@ module CommitsHelper
namespace_key: current_user.namespace.id,
continue: continue_params)
- link_to 'Cherry-pick', fork_path, class: 'btn btn-grouped btn-close', method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: tooltip
+ btn_class = "btn btn-grouped btn-close" unless btn_class.nil?
+ link_to 'Cherry-pick', fork_path, class: "#{btn_class}", method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: (tooltip if has_tooltip)
end
end
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index ea383f9b0f6..cbe47176831 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -39,11 +39,11 @@ module DiffHelper
end
def unfold_bottom_class(bottom)
- (bottom) ? 'js-unfold-bottom' : ''
+ bottom ? 'js-unfold-bottom' : ''
end
def unfold_class(unfold)
- (unfold) ? 'unfold js-unfold' : ''
+ unfold ? 'unfold js-unfold' : ''
end
def diff_line_content(line, line_type = nil)
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index e1489381706..bfedcb1c42b 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -159,28 +159,6 @@ module EventsHelper
"--broken encoding"
end
- def event_to_atom(xml, event)
- if event.visible_to_user?(current_user)
- xml.entry do
- event_link = event_feed_url(event)
- event_title = event_feed_title(event)
- event_summary = event_feed_summary(event)
-
- xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}"
- xml.link href: event_link
- xml.title truncate(event_title, length: 80)
- xml.updated event.created_at.xmlschema
- xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(event.author_email))
- xml.author do |author|
- xml.name event.author_name
- xml.email event.author_email
- end
-
- xml.summary(type: "xhtml") { |x| x << event_summary unless event_summary.nil? }
- end
- end
- end
-
def event_row_class(event)
if event.body?
"event-block"
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index b1f0a765bb9..4cac69c6795 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -31,7 +31,7 @@ module GroupsHelper
if group && group.avatar.present?
group.avatar.url
else
- 'no_group_avatar.png'
+ image_path('no_group_avatar.png')
end
end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 39474217286..fe84ee3de44 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -50,14 +50,10 @@ module IssuablesHelper
end
def user_dropdown_label(user_id, default_label)
+ return default_label if user_id.nil?
return "Unassigned" if user_id == "0"
- if @project
- member = @project.team.find_member(user_id)
- user = member.user if member
- else
- user = User.find_by(id: user_id)
- end
+ user = User.find_by(id: user_id)
if user
user.name
@@ -76,7 +72,7 @@ module IssuablesHelper
def issuable_meta(issuable, project, text)
output = content_tag :strong, "#{text} #{issuable.to_reference}", class: "identifier"
- output << " opened #{time_ago_with_tooltip(issuable.created_at)} by".html_safe
+ 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")
author_output << link_to_member(project, issuable.author, size: 24, by_username: true, avatar: false, mobile_classes: "hidden-sm hidden-md hidden-lg")
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 198d39455d7..173bdbb8654 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -105,23 +105,6 @@ module IssuesHelper
return 'hidden' if issue.closed? == closed
end
- def issue_to_atom(xml, issue)
- xml.entry do
- xml.id namespace_project_issue_url(issue.project.namespace,
- issue.project, issue)
- xml.link href: namespace_project_issue_url(issue.project.namespace,
- issue.project, issue)
- xml.title truncate(issue.title, length: 80)
- xml.updated issue.created_at.xmlschema
- xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(issue.author_email))
- xml.author do |author|
- xml.name issue.author_name
- xml.email issue.author_email
- end
- xml.summary issue.title
- end
- end
-
def merge_requests_sentence(merge_requests)
# Sorting based on the `!123` or `group/project!123` reference will sort
# local merge requests first.
@@ -164,8 +147,8 @@ module IssuesHelper
def emoji_author_list(notes, current_user)
list = notes.map do |note|
- note.author == current_user ? "me" : note.author.name
- end
+ note.author == current_user ? "me" : note.author.name
+ end
list.join(", ")
end
diff --git a/app/helpers/javascript_helper.rb b/app/helpers/javascript_helper.rb
new file mode 100644
index 00000000000..91dd91718dc
--- /dev/null
+++ b/app/helpers/javascript_helper.rb
@@ -0,0 +1,7 @@
+module JavascriptHelper
+ def page_specific_javascripts(js = nil)
+ @page_specific_javascripts = js unless js.nil?
+
+ @page_specific_javascripts
+ end
+end
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index fbb799eecd3..f685e547537 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -48,7 +48,7 @@ module NavHelper
"page-with-layout-nav" if defined?(nav) && nav
end
- def layout_dropdown_class
- "controls-dropdown-visible" if current_user
+ def nav_control_class
+ "nav-control" if current_user
end
end
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 81b9b5d7052..b9d7edb4185 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -37,6 +37,16 @@ module TodosHelper
end
end
+ def todo_target_state_pill(todo)
+ return unless show_todo_state?(todo)
+
+ content_tag(:span, nil, class: 'target-status') do
+ content_tag(:span, nil, class: "status-box status-box-#{todo.target.state.dasherize}") do
+ todo.target.state.capitalize
+ end
+ end
+ end
+
def todos_filter_params
{
state: params[:state],
@@ -95,4 +105,10 @@ module TodosHelper
options_from_collection_for_select(types, 'name', 'title', params[:type])
end
+
+ private
+
+ def show_todo_state?(todo)
+ (todo.target.is_a?(MergeRequest) || todo.target.is_a?(Issue)) && ['closed', 'merged'].include?(todo.target.state)
+ end
end
diff --git a/app/mailers/devise_mailer.rb b/app/mailers/devise_mailer.rb
index b616add283a..415f6e12885 100644
--- a/app/mailers/devise_mailer.rb
+++ b/app/mailers/devise_mailer.rb
@@ -1,4 +1,6 @@
class DeviseMailer < Devise::Mailer
default from: "#{Gitlab.config.gitlab.email_display_name} <#{Gitlab.config.gitlab.email_from}>"
default reply_to: Gitlab.config.gitlab.email_reply_to
+
+ layout 'devise_mailer'
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index b354b1990c7..44515550d9e 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -23,20 +23,41 @@ class Ability
end.concat(global_abilities(user))
end
+ # Given a list of users and a project this method returns the users that can
+ # read the given project.
+ def users_that_can_read_project(users, project)
+ if project.public?
+ users
+ else
+ users.select do |user|
+ if user.admin?
+ true
+ elsif project.internal? && !user.external?
+ true
+ elsif project.owner == user
+ true
+ elsif project.team.members.include?(user)
+ true
+ else
+ false
+ end
+ end
+ end
+ end
+
# List of possible abilities for anonymous user
def anonymous_abilities(user, subject)
- case true
- when subject.is_a?(PersonalSnippet)
+ if subject.is_a?(PersonalSnippet)
anonymous_personal_snippet_abilities(subject)
- when subject.is_a?(ProjectSnippet)
+ elsif subject.is_a?(ProjectSnippet)
anonymous_project_snippet_abilities(subject)
- when subject.is_a?(CommitStatus)
+ elsif subject.is_a?(CommitStatus)
anonymous_commit_status_abilities(subject)
- when subject.is_a?(Project) || subject.respond_to?(:project)
+ elsif subject.is_a?(Project) || subject.respond_to?(:project)
anonymous_project_abilities(subject)
- when subject.is_a?(Group) || subject.respond_to?(:group)
+ elsif subject.is_a?(Group) || subject.respond_to?(:group)
anonymous_group_abilities(subject)
- when subject.is_a?(User)
+ elsif subject.is_a?(User)
anonymous_user_abilities
else
[]
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 9a14954b4a7..42f908aa344 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -51,6 +51,10 @@ class ApplicationSetting < ActiveRecord::Base
presence: true,
numericality: { only_integer: true, greater_than: 0 }
+ validates :container_registry_token_expire_delay,
+ presence: true,
+ numericality: { only_integer: true, greater_than: 0 }
+
validates_each :restricted_visibility_levels do |record, attr, value|
unless value.nil?
value.each do |level|
@@ -98,6 +102,10 @@ class ApplicationSetting < ActiveRecord::Base
Rails.cache.delete(CACHE_KEY)
end
+ def self.cached
+ Rails.cache.fetch(CACHE_KEY)
+ end
+
def self.create_from_defaults
create(
default_projects_limit: Settings.gitlab['default_projects_limit'],
@@ -121,7 +129,8 @@ class ApplicationSetting < ActiveRecord::Base
akismet_enabled: false,
repository_checks_enabled: true,
disabled_oauth_sign_in_sources: [],
- send_user_confirmation_email: false
+ send_user_confirmation_email: false,
+ container_registry_token_expire_delay: 5,
)
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index ff7dd44c526..5e77fda70b9 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -286,7 +286,7 @@ module Ci
project.runners_token
end
- def valid_token? token
+ def valid_token?(token)
project.valid_runners_token? token
end
diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb
index 6675a3f5d53..f22b573a94c 100644
--- a/app/models/ci/commit.rb
+++ b/app/models/ci/commit.rb
@@ -66,6 +66,10 @@ module Ci
end
end
+ def cancelable?
+ builds.running_or_pending.any?
+ end
+
def cancel_running
builds.running_or_pending.each(&:cancel)
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 6829dc91cb9..adb65292208 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -60,7 +60,7 @@ module Ci
end
def display_name
- return short_sha unless !description.blank?
+ return short_sha if description.blank?
description
end
diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb
index 10802f64813..f8d5d4486fd 100644
--- a/app/models/ci/variable.rb
+++ b/app/models/ci/variable.rb
@@ -11,6 +11,9 @@ module Ci
format: { with: /\A[a-zA-Z0-9_]+\z/,
message: "can contain only letters, digits and '_'." }
- attr_encrypted :value, mode: :per_attribute_iv_and_salt, key: Gitlab::Application.secrets.db_key_base
+ attr_encrypted :value,
+ mode: :per_attribute_iv_and_salt,
+ key: Gitlab::Application.secrets.db_key_base,
+ algorithm: 'aes-256-cbc'
end
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index 562c3ed15b2..f96c7cb34d0 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -8,7 +8,10 @@ class Commit
include StaticModel
attr_mentionable :safe_message, pipeline: :single_line
- participant :author, :committer, :notes
+
+ participant :author
+ participant :committer
+ participant :notes_with_associations
attr_accessor :project
@@ -194,6 +197,10 @@ class Commit
project.notes.for_commit_id(self.id)
end
+ def notes_with_associations
+ notes.includes(:author, :project)
+ end
+
def method_missing(m, *args, &block)
@raw.send(m, *args, &block)
end
@@ -219,7 +226,7 @@ class Commit
def revert_branch_name
"revert-#{short_id}"
end
-
+
def cherry_pick_branch_name
project.repository.next_branch("cherry-pick-#{short_id}", mild: true)
end
@@ -251,11 +258,13 @@ class Commit
end
def has_been_reverted?(current_user = nil, noteable = self)
- Gitlab::ReferenceExtractor.lazily do
- noteable.notes.system.flat_map do |note|
- note.all_references(current_user).commits
- end
- end.any? { |commit_ref| commit_ref.reverts_commit?(self) }
+ ext = all_references(current_user)
+
+ noteable.notes_with_associations.system.each do |note|
+ note.all_references(current_user, extractor: ext)
+ end
+
+ ext.commits.any? { |commit_ref| commit_ref.reverts_commit?(self) }
end
def change_type_title
diff --git a/app/models/commit_range.rb b/app/models/commit_range.rb
index 51673897d98..4066958f67c 100644
--- a/app/models/commit_range.rb
+++ b/app/models/commit_range.rb
@@ -62,7 +62,7 @@ class CommitRange
def initialize(range_string, project)
@project = project
- range_string.strip!
+ range_string = range_string.strip
unless range_string =~ /\A#{PATTERN}\z/
raise ArgumentError, "invalid CommitRange string format: #{range_string}"
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index c1248b53031..2326a395cb8 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -31,18 +31,21 @@ module Issuable
scope :unassigned, -> { where("assignee_id IS NULL") }
scope :of_projects, ->(ids) { where(project_id: ids) }
scope :of_milestones, ->(ids) { where(milestone_id: ids) }
+ scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) }
scope :opened, -> { with_state(:opened, :reopened) }
scope :only_opened, -> { with_state(:opened) }
scope :only_reopened, -> { with_state(:reopened) }
scope :closed, -> { with_state(:closed) }
- scope :order_milestone_due_desc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date DESC, milestones.id DESC') }
- scope :order_milestone_due_asc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date ASC, milestones.id ASC') }
- scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
+ scope :left_joins_milestones, -> { joins("LEFT OUTER JOIN milestones ON #{table_name}.milestone_id = milestones.id") }
+ scope :order_milestone_due_desc, -> { left_joins_milestones.reorder('milestones.due_date IS NULL, milestones.id IS NULL, milestones.due_date DESC') }
+ scope :order_milestone_due_asc, -> { left_joins_milestones.reorder('milestones.due_date IS NULL, milestones.id IS NULL, milestones.due_date ASC') }
+
+ scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
scope :join_project, -> { joins(:project) }
scope :references_project, -> { references(:project) }
scope :non_archived, -> { join_project.where(projects: { archived: false }) }
- scope :outer_join_milestone, -> { joins("LEFT OUTER JOIN milestones ON milestones.id = #{table_name}.milestone_id") }
+
delegate :name,
:email,
@@ -56,8 +59,12 @@ module Issuable
prefix: true
attr_mentionable :title, pipeline: :single_line
- attr_mentionable :description, cache: true
- participant :author, :assignee, :notes_with_associations
+ attr_mentionable :description
+
+ participant :author
+ participant :assignee
+ participant :notes_with_associations
+
strip_attributes :title
acts_as_paranoid
@@ -123,13 +130,29 @@ module Issuable
joins(join_clause).group(issuable_table[:id]).reorder("COUNT(notes.id) DESC")
end
- def with_label(title)
+ def with_label(title, sort = nil)
if title.is_a?(Array) && title.size > 1
- joins(:labels).where(labels: { title: title }).group(arel_table[:id]).having("COUNT(DISTINCT labels.title) = #{title.size}")
+ joins(:labels).where(labels: { title: title }).group(*grouping_columns(sort)).having("COUNT(DISTINCT labels.title) = #{title.size}")
else
joins(:labels).where(labels: { title: title })
end
end
+
+ # Includes table keys in group by clause when sorting
+ # preventing errors in postgres
+ #
+ # Returns an array of arel columns
+ def grouping_columns(sort)
+ grouping_columns = [arel_table[:id]]
+
+ if ["milestone_due_desc", "milestone_due_asc"].include?(sort)
+ milestone_table = Milestone.arel_table
+ grouping_columns << milestone_table[:id]
+ grouping_columns << milestone_table[:due_date]
+ end
+
+ grouping_columns
+ end
end
def today?
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index b381d225485..f00b5b8497c 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -23,7 +23,7 @@ module Mentionable
included do
if self < Participable
- participant ->(current_user) { mentioned_users(current_user) }
+ participant -> (user, ext) { all_references(user, extractor: ext) }
end
end
@@ -43,23 +43,22 @@ module Mentionable
self
end
- def all_references(current_user = nil, text = nil)
- ext = Gitlab::ReferenceExtractor.new(self.project, current_user || self.author, self.author)
+ def all_references(current_user = nil, text = nil, extractor: nil)
+ extractor ||= Gitlab::ReferenceExtractor.
+ new(project, current_user || author)
if text
- ext.analyze(text)
+ extractor.analyze(text, author: author)
else
self.class.mentionable_attrs.each do |attr, options|
- text = send(attr)
+ text = __send__(attr)
+ options = options.merge(cache_key: [self, attr], author: author)
- context = options.dup
- context[:cache_key] = [self, attr] if context.delete(:cache) && self.persisted?
-
- ext.analyze(text, context)
+ extractor.analyze(text, options)
end
end
- ext
+ extractor
end
def mentioned_users(current_user = nil)
diff --git a/app/models/concerns/participable.rb b/app/models/concerns/participable.rb
index fc6f83b918b..9056722f45e 100644
--- a/app/models/concerns/participable.rb
+++ b/app/models/concerns/participable.rb
@@ -3,8 +3,6 @@
# Contains functionality related to objects that can have participants, such as
# an author, an assignee and people mentioned in its description or comments.
#
-# Used by Issue, Note, MergeRequest, Snippet and Commit.
-#
# Usage:
#
# class Issue < ActiveRecord::Base
@@ -12,22 +10,36 @@
#
# # ...
#
-# participant :author, :assignee, :notes, ->(current_user) { mentioned_users(current_user) }
+# participant :author
+# participant :assignee
+# participant :notes
+#
+# participant -> (current_user, ext) do
+# ext.analyze('...')
+# end
# end
#
# issue = Issue.last
# users = issue.participants
-# # `users` will contain the issue's author, its assignee,
-# # all users returned by its #mentioned_users method,
-# # as well as all participants to all of the issue's notes,
-# # since Note implements Participable as well.
-#
module Participable
extend ActiveSupport::Concern
module ClassMethods
- def participant(*attrs)
- participant_attrs.concat(attrs)
+ # Adds a list of participant attributes. Attributes can either be symbols or
+ # Procs.
+ #
+ # When using a Proc instead of a Symbol the Proc will be given two
+ # arguments:
+ #
+ # 1. The current user (as an instance of User)
+ # 2. An instance of `Gitlab::ReferenceExtractor`
+ #
+ # It is expected that a Proc populates the given reference extractor
+ # instance with data. The return value of the Proc is ignored.
+ #
+ # attr - The name of the attribute or a Proc
+ def participant(attr)
+ participant_attrs << attr
end
def participant_attrs
@@ -35,42 +47,42 @@ module Participable
end
end
- # Be aware that this method makes a lot of sql queries.
- # Save result into variable if you are going to reuse it inside same request
- def participants(current_user = self.author)
- participants =
- Gitlab::ReferenceExtractor.lazily do
- self.class.participant_attrs.flat_map do |attr|
- value =
- if attr.respond_to?(:call)
- instance_exec(current_user, &attr)
- else
- send(attr)
- end
+ # Returns the users participating in a discussion.
+ #
+ # This method processes attributes of objects in breadth-first order.
+ #
+ # Returns an Array of User instances.
+ def participants(current_user = nil)
+ current_user ||= author
+ ext = Gitlab::ReferenceExtractor.new(project, current_user)
+ participants = Set.new
+ process = [self]
- participants_for(value, current_user)
- end.compact.uniq
- end
+ until process.empty?
+ source = process.pop
- unless Gitlab::ReferenceExtractor.lazy?
- participants.select! do |user|
- user.can?(:read_project, project)
+ case source
+ when User
+ participants << source
+ when Participable
+ source.class.participant_attrs.each do |attr|
+ if attr.respond_to?(:call)
+ source.instance_exec(current_user, ext, &attr)
+ else
+ process << source.__send__(attr)
+ end
+ end
+ when Enumerable, ActiveRecord::Relation
+ # This uses reverse_each so we can use "pop" to get the next value to
+ # process (in order). Using unshift instead of pop would require
+ # moving all Array values one index to the left (which can be
+ # expensive).
+ source.reverse_each { |obj| process << obj }
end
end
- participants
- end
-
- private
+ participants.merge(ext.users)
- def participants_for(value, current_user = nil)
- case value
- when User, Banzai::LazyReference
- [value]
- when Enumerable, ActiveRecord::Relation
- value.flat_map { |v| participants_for(v, current_user) }
- when Participable
- value.participants(current_user)
- end
+ Ability.users_that_can_read_project(participants.to_a, project)
end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 2d4a9b9f19a..bd0fbc96d18 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -95,14 +95,13 @@ class Issue < ActiveRecord::Base
end
def referenced_merge_requests(current_user = nil)
- @referenced_merge_requests ||= {}
- @referenced_merge_requests[current_user] ||= begin
- Gitlab::ReferenceExtractor.lazily do
- [self, *notes].flat_map do |note|
- note.all_references(current_user).merge_requests
- end
- end.sort_by(&:iid).uniq
+ ext = all_references(current_user)
+
+ notes_with_associations.each do |object|
+ object.all_references(current_user, extractor: ext)
end
+
+ ext.merge_requests.sort_by(&:iid)
end
# All branches containing the current issue's ID, except for
@@ -139,9 +138,13 @@ class Issue < ActiveRecord::Base
def closed_by_merge_requests(current_user = nil)
return [] unless open?
- notes.system.flat_map do |note|
- note.all_references(current_user).merge_requests
- end.uniq.select { |mr| mr.open? && mr.closes_issue?(self) }
+ ext = all_references(current_user)
+
+ notes.system.each do |note|
+ note.all_references(current_user, extractor: ext)
+ end
+
+ ext.merge_requests.select { |mr| mr.open? && mr.closes_issue?(self) }
end
def moved?
diff --git a/app/models/key.rb b/app/models/key.rb
index d52afda67d1..0532e84f47d 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -26,7 +26,7 @@ class Key < ActiveRecord::Base
end
def publishable_key
- #Removes anything beyond the keytype and key itself
+ # Removes anything beyond the keytype and key itself
self.key.split[0..1].join(' ')
end
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index 8dae3bb2ef2..46955b430f3 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -5,7 +5,6 @@ class ProjectMember < Member
belongs_to :project, class_name: 'Project', foreign_key: 'source_id'
-
# Make sure project member points only to project as it source
default_value_for :source_type, SOURCE_TYPE
validates_format_of :source_type, with: /\AProject\z/
@@ -15,6 +14,8 @@ class ProjectMember < Member
scope :in_projects, ->(projects) { where(source_id: projects.pluck(:id)) }
scope :with_user, ->(user) { where(user_id: user.id) }
+ before_destroy :delete_member_todos
+
class << self
# Add users to project teams with passed access option
@@ -102,6 +103,10 @@ class ProjectMember < Member
private
+ def delete_member_todos
+ user.todos.where(project_id: source_id).destroy_all if user
+ end
+
def send_invite
notification_service.invite_project_member(self, @raw_invite_token)
diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb
index 9259cb1a0fa..a2aee2f925b 100644
--- a/app/models/network/graph.rb
+++ b/app/models/network/graph.rb
@@ -22,9 +22,16 @@ module Network
def collect_notes
h = Hash.new(0)
- @project.notes.where('noteable_type = ?' ,"Commit").group('notes.commit_id').select('notes.commit_id, count(notes.id) as note_count').each do |item|
- h[item.commit_id] = item.note_count.to_i
- end
+
+ @project
+ .notes
+ .where('noteable_type = ?', 'Commit')
+ .group('notes.commit_id')
+ .select('notes.commit_id, count(notes.id) as note_count')
+ .each do |item|
+ h[item.commit_id] = item.note_count.to_i
+ end
+
h
end
@@ -89,7 +96,7 @@ module Network
end
end
- if self.class.max_count / 2 < offset then
+ if self.class.max_count / 2 < offset
# get max index that commit is displayed in the center.
offset - self.class.max_count / 2
else
@@ -130,7 +137,7 @@ module Network
commit.parents(@map).each do |parent|
range = commit.time..parent.time
- space = if commit.space >= parent.space then
+ space = if commit.space >= parent.space
find_free_parent_space(range, parent.space, -1, commit.space)
else
find_free_parent_space(range, commit.space, -1, parent.space)
@@ -144,7 +151,7 @@ module Network
end
def find_free_parent_space(range, space_base, space_step, space_default)
- if is_overlap?(range, space_default) then
+ if is_overlap?(range, space_default)
find_free_space(range, space_step, space_base, space_default)
else
space_default
@@ -155,9 +162,9 @@ module Network
range.each do |i|
if i != range.first &&
i != range.last &&
- @commits[i].spaces.include?(overlap_space) then
+ @commits[i].spaces.include?(overlap_space)
- return true;
+ return true
end
end
@@ -198,7 +205,7 @@ module Network
# Visit branching chains
leaves.each do |l|
parents = l.parents(@map).select{|p| p.space.zero?}
- for p in parents
+ parents.each do |p|
place_chain(p, l.time)
end
end
@@ -216,7 +223,7 @@ module Network
end
def mark_reserved(time_range, space)
- for day in time_range
+ time_range.each do |day|
@reserved[day].push(space)
end
end
@@ -225,15 +232,15 @@ module Network
space_default ||= space_base
reserved = []
- for day in time_range
+ time_range.each do |day|
reserved.push(*@reserved[day])
end
reserved.uniq!
space = space_default
- while reserved.include?(space) do
+ while reserved.include?(space)
space += space_step
- if space < space_base then
+ if space < space_base
space_step *= -1
space = space_base + space_step
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 55b98557244..c21981ead84 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -6,7 +6,7 @@ class Note < ActiveRecord::Base
default_value_for :system, false
- attr_mentionable :note, cache: true, pipeline: :note
+ attr_mentionable :note, pipeline: :note
participant :author
belongs_to :project
@@ -29,10 +29,17 @@ class Note < ActiveRecord::Base
# Attachments are deprecated and are handled by Markdown uploader
validates :attachment, file_size: { maximum: :max_attachment_size }
- validates :noteable_id, presence: true, if: ->(n) { n.noteable_type.present? && n.noteable_type != 'Commit' }
- validates :commit_id, presence: true, if: ->(n) { n.noteable_type == 'Commit' }
+ validates :noteable_type, presence: true
+ validates :noteable_id, presence: true, unless: :for_commit?
+ validates :commit_id, presence: true, if: :for_commit?
validates :author, presence: true
+ validate unless: :for_commit? do |note|
+ unless note.noteable.try(:project) == note.project
+ errors.add(:invalid_project, 'Note and noteable project mismatch')
+ end
+ end
+
mount_uploader :attachment, AttachmentUploader
# Scopes
@@ -77,14 +84,30 @@ class Note < ActiveRecord::Base
#
# This method uses ILIKE on PostgreSQL and LIKE on MySQL.
#
- # query - The search query as a String.
+ # query - The search query as a String.
+ # as_user - Limit results to those viewable by a specific user
#
# Returns an ActiveRecord::Relation.
- def search(query)
+ def search(query, as_user: nil)
table = arel_table
pattern = "%#{query}%"
- where(table[:note].matches(pattern))
+ found_notes = joins('LEFT JOIN issues ON issues.id = noteable_id').
+ where(table[:note].matches(pattern))
+
+ if as_user
+ found_notes.where('
+ issues.confidential IS NULL
+ OR issues.confidential IS FALSE
+ OR (issues.confidential IS TRUE
+ AND (issues.author_id = :user_id
+ OR issues.assignee_id = :user_id
+ OR issues.project_id IN(:project_ids)))',
+ user_id: as_user.id,
+ project_ids: as_user.authorized_projects.select(:id))
+ else
+ found_notes.where('issues.confidential IS NULL OR issues.confidential IS FALSE')
+ end
end
def grouped_awards
diff --git a/app/models/project.rb b/app/models/project.rb
index 37de1dfe4d5..525a82c7534 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -309,21 +309,25 @@ class Project < ActiveRecord::Base
@repository ||= Repository.new(path_with_namespace, self)
end
+ def container_registry_path_with_namespace
+ path_with_namespace.downcase
+ end
+
def container_registry_repository
return unless Gitlab.config.registry.enabled
@container_registry_repository ||= begin
- token = Auth::ContainerRegistryAuthenticationService.full_access_token(path_with_namespace)
+ token = Auth::ContainerRegistryAuthenticationService.full_access_token(container_registry_path_with_namespace)
url = Gitlab.config.registry.api_url
host_port = Gitlab.config.registry.host_port
registry = ContainerRegistry::Registry.new(url, token: token, path: host_port)
- registry.repository(path_with_namespace)
+ registry.repository(container_registry_path_with_namespace)
end
end
def container_registry_repository_url
if Gitlab.config.registry.enabled
- "#{Gitlab.config.registry.host_port}/#{path_with_namespace}"
+ "#{Gitlab.config.registry.host_port}/#{container_registry_path_with_namespace}"
end
end
@@ -431,7 +435,13 @@ class Project < ActiveRecord::Base
def check_limit
unless creator.can_create_project? or namespace.kind == 'group'
- self.errors.add(:limit_reached, "Your project limit is #{creator.projects_limit} projects! Please contact your administrator to increase it")
+ projects_limit = creator.projects_limit
+
+ if projects_limit == 0
+ self.errors.add(:limit_reached, "Personal project creation is not allowed. Please contact your administrator with questions")
+ else
+ self.errors.add(:limit_reached, "Your project limit is #{projects_limit} projects! Please contact your administrator to increase it")
+ end
end
rescue
self.errors.add(:base, "Can't check your ability to create project")
@@ -940,13 +950,13 @@ class Project < ActiveRecord::Base
shared_runners_enabled? && Ci::Runner.shared.active.any?(&block)
end
- def valid_runners_token? token
+ def valid_runners_token?(token)
self.runners_token && ActiveSupport::SecurityUtils.variable_size_secure_compare(token, self.runners_token)
end
# TODO (ayufan): For now we use runners_token (backward compatibility)
# In 8.4 every build will have its own individual token valid for time of build
- def valid_build_token? token
+ def valid_build_token?(token)
self.builds_enabled? && self.runners_token && ActiveSupport::SecurityUtils.variable_size_secure_compare(token, self.runners_token)
end
diff --git a/app/models/project_import_data.rb b/app/models/project_import_data.rb
index e2f9ffb69ac..ca8a9b4217b 100644
--- a/app/models/project_import_data.rb
+++ b/app/models/project_import_data.rb
@@ -6,7 +6,8 @@ class ProjectImportData < ActiveRecord::Base
key: Gitlab::Application.secrets.db_key_base,
marshal: true,
encode: true,
- mode: :per_attribute_iv_and_salt
+ mode: :per_attribute_iv_and_salt,
+ algorithm: 'aes-256-cbc'
serialize :data, JSON
diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb
index 91015e6c9b1..2e5e854fc5e 100644
--- a/app/models/project_services/irker_service.rb
+++ b/app/models/project_services/irker_service.rb
@@ -70,7 +70,7 @@ class IrkerService < Service
private
def get_channels
- return true unless :activated?
+ return true unless activated?
return true if recipients.nil? || recipients.empty?
map_recipients
diff --git a/app/models/project_services/slack_service/build_message.rb b/app/models/project_services/slack_service/build_message.rb
index c124cad4afd..69c21b3fc38 100644
--- a/app/models/project_services/slack_service/build_message.rb
+++ b/app/models/project_services/slack_service/build_message.rb
@@ -35,8 +35,8 @@ class SlackService
private
def message
- "#{project_link}: Commit #{commit_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status} in #{duration} second(s)"
- end
+ "#{project_link}: Commit #{commit_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status} in #{duration} #{'second'.pluralize(duration)}"
+ end
def format(string)
Slack::Notifier::LinkFormatter.format(string)
diff --git a/app/models/project_snippet.rb b/app/models/project_snippet.rb
index 5fba6baa204..25b5d777641 100644
--- a/app/models/project_snippet.rb
+++ b/app/models/project_snippet.rb
@@ -7,5 +7,6 @@ class ProjectSnippet < Snippet
# Scopes
scope :fresh, -> { order("created_at DESC") }
- participant :author, :notes
+ participant :author
+ participant :notes_with_associations
end
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb
index 339fb0b9f9d..25d82929c0b 100644
--- a/app/models/project_wiki.rb
+++ b/app/models/project_wiki.rb
@@ -27,6 +27,10 @@ class ProjectWiki
@project.path_with_namespace + ".wiki"
end
+ def web_url
+ Gitlab::Routing.url_helpers.namespace_project_wiki_url(@project.namespace, @project, :home)
+ end
+
def url_to_repo
gitlab_shell.url_to_repo(path_with_namespace)
end
@@ -142,6 +146,16 @@ class ProjectWiki
wiki
end
+ def hook_attrs
+ {
+ web_url: web_url,
+ git_ssh_url: ssh_url_to_repo,
+ git_http_url: http_url_to_repo,
+ path_with_namespace: path_with_namespace,
+ default_branch: default_branch
+ }
+ end
+
private
def init_repo(path_with_namespace)
diff --git a/app/models/repository.rb b/app/models/repository.rb
index ecc8795c954..1ab163510bf 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -972,12 +972,6 @@ class Repository
end
end
- def main_language
- return unless head_exists?
-
- Linguist::Repository.new(rugged, rugged.head.target_id).language
- end
-
def avatar
return nil unless exists?
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 0a3c3b57669..407697b745c 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -30,7 +30,8 @@ class Snippet < ActiveRecord::Base
scope :public_and_internal, -> { where(visibility_level: [Snippet::PUBLIC, Snippet::INTERNAL]) }
scope :fresh, -> { order("created_at DESC") }
- participant :author, :notes
+ participant :author
+ participant :notes_with_associations
def self.reference_prefix
'$'
@@ -100,6 +101,10 @@ class Snippet < ActiveRecord::Base
content.lines.count > 1000
end
+ def notes_with_associations
+ notes.includes(:author, :project)
+ end
+
class << self
# Searches for snippets with a matching title or file name.
#
diff --git a/app/models/user.rb b/app/models/user.rb
index 6a09b78455b..15b6cbc2255 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -20,6 +20,11 @@ class User < ActiveRecord::Base
default_value_for :hide_no_password, false
default_value_for :theme_id, gitlab_config.default_theme
+ attr_encrypted :otp_secret,
+ key: Gitlab::Application.config.secret_key_base,
+ mode: :per_attribute_iv_and_salt,
+ algorithm: 'aes-256-cbc'
+
devise :two_factor_authenticatable,
otp_secret_encryption_key: Gitlab::Application.config.secret_key_base
alias_attribute :two_factor_enabled, :otp_required_for_login
@@ -27,7 +32,7 @@ class User < ActiveRecord::Base
devise :two_factor_backupable, otp_number_of_backup_codes: 10
serialize :otp_backup_codes, JSON
- devise :lockable, :async, :recoverable, :rememberable, :trackable,
+ devise :lockable, :recoverable, :rememberable, :trackable,
:validatable, :omniauthable, :confirmable, :registerable
attr_accessor :force_random_password
diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb
index 2bbab643e69..e57b95f21ec 100644
--- a/app/services/auth/container_registry_authentication_service.rb
+++ b/app/services/auth/container_registry_authentication_service.rb
@@ -1,13 +1,13 @@
module Auth
class ContainerRegistryAuthenticationService < BaseService
+ include Gitlab::CurrentSettings
+
AUDIENCE = 'container_registry'
def execute
return error('not found', 404) unless registry.enabled
- if params[:offline_token]
- return error('unauthorized', 401) unless current_user || project
- else
+ unless current_user || project
return error('forbidden', 403) unless scope
end
@@ -19,6 +19,7 @@ module Auth
token = JSONWebToken::RSAToken.new(registry.key)
token.issuer = registry.issuer
token.audience = AUDIENCE
+ token.expire_time = token_expire_at
token[:access] = names.map do |name|
{ type: 'repository', name: name, actions: %w(*) }
end
@@ -32,6 +33,7 @@ module Auth
token.issuer = registry.issuer
token.audience = params[:service]
token.subject = current_user.try(:username)
+ token.expire_time = ContainerRegistryAuthenticationService.token_expire_at
token[:access] = accesses.compact
token
end
@@ -77,5 +79,9 @@ module Auth
def registry
Gitlab.config.registry
end
+
+ def self.token_expire_at
+ Time.now + current_application_settings.container_registry_token_expire_delay.minutes
+ end
end
end
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 66136b62617..a886f35981f 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -53,10 +53,6 @@ class GitPushService < BaseService
# could cause the last commit of a merge request to change.
update_merge_requests
- # Checks if the main language has changed in the project and if so
- # it updates it accordingly
- update_main_language
-
perform_housekeeping
end
@@ -64,19 +60,6 @@ class GitPushService < BaseService
@project.repository.copy_gitattributes(params[:ref])
end
- def update_main_language
- # Performance can be bad so for now only check main_language once
- # See https://gitlab.com/gitlab-org/gitlab-ce/issues/14937
- return if @project.main_language.present?
-
- return unless is_default_branch?
- return unless push_to_new_branch? || push_to_existing_branch?
-
- current_language = @project.repository.main_language
- @project.update_attributes(main_language: current_language)
- true
- end
-
protected
def update_merge_requests
diff --git a/app/services/git_tag_push_service.rb b/app/services/git_tag_push_service.rb
index 7410442609d..299a0a967b0 100644
--- a/app/services/git_tag_push_service.rb
+++ b/app/services/git_tag_push_service.rb
@@ -23,7 +23,7 @@ class GitTagPushService < BaseService
commits = []
message = nil
- if !Gitlab::Git.blank_ref?(params[:newrev])
+ unless Gitlab::Git.blank_ref?(params[:newrev])
tag_name = Gitlab::Git.ref_name(params[:ref])
tag = project.repository.find_tag(tag_name)
if tag && tag.target == params[:newrev]
diff --git a/app/services/notes/create_service.rb b/app/services/notes/create_service.rb
index 01586994813..2bb312bb252 100644
--- a/app/services/notes/create_service.rb
+++ b/app/services/notes/create_service.rb
@@ -5,8 +5,6 @@ module Notes
note.author = current_user
note.system = false
- return unless valid_project?(note)
-
if note.save
# Finish the harder work in the background
NewNoteWorker.perform_in(2.seconds, note.id, params)
@@ -15,14 +13,5 @@ module Notes
note
end
-
- private
-
- def valid_project?(note)
- return false unless project
- return true if note.for_commit?
-
- note.noteable.try(:project) == project
- end
end
end
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 0577ae778d5..de6dc38cc8e 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -3,7 +3,7 @@ module Projects
def execute
new_params = {
forked_from_project_id: @project.id,
- visibility_level: @project.visibility_level,
+ visibility_level: allowed_visibility_level,
description: @project.description,
name: @project.name,
path: @project.path,
@@ -19,5 +19,17 @@ module Projects
new_project = CreateService.new(current_user, new_params).execute
new_project
end
+
+ private
+
+ def allowed_visibility_level
+ project_level = @project.visibility_level
+
+ if Gitlab::VisibilityLevel.non_restricted_level?(project_level)
+ project_level
+ else
+ Gitlab::VisibilityLevel.highest_allowed_level
+ end
+ end
end
end
diff --git a/app/services/projects/housekeeping_service.rb b/app/services/projects/housekeeping_service.rb
index 3b7c36f0908..43db29315a1 100644
--- a/app/services/projects/housekeeping_service.rb
+++ b/app/services/projects/housekeeping_service.rb
@@ -22,7 +22,7 @@ module Projects
end
def execute
- raise LeaseTaken if !try_obtain_lease
+ raise LeaseTaken unless try_obtain_lease
GitlabShellOneShotWorker.perform_async(:gc, @project.path_with_namespace)
ensure
diff --git a/app/services/wiki_pages/base_service.rb b/app/services/wiki_pages/base_service.rb
index 9162f128602..4c0a2c6b4d8 100644
--- a/app/services/wiki_pages/base_service.rb
+++ b/app/services/wiki_pages/base_service.rb
@@ -6,9 +6,8 @@ module WikiPages
object_kind: page.class.name.underscore,
user: current_user.hook_attrs,
project: @project.hook_attrs,
- object_attributes: page.hook_attrs,
- # DEPRECATED
- repository: @project.hook_attrs.slice(:name, :url, :description, :homepage)
+ wiki: @project.wiki.hook_attrs,
+ object_attributes: page.hook_attrs
}
page_url = Gitlab::UrlBuilder.build(page)
diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml
index 2ab01704b77..862b86d9d4a 100644
--- a/app/views/admin/abuse_reports/_abuse_report.html.haml
+++ b/app/views/admin/abuse_reports/_abuse_report.html.haml
@@ -16,7 +16,7 @@
.light.small
= time_ago_with_tooltip(abuse_report.created_at)
%td
- = markdown(abuse_report.message.squish!, pipeline: :single_line)
+ = markdown(abuse_report.message.squish!, pipeline: :single_line, author: reporter)
%td
- if user
= link_to 'Remove user & report', admin_abuse_report_path(abuse_report, remove_user: true),
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index df286852b97..f149f9eb431 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -178,6 +178,14 @@
.col-sm-10
= f.number_field :max_artifacts_size, class: 'form-control'
+ - if Gitlab.config.registry.enabled
+ %fieldset
+ %legend Container Registry
+ .form-group
+ = f.label :container_registry_token_expire_delay, 'Authorization token duration (minutes)', class: 'control-label col-sm-2'
+ .col-sm-10
+ = f.number_field :container_registry_token_expire_delay, class: 'form-control'
+
%fieldset
%legend Metrics
%p
diff --git a/app/views/admin/builds/index.html.haml b/app/views/admin/builds/index.html.haml
index ed24757087b..d74cf8598e8 100644
--- a/app/views/admin/builds/index.html.haml
+++ b/app/views/admin/builds/index.html.haml
@@ -47,4 +47,3 @@
= render "admin/builds/build", build: build
= paginate @builds, theme: 'gitlab'
-
diff --git a/app/views/dashboard/issues.atom.builder b/app/views/dashboard/issues.atom.builder
index 0d7b1b30dc3..83c0c6da21b 100644
--- a/app/views/dashboard/issues.atom.builder
+++ b/app/views/dashboard/issues.atom.builder
@@ -6,8 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.id issues_dashboard_url
xml.updated @issues.first.created_at.xmlschema if @issues.any?
- @issues.each do |issue|
- issue_to_atom(xml, issue)
- end
+ xml << render(partial: 'issues/issue', collection: @issues) if @issues.any?
end
-
diff --git a/app/views/dashboard/projects/index.atom.builder b/app/views/dashboard/projects/index.atom.builder
index d4daf07c6c0..fb5be63b472 100644
--- a/app/views/dashboard/projects/index.atom.builder
+++ b/app/views/dashboard/projects/index.atom.builder
@@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.id dashboard_projects_url
xml.updated @events[0].updated_at.xmlschema if @events[0]
- @events.each do |event|
- event_to_atom(xml, event)
- end
+ xml << render(partial: 'events/event', collection: @events) if @events.any?
end
diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml
index 539f1dc6036..98f302d2f93 100644
--- a/app/views/dashboard/todos/_todo.html.haml
+++ b/app/views/dashboard/todos/_todo.html.haml
@@ -3,6 +3,8 @@
= image_tag avatar_icon(todo.author_email, 40), class: 'avatar s40', alt:''
.todo-title.title
- unless todo.build_failed?
+ = todo_target_state_pill(todo)
+
%span.author-name
- if todo.author
= link_to_author(todo)
diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb
deleted file mode 100644
index c6fa8f0ee36..00000000000
--- a/app/views/devise/mailer/confirmation_instructions.html.erb
+++ /dev/null
@@ -1,9 +0,0 @@
-<p>Welcome <%= @resource.name %>!</p>
-
-<% if @resource.unconfirmed_email.present? %>
- <p>You can confirm your email (<%= @resource.unconfirmed_email %>) through the link below:</p>
-<% else %>
- <p>You can confirm your account through the link below:</p>
-<% end %>
-
-<p><%= link_to 'Confirm your account', confirmation_url(@resource, confirmation_token: @token) %></p>
diff --git a/app/views/devise/mailer/confirmation_instructions.html.haml b/app/views/devise/mailer/confirmation_instructions.html.haml
new file mode 100644
index 00000000000..086bb8e083d
--- /dev/null
+++ b/app/views/devise/mailer/confirmation_instructions.html.haml
@@ -0,0 +1,16 @@
+.center
+ - if @resource.unconfirmed_email.present?
+ #content
+ %h2= @resource.unconfirmed_email
+ %p Click the link below to confirm your email address.
+ #cta
+ = link_to 'Confirm your email address', confirmation_url(@resource, confirmation_token: @token)
+ - else
+ #content
+ - if Gitlab.com?
+ %h2 Thanks for signing up to GitLab!
+ - else
+ %h2 Welcome, #{@resource.name}!
+ %p To get started, click the link below to confirm your account.
+ #cta
+ = link_to 'Confirm your account', confirmation_url(@resource, confirmation_token: @token)
diff --git a/app/views/devise/mailer/confirmation_instructions.text.erb b/app/views/devise/mailer/confirmation_instructions.text.erb
new file mode 100644
index 00000000000..9f76edb76a4
--- /dev/null
+++ b/app/views/devise/mailer/confirmation_instructions.text.erb
@@ -0,0 +1,9 @@
+Welcome, <%= @resource.name %>!
+
+<% if @resource.unconfirmed_email.present? %>
+You can confirm your email (<%= @resource.unconfirmed_email %>) through the link below:
+<% else %>
+You can confirm your account through the link below:
+<% end %>
+
+<%= confirmation_url(@resource, confirmation_token: @token) %>
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index c9d1e454a5e..8c6a1552a53 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -4,6 +4,7 @@
%h3 Two-factor Authentication
.login-body
= form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
+ = f.hidden_field :remember_me, value: params[resource_name][:remember_me]
= f.text_field :otp_attempt, class: 'form-control', placeholder: 'Two-factor Authentication code', required: true, autofocus: true
%p.help-block.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.
.prepend-top-20
diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml
index eae80e5210f..ce050007204 100644
--- a/app/views/doorkeeper/authorizations/new.html.haml
+++ b/app/views/doorkeeper/authorizations/new.html.haml
@@ -1,4 +1,4 @@
-%h3.page-title Authorize required
+%h3.page-title Authorization required
%main{:role => "main"}
%p.h4
Authorize
diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml
index dce4081288c..1bc9f604438 100644
--- a/app/views/events/_commit.html.haml
+++ b/app/views/events/_commit.html.haml
@@ -2,4 +2,4 @@
.commit-row-title
= link_to truncate_sha(commit[:id]), namespace_project_commit_path(project.namespace, project, commit[:id]), class: "commit_short_id", alt: '', title: truncate_sha(commit[:id])
&middot;
- = markdown event_commit_title(commit[:message]), project: project, pipeline: :single_line
+ = markdown event_commit_title(commit[:message]), project: project, pipeline: :single_line, author: event.author
diff --git a/app/views/events/_event.atom.builder b/app/views/events/_event.atom.builder
new file mode 100644
index 00000000000..7890e717aa7
--- /dev/null
+++ b/app/views/events/_event.atom.builder
@@ -0,0 +1,20 @@
+return unless event.visible_to_user?(current_user)
+
+xml.entry do
+ xml.id "tag:#{request.host},#{event.created_at.strftime("%Y-%m-%d")}:#{event.id}"
+ xml.link href: event_feed_url(event)
+ xml.title truncate(event_feed_title(event), length: 80)
+ xml.updated event.created_at.xmlschema
+ xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(event.author_email))
+
+ xml.author do
+ xml.name event.author_name
+ xml.email event.author_email
+ end
+
+ xml.summary(type: "xhtml") do |summary|
+ event_summary = event_feed_summary(event)
+
+ summary << event_summary unless event_summary.nil?
+ end
+end
diff --git a/app/views/events/_event_issue.atom.haml b/app/views/events/_event_issue.atom.haml
index fad65310021..083c3936212 100644
--- a/app/views/events/_event_issue.atom.haml
+++ b/app/views/events/_event_issue.atom.haml
@@ -1,2 +1,2 @@
%div{xmlns: "http://www.w3.org/1999/xhtml"}
- = markdown(issue.description, pipeline: :atom, project: issue.project)
+ = markdown(issue.description, pipeline: :atom, project: issue.project, author: issue.author)
diff --git a/app/views/events/_event_merge_request.atom.haml b/app/views/events/_event_merge_request.atom.haml
index 19bdc7b9ca5..d7e05600627 100644
--- a/app/views/events/_event_merge_request.atom.haml
+++ b/app/views/events/_event_merge_request.atom.haml
@@ -1,2 +1,2 @@
%div{xmlns: "http://www.w3.org/1999/xhtml"}
- = markdown(merge_request.description, pipeline: :atom, project: merge_request.project)
+ = markdown(merge_request.description, pipeline: :atom, project: merge_request.project, author: merge_request.author)
diff --git a/app/views/events/_event_note.atom.haml b/app/views/events/_event_note.atom.haml
index b730ebbd5f9..1154f982821 100644
--- a/app/views/events/_event_note.atom.haml
+++ b/app/views/events/_event_note.atom.haml
@@ -1,2 +1,2 @@
%div{xmlns: "http://www.w3.org/1999/xhtml"}
- = markdown(note.note, pipeline: :atom, project: note.project)
+ = markdown(note.note, pipeline: :atom, project: note.project, author: note.author)
diff --git a/app/views/events/_event_push.atom.haml b/app/views/events/_event_push.atom.haml
index b271b9daff1..28bee1d0a33 100644
--- a/app/views/events/_event_push.atom.haml
+++ b/app/views/events/_event_push.atom.haml
@@ -6,7 +6,7 @@
%i
at
= commit[:timestamp].to_time.to_s(:short)
- %blockquote= markdown(escape_once(commit[:message]), pipeline: :atom, project: event.project)
+ %blockquote= markdown(escape_once(commit[:message]), pipeline: :atom, project: event.project, author: event.author)
- if event.commits_count > 15
%p
%i
diff --git a/app/views/events/event/_common.html.haml b/app/views/events/event/_common.html.haml
index f9f623cc031..c7f29f2fc0e 100644
--- a/app/views/events/event/_common.html.haml
+++ b/app/views/events/event/_common.html.haml
@@ -4,7 +4,7 @@
= event_action_name(event)
- if event.target
- %strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target], title: event.target_title
+ %strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target], class: 'has-tooltip', title: event.target_title
= event_preposition(event)
diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml
index 235bd46107e..dc4ff17e31a 100644
--- a/app/views/events/event/_push.html.haml
+++ b/app/views/events/event/_push.html.haml
@@ -15,7 +15,7 @@
%ul.well-list.event_commits
- few_commits = event.commits[0...2]
- few_commits.each do |commit|
- = render "events/commit", commit: commit, project: project
+ = render "events/commit", commit: commit, project: project, event: event
- create_mr = event.new_ref? && create_mr_button?(event.project.default_branch, event.ref_name, event.project)
- if event.commits_count > 1
diff --git a/app/views/groups/issues.atom.builder b/app/views/groups/issues.atom.builder
index a6eb9abada6..c19671295af 100644
--- a/app/views/groups/issues.atom.builder
+++ b/app/views/groups/issues.atom.builder
@@ -6,8 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.id issues_group_url
xml.updated @issues.first.created_at.xmlschema if @issues.any?
- @issues.each do |issue|
- issue_to_atom(xml, issue)
- end
+ xml << render(partial: 'issues/issue', collection: @issues) if @issues.any?
end
-
diff --git a/app/views/groups/show.atom.builder b/app/views/groups/show.atom.builder
index c66b82bb484..b68bf444d27 100644
--- a/app/views/groups/show.atom.builder
+++ b/app/views/groups/show.atom.builder
@@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.id group_url(@group)
xml.updated @events[0].updated_at.xmlschema if @events[0]
- @events.each do |event|
- event_to_atom(xml, event)
- end
+ xml << render(@events) if @events.any?
end
diff --git a/app/views/import/gitlab/status.html.haml b/app/views/import/gitlab/status.html.haml
index e3a356b5379..aedb8468eca 100644
--- a/app/views/import/gitlab/status.html.haml
+++ b/app/views/import/gitlab/status.html.haml
@@ -47,7 +47,7 @@
%td.import-target
= repo["path_with_namespace"]
%td.import-actions.job-status
- = button_tag class: "btn js-add-to-import" do
+ = button_tag class: "btn btn-import js-add-to-import" do
Import
= icon("spinner spin", class: "loading-icon")
diff --git a/app/views/issues/_issue.atom.builder b/app/views/issues/_issue.atom.builder
new file mode 100644
index 00000000000..68a2d19e58d
--- /dev/null
+++ b/app/views/issues/_issue.atom.builder
@@ -0,0 +1,14 @@
+xml.entry do
+ xml.id namespace_project_issue_url(issue.project.namespace, issue.project, issue)
+ xml.link href: namespace_project_issue_url(issue.project.namespace, issue.project, issue)
+ xml.title truncate(issue.title, length: 80)
+ xml.updated issue.created_at.xmlschema
+ xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(issue.author_email))
+
+ xml.author do |author|
+ xml.name issue.author_name
+ xml.email issue.author_email
+ end
+
+ xml.summary issue.title
+end
diff --git a/app/views/kaminari/gitlab/_first_page.html.haml b/app/views/kaminari/gitlab/_first_page.html.haml
index ada7306d98d..e7a70e3bb28 100644
--- a/app/views/kaminari/gitlab/_first_page.html.haml
+++ b/app/views/kaminari/gitlab/_first_page.html.haml
@@ -2,7 +2,7 @@
-# available local variables
-# url: url to the first page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
%li.first
diff --git a/app/views/kaminari/gitlab/_gap.html.haml b/app/views/kaminari/gitlab/_gap.html.haml
index 3ffd12f8587..80ca30f36e6 100644
--- a/app/views/kaminari/gitlab/_gap.html.haml
+++ b/app/views/kaminari/gitlab/_gap.html.haml
@@ -1,7 +1,7 @@
-# Non-link tag that stands for skipped pages...
-# available local variables
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
%li{class: "page"}
diff --git a/app/views/kaminari/gitlab/_last_page.html.haml b/app/views/kaminari/gitlab/_last_page.html.haml
index 3431d029bcc..53f780d1d1b 100644
--- a/app/views/kaminari/gitlab/_last_page.html.haml
+++ b/app/views/kaminari/gitlab/_last_page.html.haml
@@ -2,7 +2,7 @@
-# available local variables
-# url: url to the last page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
%li.last
diff --git a/app/views/kaminari/gitlab/_next_page.html.haml b/app/views/kaminari/gitlab/_next_page.html.haml
index c805914fc3f..125f09777ba 100644
--- a/app/views/kaminari/gitlab/_next_page.html.haml
+++ b/app/views/kaminari/gitlab/_next_page.html.haml
@@ -2,7 +2,7 @@
-# available local variables
-# url: url to the next page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
- if current_page.last?
diff --git a/app/views/kaminari/gitlab/_page.html.haml b/app/views/kaminari/gitlab/_page.html.haml
index a52d883b9a8..522e4d1d05f 100644
--- a/app/views/kaminari/gitlab/_page.html.haml
+++ b/app/views/kaminari/gitlab/_page.html.haml
@@ -3,7 +3,7 @@
-# page: a page object for "this" page
-# url: url to this page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
%li{class: "page#{' active' if page.current?}"}
diff --git a/app/views/kaminari/gitlab/_paginator.html.haml b/app/views/kaminari/gitlab/_paginator.html.haml
index a12c53bcfe7..f5e0d2ed3f3 100644
--- a/app/views/kaminari/gitlab/_paginator.html.haml
+++ b/app/views/kaminari/gitlab/_paginator.html.haml
@@ -1,7 +1,7 @@
-# The container tag
-# available local variables
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
-# paginator: the paginator that renders the pagination tags inside
@@ -9,7 +9,7 @@
%div.gl-pagination
%ul.pagination.clearfix
- unless current_page.first?
- = first_page_tag unless num_pages < 5 # As kaminari will always show the first 5 pages
+ = first_page_tag unless total_pages < 5 # As kaminari will always show the first 5 pages
= prev_page_tag
- each_page do |page|
- if page.left_outer? || page.right_outer? || page.inside_window?
@@ -18,5 +18,5 @@
= gap_tag
= next_page_tag
- unless current_page.last?
- = last_page_tag unless num_pages < 5
+ = last_page_tag unless total_pages < 5
diff --git a/app/views/kaminari/gitlab/_prev_page.html.haml b/app/views/kaminari/gitlab/_prev_page.html.haml
index afb20455e0a..7edf10498a8 100644
--- a/app/views/kaminari/gitlab/_prev_page.html.haml
+++ b/app/views/kaminari/gitlab/_prev_page.html.haml
@@ -2,7 +2,7 @@
-# available local variables
-# url: url to the previous page
-# current_page: a page object for the currently displayed page
--# num_pages: total number of pages
+-# total_pages: total number of pages
-# per_page: number of items to fetch per page
-# remote: data-remote
- if current_page.first?
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 79cdbac1f37..b30fb0a5da9 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -30,6 +30,9 @@
= javascript_include_tag "application"
+ - if page_specific_javascripts
+ = javascript_include_tag page_specific_javascripts, {"data-turbolinks-track" => true}
+
= csrf_meta_tags
= include_gon
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index 5be0b546a62..1e961853c70 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -25,7 +25,7 @@
.layout-nav
.container-fluid
= render "layouts/nav/#{nav}"
- .content-wrapper{ class: "#{layout_nav_class} #{layout_dropdown_class}" }
+ .content-wrapper{ class: "#{layout_nav_class}" }
= render "layouts/broadcast"
= render "layouts/flash"
= yield :flash_message
diff --git a/app/views/layouts/devise_mailer.html.haml b/app/views/layouts/devise_mailer.html.haml
new file mode 100644
index 00000000000..c258eafdd51
--- /dev/null
+++ b/app/views/layouts/devise_mailer.html.haml
@@ -0,0 +1,34 @@
+!!! 5
+%html
+ %head
+ %meta(content='text/html; charset=UTF-8' http-equiv='Content-Type')
+ = stylesheet_link_tag 'mailers/devise'
+
+ %body
+ %table#wrapper
+ %tr
+ %td
+ %table#header
+ %td{valign: "top"}
+ = image_tag('mailers/gitlab_header_logo.png', id: 'logo', alt: 'GitLab Wordmark')
+
+ %table#body
+ %tr
+ %td#body-container
+ = yield
+
+ - if Gitlab.com?
+ %table#footer
+ %tr
+ %td#tanuki
+ = image_tag('mailers/gitlab_tanuki_2x.png', alt: 'GitLab Logo')
+ %tr
+ %td#tagline
+ Everyone can contribute
+ %tr
+ %td#social
+ = link_to 'Blog', 'https://about.gitlab.com/blog/'
+ = link_to 'Twitter', 'https://twitter.com/gitlab'
+ = link_to 'Facebook', 'https://www.facebook.com/gitlab/'
+ = link_to 'YouTube', 'https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg'
+ = link_to 'LinkedIn', 'https://www.linkedin.com/company/gitlab-com'
diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml
index 3438005863a..de15add3617 100644
--- a/app/views/layouts/nav/_group.html.haml
+++ b/app/views/layouts/nav/_group.html.haml
@@ -1,37 +1,40 @@
-= render 'layouts/nav/group_settings'
+%div{ class: nav_control_class }
+ = render 'layouts/nav/group_settings'
-%ul.nav-links
- = nav_link(path: 'groups#show', html_options: {class: 'home'}) do
- = link_to group_path(@group), title: 'Home' do
- = icon('group fw')
- %span
- Group
- = nav_link(path: 'groups#activity') do
- = link_to activity_group_path(@group), title: 'Activity' do
- = icon('dashboard fw')
- %span
- Activity
- = nav_link(controller: [:group, :milestones]) do
- = link_to group_milestones_path(@group), title: 'Milestones' do
- = icon('clock-o fw')
- %span
- Milestones
- = nav_link(path: 'groups#issues') do
- = link_to issues_group_path(@group), title: 'Issues' do
- = icon('exclamation-circle fw')
- %span
- Issues
- - issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
- %span.badge.count= number_with_delimiter(issues.count)
- = nav_link(path: 'groups#merge_requests') do
- = link_to merge_requests_group_path(@group), title: 'Merge Requests' do
- = icon('tasks fw')
- %span
- Merge Requests
- - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened').execute
- %span.badge.count= number_with_delimiter(merge_requests.count)
- = nav_link(controller: [:group_members]) do
- = link_to group_group_members_path(@group), title: 'Members' do
- = icon('users fw')
- %span
- Members
+ %ul.nav-links.scrolling-tabs
+ .fade-left
+ = nav_link(path: 'groups#show', html_options: {class: 'home'}) do
+ = link_to group_path(@group), title: 'Home' do
+ = icon('group fw')
+ %span
+ Group
+ = nav_link(path: 'groups#activity') do
+ = link_to activity_group_path(@group), title: 'Activity' do
+ = icon('dashboard fw')
+ %span
+ Activity
+ = nav_link(controller: [:group, :milestones]) do
+ = link_to group_milestones_path(@group), title: 'Milestones' do
+ = icon('clock-o fw')
+ %span
+ Milestones
+ = nav_link(path: 'groups#issues') do
+ = link_to issues_group_path(@group), title: 'Issues' do
+ = icon('exclamation-circle fw')
+ %span
+ Issues
+ - issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
+ %span.badge.count= number_with_delimiter(issues.count)
+ = nav_link(path: 'groups#merge_requests') do
+ = link_to merge_requests_group_path(@group), title: 'Merge Requests' do
+ = icon('tasks fw')
+ %span
+ Merge Requests
+ - merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened').execute
+ %span.badge.count= number_with_delimiter(merge_requests.count)
+ = nav_link(controller: [:group_members]) do
+ = link_to group_group_members_path(@group), title: 'Members' do
+ = icon('users fw')
+ %span
+ Members
+ .fade-right
diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml
index d730840d63a..2efc6c48a48 100644
--- a/app/views/layouts/nav/_profile.html.haml
+++ b/app/views/layouts/nav/_profile.html.haml
@@ -1,4 +1,5 @@
-%ul.nav-links
+%ul.nav-links.scrolling-tabs
+ .fade-left
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
= link_to profile_path, title: 'Profile Settings' do
= icon('user fw')
@@ -47,3 +48,4 @@
= icon('history fw')
%span
Audit Log
+ .fade-right
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index 33ba654bbee..2c9b9006668 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -19,113 +19,114 @@
data: { confirm: leave_project_message(@project) }, method: :delete, title: 'Leave project' do
Leave Project
-%ul.nav-links
- = nav_link(path: 'projects#show', html_options: {class: 'home'}) do
- = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do
- = icon('bookmark fw')
- %span
- Project
- = nav_link(path: 'projects#activity') do
- = link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do
- = icon('dashboard fw')
- %span
- Activity
- - if project_nav_tab? :files
- = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
- = link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree' do
- = icon('files-o fw')
+%div{ class: nav_control_class }
+ %ul.nav-links.scrolling-tabs
+ .fade-left
+ = nav_link(path: 'projects#show', html_options: {class: 'home'}) do
+ = link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do
+ = icon('bookmark fw')
%span
- Files
-
- - if project_nav_tab? :commits
- = nav_link(controller: %w(commit commits compare repositories tags branches releases network)) do
- = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do
- = icon('history fw')
+ Project
+ = nav_link(path: 'projects#activity') do
+ = link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do
+ = icon('dashboard fw')
%span
- Commits
+ Activity
+ - if project_nav_tab? :files
+ = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
+ = link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree' do
+ = icon('files-o fw')
+ %span
+ Files
- - if project_nav_tab? :pipelines
- = nav_link(controller: :pipelines) do
- = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
- = icon('ship fw')
- %span
- Pipelines
- %span.badge.count.ci_counter= number_with_delimiter(@project.ci_commits.running_or_pending.count)
+ - if project_nav_tab? :commits
+ = nav_link(controller: %w(commit commits compare repositories tags branches releases network)) do
+ = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do
+ = icon('history fw')
+ %span
+ Commits
- - if project_nav_tab? :builds
- = nav_link(controller: %w(builds)) do
- = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
- = icon('cubes fw')
- %span
- Builds
- %span.badge.count.builds_counter= number_with_delimiter(@project.builds.running_or_pending.count(:all))
+ - if project_nav_tab? :pipelines
+ = nav_link(controller: :pipelines) do
+ = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
+ = icon('ship fw')
+ %span
+ Pipelines
- - if project_nav_tab? :container_registry
- = nav_link(controller: %w(container_registry)) do
- = link_to project_container_registry_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do
- = icon('hdd-o fw')
- %span
- Container Registry
+ - if project_nav_tab? :container_registry
+ = nav_link(controller: %w(container_registry)) do
+ = link_to project_container_registry_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do
+ = icon('hdd-o fw')
+ %span
+ Container Registry
- - if project_nav_tab? :graphs
- = nav_link(controller: %w(graphs)) do
- = link_to namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Graphs', class: 'shortcuts-graphs' do
- = icon('area-chart fw')
- %span
- Graphs
+ - if project_nav_tab? :graphs
+ = nav_link(controller: %w(graphs)) do
+ = link_to namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Graphs', class: 'shortcuts-graphs' do
+ = icon('area-chart fw')
+ %span
+ Graphs
- - if project_nav_tab? :milestones
- = nav_link(controller: :milestones) do
- = link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do
- = icon('clock-o fw')
- %span
- Milestones
+ - if project_nav_tab? :milestones
+ = nav_link(controller: :milestones) do
+ = link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do
+ = icon('clock-o fw')
+ %span
+ Milestones
- - if project_nav_tab? :issues
- = nav_link(controller: :issues) do
- = link_to url_for_project_issues(@project, only_path: true), title: 'Issues', class: 'shortcuts-issues' do
- = icon('exclamation-circle fw')
- %span
- Issues
- - if @project.default_issues_tracker?
- %span.badge.count.issue_counter= number_with_delimiter(@project.issues.visible_to_user(current_user).opened.count)
+ - if project_nav_tab? :issues
+ = nav_link(controller: :issues) do
+ = link_to url_for_project_issues(@project, only_path: true), title: 'Issues', class: 'shortcuts-issues' do
+ = icon('exclamation-circle fw')
+ %span
+ Issues
+ - if @project.default_issues_tracker?
+ %span.badge.count.issue_counter= number_with_delimiter(@project.issues.visible_to_user(current_user).opened.count)
- - if project_nav_tab? :merge_requests
- = nav_link(controller: :merge_requests) do
- = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do
- = icon('tasks fw')
- %span
- Merge Requests
- %span.badge.count.merge_counter= number_with_delimiter(@project.merge_requests.opened.count)
+ - if project_nav_tab? :merge_requests
+ = nav_link(controller: :merge_requests) do
+ = link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do
+ = icon('tasks fw')
+ %span
+ Merge Requests
+ %span.badge.count.merge_counter= number_with_delimiter(@project.merge_requests.opened.count)
- - if project_nav_tab? :labels
- = nav_link(controller: :labels) do
- = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do
- = icon('tags fw')
- %span
- Labels
+ - if project_nav_tab? :labels
+ = nav_link(controller: :labels) do
+ = link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do
+ = icon('tags fw')
+ %span
+ Labels
- - if project_nav_tab? :wiki
- = nav_link(controller: :wikis) do
- = link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do
- = icon('book fw')
- %span
- Wiki
+ - if project_nav_tab? :wiki
+ = nav_link(controller: :wikis) do
+ = link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do
+ = icon('book fw')
+ %span
+ Wiki
- - if project_nav_tab? :snippets
- = nav_link(controller: :snippets) do
- = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do
- = icon('clipboard fw')
- %span
- Snippets
+ - if project_nav_tab? :snippets
+ = nav_link(controller: :snippets) do
+ = link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do
+ = icon('clipboard fw')
+ %span
+ Snippets
- -# Global shortcut to network page for compatibility
- - if project_nav_tab? :network
+ -# Global shortcut to network page for compatibility
+ - if project_nav_tab? :network
+ %li.hidden
+ = link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network' do
+ Network
+
+ -# Shortcut to create a new issue
%li.hidden
- = link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network' do
- Network
+ = link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'shortcuts-new-issue' do
+ Create a new issue
+
+ -# Shortcut to builds page
+ - if project_nav_tab? :builds
+ %li.hidden
+ = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
+ Builds
- -# Shortcut to create a new issue
- %li.hidden
- = link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'shortcuts-new-issue' do
- Create a new issue
+ .fade-right
diff --git a/app/views/notify/_note_message.html.haml b/app/views/notify/_note_message.html.haml
index 12ded41fbf2..e9c66170877 100644
--- a/app/views/notify/_note_message.html.haml
+++ b/app/views/notify/_note_message.html.haml
@@ -2,4 +2,4 @@
%div
#{link_to @note.author_name, user_url(@note.author)} wrote:
%div
- = markdown(@note.note, pipeline: :email)
+ = markdown(@note.note, pipeline: :email, author: @note.author)
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index ad3ab2525bb..f42b150c0d6 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -2,7 +2,7 @@
%div
#{link_to @issue.author_name, user_url(@issue.author)} wrote:
-if @issue.description
- = markdown(@issue.description, pipeline: :email)
+ = markdown(@issue.description, pipeline: :email, author: @issue.author)
- if @issue.assignee_id.present?
%p
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index 23423e7d981..158404de396 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -9,4 +9,4 @@
Assignee: #{@merge_request.author_name} &rarr; #{@merge_request.assignee_name}
-if @merge_request.description
- = markdown(@merge_request.description, pipeline: :email)
+ = markdown(@merge_request.description, pipeline: :email, author: @merge_request.author)
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index afd3d79321f..01ac8161945 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -70,7 +70,7 @@
- if current_user.can_change_username?
.row.prepend-top-default
.col-lg-3.profile-settings-sidebar
- %h4.prepend-top-0.change-username-title
+ %h4.prepend-top-0.warning-title
Change username
%p
Changing your username will change path to all personal projects!
@@ -94,7 +94,7 @@
- if signup_enabled?
.row.prepend-top-default
.col-lg-3.profile-settings-sidebar
- %h4.prepend-top-0.remove-account-title
+ %h4.prepend-top-0.danger-title
Remove account
.col-lg-9
- if @user.can_be_removed?
diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index bfe53be6854..1b1b16d656f 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -5,7 +5,7 @@
%h4.prepend-top-0
Application theme
%p
- This setting allows you to customize the appearance of the site, ex. sidebar.
+ This setting allows you to customize the appearance of the site, e.g. the sidebar.
.col-lg-9.application-theme
- Gitlab::Themes.each do |theme|
= label_tag do
diff --git a/app/views/projects/_builds_settings.html.haml b/app/views/projects/_builds_settings.html.haml
index 0de019983ca..0568c2d305e 100644
--- a/app/views/projects/_builds_settings.html.haml
+++ b/app/views/projects/_builds_settings.html.haml
@@ -1,74 +1,65 @@
%fieldset.builds-feature
- %legend
- Builds:
-
+ %h5.prepend-top-0
+ Builds
- unless @repository.gitlab_ci_yml
.form-group
- .col-sm-offset-2.col-sm-10
- %p Builds need to be configured before you can begin using Continuous Integration.
- = link_to 'Get started with Builds', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info'
- %hr
-
+ %p Builds need to be configured before you can begin using Continuous Integration.
+ = link_to 'Get started with Builds', help_page_path('ci/quick_start', 'README'), class: 'btn btn-info'
.form-group
- .col-sm-offset-2.col-sm-10
- %p Get recent application code using the following command:
- .radio
- = f.label :build_allow_git_fetch_false do
- = f.radio_button :build_allow_git_fetch, 'false'
- %strong git clone
- %br
- %span.descr Slower but makes sure you have a clean dir before every build
- .radio
- = f.label :build_allow_git_fetch_true do
- = f.radio_button :build_allow_git_fetch, 'true'
- %strong git fetch
- %br
- %span.descr Faster
+ %p Get recent application code using the following command:
+ .radio
+ = f.label :build_allow_git_fetch_false do
+ = f.radio_button :build_allow_git_fetch, 'false'
+ %strong git clone
+ %br
+ %span.descr Slower but makes sure you have a clean dir before every build
+ .radio
+ = f.label :build_allow_git_fetch_true do
+ = f.radio_button :build_allow_git_fetch, 'true'
+ %strong git fetch
+ %br
+ %span.descr Faster
.form-group
- = f.label :build_timeout_in_minutes, 'Timeout', class: 'control-label'
- .col-sm-10
- = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0'
- %p.help-block per build in minutes
+ = f.label :build_timeout_in_minutes, 'Timeout', class: 'label-light'
+ = f.number_field :build_timeout_in_minutes, class: 'form-control', min: '0'
+ %p.help-block per build in minutes
.form-group
- = f.label :build_coverage_regex, "Test coverage parsing", class: 'control-label'
- .col-sm-10
- .input-group
- %span.input-group-addon /
- = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered'
- %span.input-group-addon /
- %p.help-block
- We will use this regular expression to find test coverage output in build trace.
- Leave blank if you want to disable this feature
- .bs-callout.bs-callout-info
- %p Below are examples of regex for existing tools:
- %ul
- %li
- Simplecov (Ruby) -
- %code \(\d+.\d+\%\) covered
- %li
- pytest-cov (Python) -
- %code \d+\%\s*$
- %li
- phpunit --coverage-text --colors=never (PHP) -
- %code ^\s*Lines:\s*\d+.\d+\%
- %li
- gcovr (C/C++) -
- %code ^TOTAL.*\s+(\d+\%)$
- %li
- tap --coverage-report=text-summary (Node.js) -
- %code ^Statements\s*:\s*([^%]+)
+ = f.label :build_coverage_regex, "Test coverage parsing", class: 'label-light'
+ .input-group
+ %span.input-group-addon /
+ = f.text_field :build_coverage_regex, class: 'form-control', placeholder: '\(\d+.\d+\%\) covered'
+ %span.input-group-addon /
+ %p.help-block
+ We will use this regular expression to find test coverage output in build trace.
+ Leave blank if you want to disable this feature
+ .bs-callout.bs-callout-info
+ %p Below are examples of regex for existing tools:
+ %ul
+ %li
+ Simplecov (Ruby) -
+ %code \(\d+.\d+\%\) covered
+ %li
+ pytest-cov (Python) -
+ %code \d+\%\s*$
+ %li
+ phpunit --coverage-text --colors=never (PHP) -
+ %code ^\s*Lines:\s*\d+.\d+\%
+ %li
+ gcovr (C/C++) -
+ %code ^TOTAL.*\s+(\d+\%)$
+ %li
+ tap --coverage-report=text-summary (Node.js) -
+ %code ^Statements\s*:\s*([^%]+)
.form-group
- .col-sm-offset-2.col-sm-10
- .checkbox
- = f.label :public_builds do
- = f.check_box :public_builds
- %strong Public builds
- .help-block Allow everyone to access builds for Public and Internal projects
+ .checkbox
+ = f.label :public_builds do
+ = f.check_box :public_builds
+ %strong Public builds
+ .help-block Allow everyone to access builds for Public and Internal projects
- .form-group
- = f.label :runners_token, "Runners token", class: 'control-label'
- .col-sm-10
- = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89'
- %p.help-block The secure token used to checkout project.
+ .form-group.append-bottom-0
+ = f.label :runners_token, "Runners token", class: 'label-light'
+ = f.text_field :runners_token, class: "form-control", placeholder: 'xEeFCaDAB89'
+ %p.help-block The secure token used to checkout project.
diff --git a/app/views/projects/activity.html.haml b/app/views/projects/activity.html.haml
index 69fa4ad37c4..3c0f01cbf6f 100644
--- a/app/views/projects/activity.html.haml
+++ b/app/views/projects/activity.html.haml
@@ -1,5 +1,4 @@
- page_title "Activity"
-- header_title project_title(@project, "Activity", activity_project_path(@project))
= render 'projects/last_push'
diff --git a/app/views/projects/artifacts/browse.html.haml b/app/views/projects/artifacts/browse.html.haml
index 49f95ff37db..ede01dcc1aa 100644
--- a/app/views/projects/artifacts/browse.html.haml
+++ b/app/views/projects/artifacts/browse.html.haml
@@ -1,5 +1,4 @@
- page_title 'Artifacts', "#{@build.name} (##{@build.id})", 'Builds'
-= render 'projects/builds/header_title'
.top-block.row-content-block.clearfix
.pull-right
diff --git a/app/views/projects/badges/index.html.haml b/app/views/projects/badges/index.html.haml
index c22384ddf46..ee63bc55a30 100644
--- a/app/views/projects/badges/index.html.haml
+++ b/app/views/projects/badges/index.html.haml
@@ -1,6 +1,5 @@
- page_title 'Badges'
- badges_path = namespace_project_badges_path(@project.namespace, @project)
-- header_title project_title(@project, 'Badges', badges_path)
.prepend-top-10
.panel.panel-default
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index 5f9a92ff93f..377665b096f 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -1,5 +1,4 @@
- page_title "Blame", @blob.path, @ref
-- header_title project_title(@project, "Files", project_files_path(@project))
%h3.page-title Blame view
diff --git a/app/views/projects/blob/_header_title.html.haml b/app/views/projects/blob/_header_title.html.haml
deleted file mode 100644
index 78c5ef20a5f..00000000000
--- a/app/views/projects/blob/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Files", project_files_path(@project))
diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml
index effcce5a1c4..e4f04ca7764 100644
--- a/app/views/projects/blob/edit.html.haml
+++ b/app/views/projects/blob/edit.html.haml
@@ -1,5 +1,4 @@
- page_title "Edit", @blob.path, @ref
-= render "header_title"
.file-editor
%ul.nav-links.no-bottom.js-edit-mode
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index 0459699432e..c952bc7e5db 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New File", @path.presence, @ref
-= render "header_title"
%h3.page-title
New File
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index 6988039b6c7..ed670dae88d 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -1,5 +1,4 @@
- page_title @blob.path, @ref
-= render "header_title"
= render 'projects/last_push'
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index ac7790421a4..08148b1a18b 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Branches"
-= render "projects/commits/header_title"
= render "projects/commits/head"
.row-content-block
.pull-right
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index c659af6338c..5a6c8c243fa 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New Branch"
-= render "projects/commits/header_title"
- if @error
.alert.alert-danger
diff --git a/app/views/projects/builds/_header_title.html.haml b/app/views/projects/builds/_header_title.html.haml
deleted file mode 100644
index 082dab1f5b0..00000000000
--- a/app/views/projects/builds/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Builds", project_builds_path(@project))
diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml
index 98f4a9416e5..818d5d28f04 100644
--- a/app/views/projects/builds/index.html.haml
+++ b/app/views/projects/builds/index.html.haml
@@ -1,5 +1,5 @@
- page_title "Builds"
-= render "header_title"
+= render "projects/pipelines/head"
.top-area
%ul.nav-links
@@ -35,9 +35,6 @@
= icon('wrench')
%span CI Lint
-.row-content-block
- #{(@scope || 'all').capitalize} builds from this project
-
%ul.content-list
- if @builds.blank?
%li
diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml
index c7b9c36a3ab..16017c994ba 100644
--- a/app/views/projects/builds/show.html.haml
+++ b/app/views/projects/builds/show.html.haml
@@ -1,5 +1,4 @@
- page_title "#{@build.name} (##{@build.id})", "Builds"
-= render "header_title"
- trace_with_state = @build.trace_with_state
.build-page
diff --git a/app/views/projects/ci/builds/_build.html.haml b/app/views/projects/ci/builds/_build.html.haml
index e23a3782c6b..5bd6e3f0ebc 100644
--- a/app/views/projects/ci/builds/_build.html.haml
+++ b/app/views/projects/ci/builds/_build.html.haml
@@ -57,14 +57,10 @@
%td.duration
- if build.duration
- = icon("clock-o")
- &nbsp;
#{duration_in_words(build.finished_at, build.started_at)}
%td.timestamp
- if build.finished_at
- = icon("calendar")
- &nbsp;
%span #{time_ago_with_tooltip(build.finished_at)}
- if defined?(coverage) && coverage
diff --git a/app/views/projects/ci/commits/_commit.html.haml b/app/views/projects/ci/commits/_commit.html.haml
index 13162b41f9b..5e3a4123a8e 100644
--- a/app/views/projects/ci/commits/_commit.html.haml
+++ b/app/views/projects/ci/commits/_commit.html.haml
@@ -12,10 +12,10 @@
&middot;
= link_to commit.short_sha, namespace_project_commit_path(@project.namespace, @project, commit.sha), class: "commit-id monospace"
&nbsp;
- - if commit.latest?
- %span.label.label-success latest
- if commit.tag?
%span.label.label-primary tag
+ - elsif commit.latest?
+ %span.label.label-success.has-tooltip{ title: 'Latest build for this branch' } latest
- if commit.triggered?
%span.label.label-primary triggered
- if commit.yaml_errors.present?
@@ -23,33 +23,29 @@
- if commit.builds.any?(&:stuck?)
%span.label.label-warning stuck
- %p
- %span
- - if commit_data = commit.commit_data
- = link_to_gfm commit_data.title, namespace_project_commit_path(@project.namespace, @project, commit_data.id), class: "commit-row-message"
- - else
- Cant find HEAD commit for this branch
+ %p.commit-title
+ - if commit_data = commit.commit_data
+ = link_to_gfm truncate(commit_data.title, length: 60), namespace_project_commit_path(@project.namespace, @project, commit_data.id), class: "commit-row-message"
+ - else
+ Cant find HEAD commit for this branch
- stages_status = commit.statuses.stages_status
- stages.each do |stage|
%td
- - if status = stages_status[stage]
- - tooltip = "#{stage.titleize}: #{status}"
- %span.has-tooltip{ title: "#{tooltip}", class: "ci-status-icon-#{status}" }
+ - status = stages_status[stage]
+ - tooltip = "#{stage.titleize}: #{status || 'not found'}"
+ - if status
+ = link_to namespace_project_pipeline_path(@project.namespace, @project, commit.id, anchor: stage), class: "has-tooltip ci-status-icon-#{status}", title: tooltip do
= ci_icon_for_status(status)
+ - else
+ .light.has-tooltip{ title: tooltip }
+ \-
%td
- if commit.started_at && commit.finished_at
- %p
- = icon("clock-o")
- &nbsp;
+ %p.duration
#{duration_in_words(commit.finished_at, commit.started_at)}
- - if commit.finished_at
- %p
- = icon("calendar")
- &nbsp;
- #{time_ago_with_tooltip(commit.finished_at)}
%td
.controls.hidden-xs.pull-right
@@ -67,11 +63,9 @@
%span #{build.name}
- if can?(current_user, :update_pipeline, @project)
- &nbsp;
- - if commit.retryable? && commit.builds.failed.any?
+ - if commit.retryable?
= link_to retry_namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: 'btn has-tooltip', title: "Retry", method: :post do
= icon("repeat")
- &nbsp;
- - if commit.active?
+ - if commit.cancelable?
= link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do
= icon("remove")
diff --git a/app/views/projects/commit/_ci_commit.html.haml b/app/views/projects/commit/_ci_commit.html.haml
index ce5c550b441..32ff4d30977 100644
--- a/app/views/projects/commit/_ci_commit.html.haml
+++ b/app/views/projects/commit/_ci_commit.html.haml
@@ -1,24 +1,24 @@
.row-content-block.build-content.middle-block
.pull-right
- - if can?(current_user, :update_pipeline, @project)
+ - if can?(current_user, :update_pipeline, ci_commit.project)
- if ci_commit.builds.latest.failed.any?(&:retryable?)
- = link_to "Retry failed", retry_namespace_project_pipeline_path(@project.namespace, @project, ci_commit.id), class: 'btn btn-grouped btn-primary', method: :post
+ = link_to "Retry failed", retry_namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), class: 'btn btn-grouped btn-primary', method: :post
- if ci_commit.builds.running_or_pending.any?
- = link_to "Cancel running", cancel_namespace_project_pipeline_path(@project.namespace, @project, ci_commit.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
+ = link_to "Cancel running", cancel_namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
.oneline.clearfix
- if defined?(pipeline_details) && pipeline_details
Pipeline
- = link_to "##{ci_commit.id}", namespace_project_pipeline_path(@project.namespace, @project, ci_commit.id), class: "monospace"
+ = link_to "##{ci_commit.id}", namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), class: "monospace"
with
= pluralize ci_commit.statuses.count(:id), "build"
- if ci_commit.ref
for
- = link_to ci_commit.ref, namespace_project_commits_path(@project.namespace, @project, ci_commit.ref), class: "monospace"
+ = link_to ci_commit.ref, namespace_project_commits_path(ci_commit.project.namespace, ci_commit.project, ci_commit.ref), class: "monospace"
- if defined?(link_to_commit) && link_to_commit
for commit
- = link_to ci_commit.short_sha, namespace_project_commit_path(@project.namespace, @project, ci_commit.sha), class: "monospace"
+ = link_to ci_commit.short_sha, namespace_project_commit_path(ci_commit.project.namespace, ci_commit.project, ci_commit.sha), class: "monospace"
- if ci_commit.duration
in
= time_interval_in_words ci_commit.duration
@@ -31,7 +31,7 @@
%li= error
You can also test your .gitlab-ci.yml in the #{link_to "Lint", ci_lint_path}
-- if @project.builds_enabled? && !ci_commit.ci_yaml_file
+- if ci_commit.project.builds_enabled? && !ci_commit.ci_yaml_file
.bs-callout.bs-callout-warning
\.gitlab-ci.yml not found in this commit
@@ -45,7 +45,7 @@
%th Tags
%th Duration
%th Finished at
- - if @project.build_coverage_enabled?
+ - if ci_commit.project.build_coverage_enabled?
%th Coverage
%th
- ci_commit.statuses.stages.each do |stage|
diff --git a/app/views/projects/commit/_ci_stage.html.haml b/app/views/projects/commit/_ci_stage.html.haml
index aaa318e1eb3..ae7bb01223e 100644
--- a/app/views/projects/commit/_ci_stage.html.haml
+++ b/app/views/projects/commit/_ci_stage.html.haml
@@ -1,6 +1,7 @@
%tr
%th{colspan: 10}
%strong
+ %a{name: stage}
- status = statuses.latest.status
%span{class: "ci-status-link ci-status-icon-#{status}"}
= ci_icon_for_status(status)
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 028564c9305..6674d58417b 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -1,32 +1,35 @@
-.pull-right.commit-action-buttons
- %div
+.commit-info-row.commit-info-row-header
+ %span.hidden-xs Authored by
+ %strong
+ = commit_author_link(@commit, avatar: true, size: 24)
+ #{time_ago_with_tooltip(@commit.authored_date)}
+
+ .pull-right.commit-action-buttons
- if defined?(@notes_count) && @notes_count > 0
- %span.btn.disabled.btn-grouped
- %i.fa.fa-comment
+ %span.btn.disabled.btn-grouped.hidden-xs
+ = icon('comment')
= @notes_count
- .pull-left.btn-group
- %a.btn.btn-grouped.dropdown-toggle{ data: {toggle: :dropdown} }
- %i.fa.fa-download
- Download as
- %span.caret
- %ul.dropdown-menu
+ = link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-grouped hidden-xs hidden-sm" do
+ Browse Files
+ .dropdown.inline
+ %a.btn.btn-default.dropdown-toggle{ data: { toggle: "dropdown" } }
+ %span.hidden-xs Options
+ %span.caret.commit-options-dropdown-caret
+ %ul.dropdown-menu.dropdown-menu-align-right
+ %li.visible-xs-block.visible-sm-block
+ = link_to namespace_project_tree_path(@project.namespace, @project, @commit) do
+ Browse Files
+ - unless @commit.has_been_reverted?(current_user)
+ %li.clearfix
+ = revert_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id), has_tooltip: false)
+ %li.clearfix
+ = cherry_pick_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id), has_tooltip: false)
+ %li.divider
+ %li.dropdown-header
+ Download
- unless @commit.parents.length > 1
%li= link_to "Email Patches", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch)
%li= link_to "Plain Diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff)
- = link_to namespace_project_tree_path(@project.namespace, @project, @commit), class: "btn btn-grouped" do
- = icon('files-o')
- Browse Files
- - unless @commit.has_been_reverted?(current_user)
- = revert_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id))
- = cherry_pick_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id))
- %div
-
-%p
-.commit-info-row
- %span.light Authored by
- %strong
- = commit_author_link(@commit, avatar: true, size: 24)
- #{time_ago_with_tooltip(@commit.authored_date)}
- if @commit.different_committer?
.commit-info-row
@@ -36,8 +39,9 @@
#{time_ago_with_tooltip(@commit.committed_date)}
.commit-info-row
- %span.light Commit
- = link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace"
+ %span.hidden-xs.hidden-sm Commit
+ = link_to @commit.id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace hidden-xs hidden-sm"
+ = link_to @commit.short_id, namespace_project_commit_path(@project.namespace, @project, @commit), class: "monospace visible-xs-inline visible-sm-inline"
= clipboard_button(clipboard_text: @commit.id)
%span.cgray= pluralize(@commit.parents.count, "parent")
- @commit.parents.each do |parent|
@@ -59,10 +63,10 @@
.commit-box.content-block
%h3.commit-title
- = markdown escape_once(@commit.title), pipeline: :single_line
+ = markdown escape_once(@commit.title), pipeline: :single_line, author: @commit.author
- if @commit.description.present?
%pre.commit-description
- = preserve(markdown(escape_once(@commit.description), pipeline: :single_line))
+ = preserve(markdown(escape_once(@commit.description), pipeline: :single_line, author: @commit.author))
:javascript
$(".commit-info.branches").load("#{branches_namespace_project_commit_path(@project.namespace, @project, @commit.id)}");
diff --git a/app/views/projects/commit/builds.html.haml b/app/views/projects/commit/builds.html.haml
index 7118a4846c6..2f051fb90e0 100644
--- a/app/views/projects/commit/builds.html.haml
+++ b/app/views/projects/commit/builds.html.haml
@@ -1,7 +1,7 @@
- page_title "Builds", "#{@commit.title} (#{@commit.short_id})", "Commits"
-= render "projects/commits/header_title"
+
.prepend-top-default
= render "commit_box"
-= render "ci_menu"
+= render "ci_menu"
= render "builds"
diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml
index e5e3d696035..401cb4f7e30 100644
--- a/app/views/projects/commit/show.html.haml
+++ b/app/views/projects/commit/show.html.haml
@@ -1,8 +1,6 @@
- page_title "#{@commit.title} (#{@commit.short_id})", "Commits"
- page_description @commit.description
-= render "projects/commits/header_title"
-
.prepend-top-default
= render "commit_box"
- if @commit.status
diff --git a/app/views/projects/commits/_commit.atom.builder b/app/views/projects/commits/_commit.atom.builder
new file mode 100644
index 00000000000..1657fb46163
--- /dev/null
+++ b/app/views/projects/commits/_commit.atom.builder
@@ -0,0 +1,14 @@
+xml.entry do
+ xml.id namespace_project_commit_url(@project.namespace, @project, id: commit.id)
+ xml.link href: namespace_project_commit_url(@project.namespace, @project, id: commit.id)
+ xml.title truncate(commit.title, length: 80)
+ xml.updated commit.committed_date.xmlschema
+ xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(commit.author_email))
+
+ xml.author do |author|
+ xml.name commit.author_name
+ xml.email commit.author_email
+ end
+
+ xml.summary markdown(commit.description, pipeline: :single_line)
+end
diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml
index 655cb0ac3cb..367027182b6 100644
--- a/app/views/projects/commits/_commit.html.haml
+++ b/app/views/projects/commits/_commit.html.haml
@@ -24,7 +24,7 @@
- if commit.description?
.commit-row-description.js-toggle-content
%pre
- = preserve(markdown(escape_once(commit.description), pipeline: :single_line))
+ = preserve(markdown(escape_once(commit.description), pipeline: :single_line, author: commit.author))
.commit-row-info
by
diff --git a/app/views/projects/commits/_header_title.html.haml b/app/views/projects/commits/_header_title.html.haml
deleted file mode 100644
index e4385893dd9..00000000000
--- a/app/views/projects/commits/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Commits", project_commits_path(@project))
diff --git a/app/views/projects/commits/show.atom.builder b/app/views/projects/commits/show.atom.builder
index e310fafd82c..30bb7412073 100644
--- a/app/views/projects/commits/show.atom.builder
+++ b/app/views/projects/commits/show.atom.builder
@@ -6,18 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.id namespace_project_commits_url(@project.namespace, @project, @ref)
xml.updated @commits.first.committed_date.xmlschema if @commits.any?
- @commits.each do |commit|
- xml.entry do
- xml.id namespace_project_commit_url(@project.namespace, @project, id: commit.id)
- xml.link href: namespace_project_commit_url(@project.namespace, @project, id: commit.id)
- xml.title truncate(commit.title, length: 80)
- xml.updated commit.committed_date.xmlschema
- xml.media :thumbnail, width: "40", height: "40", url: image_url(avatar_icon(commit.author_email))
- xml.author do |author|
- xml.name commit.author_name
- xml.email commit.author_email
- end
- xml.summary markdown(commit.description, pipeline: :single_line)
- end
- end
+ xml << render(@commits) if @commits.any?
end
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index 088eaa28013..2c21923ed4f 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -1,5 +1,4 @@
- page_title "Commits", @ref
-= render "header_title"
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml
index 5e188dd0f3c..0b8ed23b305 100644
--- a/app/views/projects/compare/index.html.haml
+++ b/app/views/projects/compare/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Compare"
-= render "projects/commits/header_title"
= render "projects/commits/head"
.row-content-block
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index 62525168239..cdc34f51d6d 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -1,5 +1,4 @@
- page_title "#{params[:from]}...#{params[:to]}"
-= render "projects/commits/header_title"
= render "projects/commits/head"
diff --git a/app/views/projects/container_registry/_header_title.html.haml b/app/views/projects/container_registry/_header_title.html.haml
deleted file mode 100644
index f1863c52a3e..00000000000
--- a/app/views/projects/container_registry/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Container Registry", project_container_registry_path(@project))
diff --git a/app/views/projects/container_registry/index.html.haml b/app/views/projects/container_registry/index.html.haml
index e1e762410f2..993da27310f 100644
--- a/app/views/projects/container_registry/index.html.haml
+++ b/app/views/projects/container_registry/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Container Registry"
-= render "header_title"
%hr
@@ -37,4 +36,4 @@
%th
- @tags.each do |tag|
- = render 'tag', tag: tag \ No newline at end of file
+ = render 'tag', tag: tag
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index f6a53fddf17..18b125ff9d4 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -1,261 +1,221 @@
-.project-edit-container.prepend-top-default
- .project-edit-errors
- .project-edit-content
- .panel.panel-default
- .panel-heading
+.project-edit-container
+ .row.prepend-top-default
+ .col-lg-3.profile-settings-sidebar
+ %h4.prepend-top-0
Project settings
- .panel-body
- = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit_project form-horizontal fieldset-form" }, authenticity_token: true do |f|
-
- %fieldset
- .form-group.project_name_holder
- = f.label :name, class: 'control-label' do
- Project name
- .col-sm-10
- = f.text_field :name, class: "form-control", id: "project_name_edit"
-
-
- .form-group
- = f.label :description, class: 'control-label' do
- Project description
- %span.light (optional)
- .col-sm-10
- = f.text_area :description, class: "form-control", rows: 3, maxlength: 250
-
- - unless @project.empty_repo?
- .form-group
- = f.label :default_branch, "Default Branch", class: 'control-label'
- .col-sm-10= f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide'})
-
-
- = render 'shared/visibility_level', f: f, visibility_level: @project.visibility_level, can_change_visibility_level: can_change_visibility_level?(@project, current_user), form_model: @project
-
+ .col-lg-9
+ = form_for [@project.namespace.becomes(Namespace), @project], remote: true, html: { multipart: true, class: "edit-project" }, authenticity_token: true do |f|
+ %fieldset.append-bottom-0
.form-group
- = f.label :tag_list, "Tags", class: 'control-label'
- .col-sm-10
- = f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control"
- %p.help-block Separate tags with commas.
-
- %fieldset.features
- %legend
- Features:
- .form-group
- .col-sm-offset-2.col-sm-10
- .checkbox
- = f.label :issues_enabled do
- = f.check_box :issues_enabled
- %strong Issues
- %br
- %span.descr Lightweight issue tracking system for this project
-
- .form-group
- .col-sm-offset-2.col-sm-10
- .checkbox
- = f.label :merge_requests_enabled do
- = f.check_box :merge_requests_enabled
- %strong Merge Requests
- %br
- %span.descr Submit changes to be merged upstream
-
- .form-group
- .col-sm-offset-2.col-sm-10
- .checkbox
- = f.label :builds_enabled do
- = f.check_box :builds_enabled
- %strong Builds
- %br
- %span.descr Test and deploy your changes before merge
-
- .form-group
- .col-sm-offset-2.col-sm-10
- .checkbox
- = f.label :wiki_enabled do
- = f.check_box :wiki_enabled
- %strong Wiki
- %br
- %span.descr Pages for project documentation
-
- .form-group
- .col-sm-offset-2.col-sm-10
- .checkbox
- = f.label :snippets_enabled do
- = f.check_box :snippets_enabled
- %strong Snippets
- %br
- %span.descr Share code pastes with others out of git repository
-
- - if Gitlab.config.registry.enabled
- .form-group
- .col-sm-offset-2.col-sm-10
- .checkbox
- = f.label :container_registry_enabled do
- = f.check_box :container_registry_enabled
- %strong Container Registry
- %br
- %span.descr Enable Container Registry for this repository
-
- = render 'builds_settings', f: f
+ = f.label :name, class: 'label-light' do
+ Project name
+ = f.text_field :name, class: "form-control", id: "project_name_edit"
+ .form-group
+ = f.label :description, class: 'label-light' do
+ Project description
+ %span.light (optional)
+ = f.text_area :description, class: "form-control", rows: 3, maxlength: 250
- %fieldset.features
- %legend
- Project avatar:
+ - unless @project.empty_repo?
.form-group
- .col-sm-offset-2.col-sm-10
- - if @project.avatar?
- = project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160')
- %p.light
- - if @project.avatar_in_git
- Project avatar in repository: #{ @project.avatar_in_git }
- %p.light
- - if @project.avatar?
- You can change your project avatar here
- - else
- You can upload a project avatar here
- %a.choose-btn.btn.btn-sm.js-choose-project-avatar-button
- %i.icon-paper-clip
- %span Choose File ...
- &nbsp;
- %span.file_name.js-avatar-filename File name...
- = f.file_field :avatar, class: "js-project-avatar-input hidden"
- .light The maximum file size allowed is 200KB.
- - if @project.avatar?
- %hr
- = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar"
-
-
- .form-actions
- = f.submit 'Save changes', class: "btn btn-save"
-
-
-
- .danger-settings
- .panel.panel-default
- .panel-heading Housekeeping
- .errors-holder
- .panel-body
- %p
- Runs a number of housekeeping tasks within the current repository,
- such as compressing file revisions and removing unreachable objects.
- %br
-
- .form-actions
- = link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project),
- method: :post, class: "btn btn-default"
-
- - if can? current_user, :archive_project, @project
- - if @project.archived?
- .panel.panel-success
- .panel-heading
- Unarchive project
- .panel-body
- %p
- Unarchiving the project will mark its repository as active.
+ = f.label :default_branch, "Default Branch", class: 'label-light'
+ = f.select(:default_branch, @project.repository.branch_names, {}, {class: 'select2 select-wide'})
+ .form-group.project-visibility-level-holder
+ = f.label :visibility_level, class: 'label-light' do
+ Visibility Level
+ = link_to "(?)", help_page_path("public_access", "public_access")
+ - if can_change_visibility_level?(@project, current_user)
+ = render('shared/visibility_radios', model_method: :visibility_level, form: f, selected_level: @project.visibility_level, form_model: @project)
+ - else
+ .info
+ = visibility_level_icon(@project.visibility_level)
+ %strong
+ = visibility_level_label(@project.visibility_level)
+ .light= visibility_level_description(@project.visibility_level, @project)
+ .form-group
+ = f.label :tag_list, "Tags", class: 'label-light'
+ = f.text_field :tag_list, value: @project.tag_list.to_s, maxlength: 2000, class: "form-control"
+ %p.help-block Separate tags with commas.
+ %hr
+ %fieldset.features.append-bottom-0
+ %h5.prepend-top-0
+ Features
+ .form-group
+ .checkbox
+ = f.label :issues_enabled do
+ = f.check_box :issues_enabled
+ %strong Issues
%br
- The project can be committed to.
+ %span.descr Lightweight issue tracking system for this project
+ .form-group
+ .checkbox
+ = f.label :merge_requests_enabled do
+ = f.check_box :merge_requests_enabled
+ %strong Merge Requests
%br
- %strong Once active this project shows up in the search and on the dashboard.
-
- .form-actions
- = link_to 'Unarchive project', unarchive_namespace_project_path(@project.namespace, @project),
- data: { confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be committed to again." },
- method: :post, class: "btn btn-success"
- - else
- .panel.panel-warning
- .panel-heading
- Archive project
- .panel-body
- %p
- Archiving the project will mark its repository as read-only.
+ %span.descr Submit changes to be merged upstream
+ .form-group
+ .checkbox
+ = f.label :builds_enabled do
+ = f.check_box :builds_enabled
+ %strong Builds
+ %br
+ %span.descr Test and deploy your changes before merge
+ .form-group
+ .checkbox
+ = f.label :wiki_enabled do
+ = f.check_box :wiki_enabled
+ %strong Wiki
%br
- It is hidden from the dashboard and doesn't show up in searches.
+ %span.descr Pages for project documentation
+ .form-group
+ .checkbox
+ = f.label :snippets_enabled do
+ = f.check_box :snippets_enabled
+ %strong Snippets
%br
- %strong Archived projects cannot be committed to!
-
- .form-actions
- = link_to 'Archive project', archive_namespace_project_path(@project.namespace, @project),
- data: { confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to." },
- method: :post, class: "btn btn-warning"
- - else
- .nothing-here-block Only the project owner can archive a project
-
- .panel.panel-default.panel.panel-warning
- .panel-heading Rename repository
- .errors-holder
- .panel-body
- = form_for([@project.namespace.becomes(Namespace), @project], html: { class: 'form-horizontal' }) do |f|
- .form-group.project_name_holder
- = f.label :name, class: 'control-label' do
- Project name
- .col-sm-9
- .form-group
- = f.text_field :name, class: "form-control"
+ %span.descr Share code pastes with others out of git repository
+ - if Gitlab.config.registry.enabled
.form-group
- = f.label :path, class: 'control-label' do
- %span Path
- .col-sm-9
- .form-group
- .input-group
- .input-group-addon
- #{URI.join(root_url, @project.namespace.path)}/
- = f.text_field :path, class: 'form-control'
- %ul
- %li Be careful. Renaming a project's repository can have unintended side effects.
- %li You will need to update your local repositories to point to the new location.
- .form-actions
- = f.submit 'Rename project', class: "btn btn-warning"
-
- - if can?(current_user, :change_namespace, @project)
- .panel.panel-default.panel.panel-danger
- .panel-heading Transfer project
- .errors-holder
- .panel-body
- = form_for([@project.namespace.becomes(Namespace), @project], url: transfer_namespace_project_path(@project.namespace, @project), method: :put, remote: true, html: { class: 'transfer-project form-horizontal' }) do |f|
- .form-group
- = label_tag :new_namespace_id, nil, class: 'control-label' do
- %span Namespace
- .col-sm-9
- .form-group
- = select_tag :new_namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace', class: 'select2' }
- %ul
- %li Be careful. Changing the project's namespace can have unintended side effects.
- %li You can only transfer the project to namespaces you manage.
- %li You will need to update your local repositories to point to the new location.
- %li Project visibility level will be changed to match namespace rules when transfering to a group.
- .form-actions
- = f.submit 'Transfer project', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => transfer_project_message(@project) }
- - else
- .nothing-here-block Only the project owner can transfer a project
-
- - if @project.forked?
- - if can?(current_user, :remove_fork_project, @project)
- = form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_namespace_project_path(@project.namespace, @project), method: :delete, remote: true, html: { class: 'transfer-project form-horizontal' }) do |f|
- .panel.panel-default.panel.panel-danger
- .panel-heading Remove fork relationship
- .panel-body
- %p
- This will remove the fork relationship to source project
- #{link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project)}.
+ .checkbox
+ = f.label :container_registry_enabled do
+ = f.check_box :container_registry_enabled
+ %strong Container Registry
%br
- %strong Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source.
- .form-actions
- = button_to 'Remove fork relationship', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_fork_project_message(@project) }
+ %span.descr Enable Container Registry for this repository
+ %hr
+ = render 'builds_settings', f: f
+ %hr
+ %fieldset.features.append-bottom-default
+ %h5.prepend-top-0
+ Project avatar
+ .form-group
+ - if @project.avatar?
+ = project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar s160')
+ %p.light
+ - if @project.avatar_in_git
+ Project avatar in repository: #{ @project.avatar_in_git }
+ %a.choose-btn.btn.js-choose-project-avatar-button
+ Browse file...
+ %span.file_name.prepend-left-default.js-avatar-filename No file chosen
+ = f.file_field :avatar, class: "js-project-avatar-input hidden"
+ .help-block The maximum file size allowed is 200KB.
+ - if @project.avatar?
+ %hr
+ = link_to 'Remove avatar', namespace_project_avatar_path(@project.namespace, @project), data: { confirm: "Project avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar"
+ = f.submit 'Save changes', class: "btn btn-save"
+ .row.prepend-top-default
+ %hr
+ .row.prepend-top-default
+ .col-lg-3
+ %h4.prepend-top-0
+ Housekeeping
+ %p.append-bottom-0
+ %p
+ Runs a number of housekeeping tasks within the current repository,
+ such as compressing file revisions and removing unreachable objects.
+ .col-lg-9
+ = link_to 'Housekeeping', housekeeping_namespace_project_path(@project.namespace, @project),
+ method: :post, class: "btn btn-save"
+ %hr
+ - if can? current_user, :archive_project, @project
+ .row.prepend-top-default
+ .col-lg-3
+ %h4.warning-title.prepend-top-0
+ - if @project.archived?
+ Unarchive project
+ - else
+ Archive project
+ %p.append-bottom-0
+ - if @project.archived?
+ Unarchiving the project will mark its repository as active. The project can be committed to.
+ - else
+ Archiving the project will mark its repository as read-only. It is hidden from the dashboard and doesn't show up in searches.
+ .col-lg-9
+ - if @project.archived?
+ %p
+ %strong Once active this project shows up in the search and on the dashboard.
+ = link_to 'Unarchive project', unarchive_namespace_project_path(@project.namespace, @project),
+ data: { confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be committed to again." },
+ method: :post, class: "btn btn-success"
- else
- .nothing-here-block Only the project owner can remove the fork relationship.
-
- - if can?(current_user, :remove_project, @project)
- .panel.panel-default.panel.panel-danger
- .panel-heading Remove project
- .panel-body
- = form_tag(namespace_project_path(@project.namespace, @project), method: :delete, class: 'form-horizontal') do
- %p
- Removing the project will delete its repository and all related resources including issues, merge requests etc.
- %br
- %strong Removed projects cannot be restored!
- .form-actions
- = button_to 'Remove project', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_project_message(@project) }
- - else
- .nothing-here-block Only the project owner can remove a project.
-
+ %p
+ %strong Archived projects cannot be committed to!
+ = link_to 'Archive project', archive_namespace_project_path(@project.namespace, @project),
+ data: { confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to." },
+ method: :post, class: "btn btn-warning"
+ %hr
+ .row.prepend-top-default
+ .col-lg-3
+ %h4.prepend-top-0.warning-title
+ Rename repository
+ .col-lg-9
+ = form_for([@project.namespace.becomes(Namespace), @project]) do |f|
+ .form-group.project_name_holder
+ = f.label :name, class: 'label-light' do
+ Project name
+ .form-group
+ = f.text_field :name, class: "form-control"
+ .form-group
+ = f.label :path, class: 'label-light' do
+ %span Path
+ .form-group
+ .input-group
+ .input-group-addon
+ #{URI.join(root_url, @project.namespace.path)}/
+ = f.text_field :path, class: 'form-control'
+ %ul
+ %li Be careful. Renaming a project's repository can have unintended side effects.
+ %li You will need to update your local repositories to point to the new location.
+ = f.submit 'Rename project', class: "btn btn-warning"
+ - if can?(current_user, :change_namespace, @project)
+ %hr
+ .row.prepend-top-default
+ .col-lg-3
+ %h4.prepend-top-0.danger-title
+ Transfer project
+ .col-lg-9
+ = form_for([@project.namespace.becomes(Namespace), @project], url: transfer_namespace_project_path(@project.namespace, @project), method: :put, remote: true) do |f|
+ .form-group
+ = label_tag :new_namespace_id, nil, class: 'label-light' do
+ %span Namespace
+ .form-group
+ = select_tag :new_namespace_id, namespaces_options(@project.namespace_id), { prompt: 'Choose a project namespace', class: 'select2' }
+ %ul
+ %li Be careful. Changing the project's namespace can have unintended side effects.
+ %li You can only transfer the project to namespaces you manage.
+ %li You will need to update your local repositories to point to the new location.
+ %li Project visibility level will be changed to match namespace rules when transfering to a group.
+ = f.submit 'Transfer project', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => transfer_project_message(@project) }
+ - if @project.forked? && can?(current_user, :remove_fork_project, @project)
+ %hr
+ .row.prepend-top-default.append-bottom-default
+ .col-lg-3
+ %h4.prepend-top-0.danger-title
+ Remove fork relationship
+ %p.append-bottom-0
+ %p
+ This will remove the fork relationship to source project
+ = succeed "." do
+ = link_to @project.forked_from_project.name_with_namespace, project_path(@project.forked_from_project)
+ .col-lg-9
+ = form_for([@project.namespace.becomes(Namespace), @project], url: remove_fork_namespace_project_path(@project.namespace, @project), method: :delete, remote: true, html: { class: 'transfer-project' }) do |f|
+ %p
+ %strong Once removed, the fork relationship cannot be restored and you will no longer be able to send merge requests to the source.
+ = button_to 'Remove fork relationship', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_fork_project_message(@project) }
+ - if can?(current_user, :remove_project, @project)
+ %hr
+ .row.prepend-top-default.append-bottom-default
+ .col-lg-3
+ %h4.prepend-top-0.danger-title
+ Remove project
+ %p.append-bottom-0
+ Removing the project will delete its repository and all related resources including issues, merge requests etc.
+ .col-lg-9
+ = form_tag(namespace_project_path(@project.namespace, @project), method: :delete) do
+ %p
+ %strong Removed projects cannot be restored!
+ = button_to 'Remove project', '#', class: "btn btn-remove js-confirm-danger", data: { "confirm-danger-message" => remove_project_message(@project) }
.save-project-loader.hide
.center
@@ -264,5 +224,4 @@
Saving project.
%p Please wait a moment, this page will automatically refresh when ready.
-
= render 'shared/confirm_modal', phrase: @project.path
diff --git a/app/views/projects/find_file/show.html.haml b/app/views/projects/find_file/show.html.haml
index 1fe1d98bf13..9322c82904f 100644
--- a/app/views/projects/find_file/show.html.haml
+++ b/app/views/projects/find_file/show.html.haml
@@ -1,5 +1,4 @@
- page_title "Find File", @ref
-- header_title project_title(@project, "Files", project_files_path(@project))
.file-finder-holder.tree-holder.clearfix
.nav-block
diff --git a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
index 8129514964a..5bc5c71283e 100644
--- a/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
+++ b/app/views/projects/generic_commit_statuses/_generic_commit_status.html.haml
@@ -40,24 +40,20 @@
%td
= generic_commit_status.name
- .pull-right
- - if generic_commit_status.tags.any?
- - generic_commit_status.tags.each do |tag|
- %span.label.label-primary
- = tag
- - if defined?(retried) && retried
- %span.label.label-warning retried
+ %td
+ - if generic_commit_status.tags.any?
+ - generic_commit_status.tags.each do |tag|
+ %span.label.label-primary
+ = tag
+ - if defined?(retried) && retried
+ %span.label.label-warning retried
%td.duration
- if generic_commit_status.duration
- = icon("clock-o")
- &nbsp;
#{duration_in_words(generic_commit_status.finished_at, generic_commit_status.started_at)}
%td.timestamp
- if generic_commit_status.finished_at
- = icon("calendar")
- &nbsp;
%span #{time_ago_with_tooltip(generic_commit_status.finished_at)}
- if defined?(coverage) && coverage
diff --git a/app/views/projects/graphs/_head.html.haml b/app/views/projects/graphs/_head.html.haml
index 79a56647c53..8becaea246f 100644
--- a/app/views/projects/graphs/_head.html.haml
+++ b/app/views/projects/graphs/_head.html.haml
@@ -1,3 +1,4 @@
+- page_specific_javascripts asset_path("graphs/application.js")
%ul.nav-links
= nav_link(action: :show) do
= link_to 'Contributors', namespace_project_graph_path
diff --git a/app/views/projects/graphs/_header_title.html.haml b/app/views/projects/graphs/_header_title.html.haml
deleted file mode 100644
index 1e2f61cd22b..00000000000
--- a/app/views/projects/graphs/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Graphs", namespace_project_graph_path(@project.namespace, @project, current_ref))
diff --git a/app/views/projects/graphs/ci.html.haml b/app/views/projects/graphs/ci.html.haml
index 9f05be9982b..19ccc125ea8 100644
--- a/app/views/projects/graphs/ci.html.haml
+++ b/app/views/projects/graphs/ci.html.haml
@@ -1,5 +1,4 @@
- page_title "Continuous Integration", "Graphs"
-= render "header_title"
= render 'head'
.row-content-block.append-bottom-default
.oneline
diff --git a/app/views/projects/graphs/commits.html.haml b/app/views/projects/graphs/commits.html.haml
index da9f648cc9c..d9b2fb6c065 100644
--- a/app/views/projects/graphs/commits.html.haml
+++ b/app/views/projects/graphs/commits.html.haml
@@ -1,5 +1,4 @@
- page_title "Commits", "Graphs"
-= render "header_title"
= render 'head'
.row-content-block.append-bottom-default
diff --git a/app/views/projects/graphs/languages.html.haml b/app/views/projects/graphs/languages.html.haml
index ebecab1dbfc..249c16f4709 100644
--- a/app/views/projects/graphs/languages.html.haml
+++ b/app/views/projects/graphs/languages.html.haml
@@ -1,5 +1,4 @@
- page_title "Languages", "Graphs"
-= render "header_title"
= render 'head'
.row-content-block.append-bottom-default
diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml
index ad4a932d391..33970e7b909 100644
--- a/app/views/projects/graphs/show.html.haml
+++ b/app/views/projects/graphs/show.html.haml
@@ -1,5 +1,4 @@
- page_title "Contributors", "Graphs"
-= render "header_title"
= render 'head'
.row-content-block.append-bottom-default
@@ -19,7 +18,7 @@
.header.clearfix
%h3#date_header.page-title
%p.light
- Commits to #{@ref}, excluding merge commits. Limited by 6,000 commits
+ Commits to #{@ref}, excluding merge commits. Limited to 6,000 commits.
%input#brush_change{:type => "hidden"}
.graphs
#contributors-master
diff --git a/app/views/projects/hooks/_project_hook.html.haml b/app/views/projects/hooks/_project_hook.html.haml
index 62eba5888a4..8151187d499 100644
--- a/app/views/projects/hooks/_project_hook.html.haml
+++ b/app/views/projects/hooks/_project_hook.html.haml
@@ -3,7 +3,7 @@
.col-md-8.col-lg-7
%strong.light-header= hook.url
%div
- - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger|
+ - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events wiki_page_events).each do |trigger|
- if hook.send(trigger)
%span.label.label-gray.deploy-project-label= trigger.titleize
.col-md-4.col-lg-5.text-right-lg.prepend-top-5
diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml
index cffe9a01a96..917a0b805b1 100644
--- a/app/views/projects/hooks/index.html.haml
+++ b/app/views/projects/hooks/index.html.haml
@@ -64,6 +64,13 @@
Build events
%p.light
This url will be triggered when the build status changes
+ %div
+ = f.check_box :wiki_page_events, class: 'pull-left'
+ .prepend-left-20
+ = f.label :wiki_page_events, class: 'label-light append-bottom-0' do
+ Wiki Page events
+ %p.light
+ This url will be triggered when a wiki page is created/updated
.form-group
= f.label :enable_ssl_verification, "SSL verification", class: "label-light"
%div
diff --git a/app/views/projects/issues/_header_title.html.haml b/app/views/projects/issues/_header_title.html.haml
deleted file mode 100644
index 99f03549c44..00000000000
--- a/app/views/projects/issues/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Issues", namespace_project_issues_path(@project.namespace, @project))
diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml
index 5cf70ea3bb7..78f64150601 100644
--- a/app/views/projects/issues/_issue.html.haml
+++ b/app/views/projects/issues/_issue.html.haml
@@ -6,7 +6,7 @@
.issue-title.title
%span.issue-title-text
= confidential_icon(issue)
- = link_to_gfm issue.title, issue_path(issue)
+ = link_to issue.title, issue_path(issue)
%ul.controls
- if issue.closed?
%li
diff --git a/app/views/projects/issues/_merge_requests.html.haml b/app/views/projects/issues/_merge_requests.html.haml
index e953353567e..2f9dc867d0d 100644
--- a/app/views/projects/issues/_merge_requests.html.haml
+++ b/app/views/projects/issues/_merge_requests.html.haml
@@ -24,5 +24,8 @@
MERGED
- elsif merge_request.closed?
CLOSED
- - if @closed_by_merge_requests.present?
+ %li
= render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count}
+ - if @closed_by_merge_requests.present?
+ %li
+ = render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count}
diff --git a/app/views/projects/issues/edit.html.haml b/app/views/projects/issues/edit.html.haml
index 20216297d25..7cf1923456e 100644
--- a/app/views/projects/issues/edit.html.haml
+++ b/app/views/projects/issues/edit.html.haml
@@ -1,5 +1,4 @@
- page_title "Edit", "#{@issue.title} (##{@issue.iid})", "Issues"
-= render "header_title"
%h3.page-title
Edit Issue ##{@issue.iid}
diff --git a/app/views/projects/issues/index.atom.builder b/app/views/projects/issues/index.atom.builder
index ee8a9414657..7ad7c9c87e8 100644
--- a/app/views/projects/issues/index.atom.builder
+++ b/app/views/projects/issues/index.atom.builder
@@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.id namespace_project_issues_url(@project.namespace, @project)
xml.updated @issues.first.created_at.xmlschema if @issues.any?
- @issues.each do |issue|
- issue_to_atom(xml, issue)
- end
+ xml << render(partial: 'issues/issue', collection: @issues) if @issues.any?
end
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index efa7642b2dc..19a6f4a91f6 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Issues"
-= render "header_title"
= content_for :meta_tags do
- if current_user
diff --git a/app/views/projects/issues/new.html.haml b/app/views/projects/issues/new.html.haml
index b317a0c1cf4..e8aae0f47e2 100644
--- a/app/views/projects/issues/new.html.haml
+++ b/app/views/projects/issues/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New Issue"
-= render "header_title"
%h3.page-title
New Issue
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index bde80bbb54b..f3b0469b7d4 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -1,7 +1,6 @@
- page_title "#{@issue.title} (##{@issue.iid})", "Issues"
- page_description @issue.description
- page_card_attributes @issue.card_attributes
-- header_title project_title(@project, "Issues", namespace_project_issues_path(@project.namespace, @project))
.clearfix.detail-page-header
.issuable-header
@@ -53,12 +52,12 @@
.issue-details.issuable-details
.detail-page-description.content-block
%h2.title
- = markdown escape_once(@issue.title), pipeline: :single_line
+ = markdown escape_once(@issue.title), pipeline: :single_line, author: @issue.author
- if @issue.description.present?
.description{ class: can?(current_user, :update_issue, @issue) ? 'js-task-list-container' : '' }
.wiki
= preserve do
- = markdown(@issue.description, cache_key: [@issue, "description"])
+ = markdown(@issue.description, cache_key: [@issue, "description"], author: @issue.author)
%textarea.hidden.js-task-list-field
= @issue.description
= edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue_edited_ago')
diff --git a/app/views/projects/labels/_header_title.html.haml b/app/views/projects/labels/_header_title.html.haml
deleted file mode 100644
index abe28da483b..00000000000
--- a/app/views/projects/labels/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Labels", namespace_project_labels_path(@project.namespace, @project))
diff --git a/app/views/projects/labels/edit.html.haml b/app/views/projects/labels/edit.html.haml
index 675a805e12f..6901ba13ab7 100644
--- a/app/views/projects/labels/edit.html.haml
+++ b/app/views/projects/labels/edit.html.haml
@@ -1,5 +1,4 @@
- page_title "Edit", @label.name, "Labels"
-= render "header_title"
%h3.page-title
Edit Label
diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml
index cc41130a9dc..2557d1a4d5b 100644
--- a/app/views/projects/labels/index.html.haml
+++ b/app/views/projects/labels/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Labels"
-= render "header_title"
.top-area
.nav-text
@@ -18,6 +17,6 @@
- else
.nothing-here-block
- if can? current_user, :admin_label, @project
- Create first label or #{link_to 'generate', generate_namespace_project_labels_path(@project.namespace, @project), method: :post} default set of labels
+ Create a label or #{link_to 'generate a default set of labels', generate_namespace_project_labels_path(@project.namespace, @project), method: :post}.
- else
No labels created
diff --git a/app/views/projects/labels/new.html.haml b/app/views/projects/labels/new.html.haml
index e20fd7d6891..49ddf901619 100644
--- a/app/views/projects/labels/new.html.haml
+++ b/app/views/projects/labels/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New Label"
-= render "header_title"
%h3.page-title
New Label
diff --git a/app/views/projects/merge_requests/_header_title.html.haml b/app/views/projects/merge_requests/_header_title.html.haml
deleted file mode 100644
index 669a9b06bdf..00000000000
--- a/app/views/projects/merge_requests/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Merge Requests", namespace_project_merge_requests_path(@project.namespace, @project))
diff --git a/app/views/projects/merge_requests/_merge_request.html.haml b/app/views/projects/merge_requests/_merge_request.html.haml
index 2c54171c6bd..c02f94490a0 100644
--- a/app/views/projects/merge_requests/_merge_request.html.haml
+++ b/app/views/projects/merge_requests/_merge_request.html.haml
@@ -1,7 +1,7 @@
%li{ class: mr_css_classes(merge_request) }
.merge-request-title.title
%span.merge-request-title-text
- = link_to_gfm merge_request.title, merge_request_path(merge_request)
+ = link_to merge_request.title, merge_request_path(merge_request)
%ul.controls
- if merge_request.merged?
%li
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 290753d57c6..7af227129ec 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -1,7 +1,6 @@
- page_title "#{@merge_request.title} (#{@merge_request.to_reference})", "Merge Requests"
- page_description @merge_request.description
- page_card_attributes @merge_request.card_attributes
-- header_title project_title(@project, "Merge Requests", namespace_project_merge_requests_path(@project.namespace, @project))
- if diff_view == 'parallel'
- fluid_layout true
diff --git a/app/views/projects/merge_requests/dropdowns/_branch.html.haml b/app/views/projects/merge_requests/dropdowns/_branch.html.haml
index ba8d9a5835c..a60c445aa51 100644
--- a/app/views/projects/merge_requests/dropdowns/_branch.html.haml
+++ b/app/views/projects/merge_requests/dropdowns/_branch.html.haml
@@ -1,5 +1,5 @@
%ul
- branches.each do |branch|
%li
- %a{ href: '#', class: "#{('is-active' if selected == branch)}", data: { id: branch } }
+ %a{ href: '#', class: "#{('is-active' if selected == branch)}", title: branch, data: { id: branch } }
= branch
diff --git a/app/views/projects/merge_requests/edit.html.haml b/app/views/projects/merge_requests/edit.html.haml
index b31ea5e5321..03159f123f3 100644
--- a/app/views/projects/merge_requests/edit.html.haml
+++ b/app/views/projects/merge_requests/edit.html.haml
@@ -1,5 +1,4 @@
- page_title "Edit", "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
-= render "header_title"
%h3.page-title
Edit Merge Request #{@merge_request.to_reference}
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index e56a44e0a79..b517e874b0f 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Merge Requests"
-= render "header_title"
= render 'projects/last_push'
diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml
index f5bf16ef3ad..a00d3128ffe 100644
--- a/app/views/projects/merge_requests/invalid.html.haml
+++ b/app/views/projects/merge_requests/invalid.html.haml
@@ -1,5 +1,4 @@
- page_title "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
-= render "header_title"
.merge-request
= render "projects/merge_requests/show/mr_title"
diff --git a/app/views/projects/merge_requests/new.html.haml b/app/views/projects/merge_requests/new.html.haml
index d259968030e..2e798ce780a 100644
--- a/app/views/projects/merge_requests/new.html.haml
+++ b/app/views/projects/merge_requests/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New Merge Request"
-= render "header_title"
- if @merge_request.can_be_created && !params[:change_branches]
= render 'new_submit'
diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml
index a23bd8d18d0..ebf18f6ac85 100644
--- a/app/views/projects/merge_requests/show/_mr_box.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_box.html.haml
@@ -1,13 +1,13 @@
.detail-page-description.content-block
%h2.title
- = markdown escape_once(@merge_request.title), pipeline: :single_line
+ = markdown escape_once(@merge_request.title), pipeline: :single_line, author: @merge_request.author
%div
- if @merge_request.description.present?
.description{class: can?(current_user, :update_merge_request, @merge_request) ? 'js-task-list-container' : ''}
.wiki
= preserve do
- = markdown(@merge_request.description, cache_key: [@merge_request, "description"])
+ = markdown(@merge_request.description, cache_key: [@merge_request, "description"], author: @merge_request.author)
%textarea.hidden.js-task-list-field
= @merge_request.description
diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml
index 55dbae598d3..13359abede7 100644
--- a/app/views/projects/merge_requests/widget/_open.html.haml
+++ b/app/views/projects/merge_requests/widget/_open.html.haml
@@ -26,4 +26,4 @@
%i.fa.fa-check
Accepting this merge request will close #{"issue".pluralize(@closes_issues.size)}
= succeed '.' do
- != markdown issues_sentence(@closes_issues), pipeline: :gfm
+ != markdown issues_sentence(@closes_issues), pipeline: :gfm, author: @merge_request.author
diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml
index 3c68d61c4b5..b79508bdc34 100644
--- a/app/views/projects/merge_requests/widget/_show.html.haml
+++ b/app/views/projects/merge_requests/widget/_show.html.haml
@@ -13,7 +13,7 @@
check_enable: #{@merge_request.unchecked? ? "true" : "false"},
ci_status_url: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
gitlab_icon: "#{asset_path 'gitlab_logo.png'}",
- ci_status: "",
+ ci_status: "#{@merge_request.ci_commit ? @merge_request.ci_commit.status : ''}",
ci_message: {
normal: "Build {{status}} for \"{{title}}\"",
preparing: "{{status}} build for \"{{title}}\""
@@ -26,4 +26,10 @@
builds_path: "#{builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}"
};
+ if (typeof merge_request_widget !== 'undefined') {
+ clearInterval(merge_request_widget.fetchBuildStatusInterval);
+ merge_request_widget.cancelPolling();
+ merge_request_widget.clearEventListeners();
+ }
+
merge_request_widget = new MergeRequestWidget(opts);
diff --git a/app/views/projects/milestones/_header_title.html.haml b/app/views/projects/milestones/_header_title.html.haml
deleted file mode 100644
index 5f4b6982a6d..00000000000
--- a/app/views/projects/milestones/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Milestones", namespace_project_milestones_path(@project.namespace, @project))
diff --git a/app/views/projects/milestones/edit.html.haml b/app/views/projects/milestones/edit.html.haml
index 43f8863163d..be682226ab6 100644
--- a/app/views/projects/milestones/edit.html.haml
+++ b/app/views/projects/milestones/edit.html.haml
@@ -1,5 +1,4 @@
- page_title "Edit", @milestone.title, "Milestones"
-= render "header_title"
%h3.page-title
Edit Milestone ##{@milestone.iid}
diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml
index abe567af1dd..e6133b22f96 100644
--- a/app/views/projects/milestones/index.html.haml
+++ b/app/views/projects/milestones/index.html.haml
@@ -1,6 +1,4 @@
- page_title "Milestones"
-= render "header_title"
-
.top-area
= render 'shared/milestones_filter'
diff --git a/app/views/projects/milestones/new.html.haml b/app/views/projects/milestones/new.html.haml
index 0d016f78313..7f372b41698 100644
--- a/app/views/projects/milestones/new.html.haml
+++ b/app/views/projects/milestones/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New Milestone"
-= render "header_title"
%h3.page-title
New Milestone
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 6ec84660157..19944e3e023 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -1,8 +1,6 @@
- page_title @milestone.title, "Milestones"
- page_description @milestone.description
-= render "header_title"
-
.detail-page-header
.status-box{ class: status_box_class(@milestone) }
- if @milestone.closed?
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index 8065663ca2a..326180ebe4e 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -1,5 +1,4 @@
- page_title "Network", @ref
-= render "projects/commits/header_title"
= render "projects/commits/head"
= render "head"
.project-network
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index a4c6094c69a..f9ac16b32f3 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -1,5 +1,5 @@
- page_title 'New Project'
-- header_title "Projects", root_path
+- header_title "Projects", dashboard_projects_path
%h3.page-title
New Project
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 9fbc9a45549..f1045bbd8c3 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -29,7 +29,7 @@
.note-body{class: note_editable ? 'js-task-list-container' : ''}
.note-text
= preserve do
- = markdown(note.note, pipeline: :note, cache_key: [note, "note"])
+ = markdown(note.note, pipeline: :note, cache_key: [note, "note"], author: note.author)
- if note_editable
= render 'projects/notes/edit_form', note: note
= edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago', include_author: true)
diff --git a/app/views/projects/pipelines/_head.html.haml b/app/views/projects/pipelines/_head.html.haml
new file mode 100644
index 00000000000..2c8ae625e67
--- /dev/null
+++ b/app/views/projects/pipelines/_head.html.haml
@@ -0,0 +1,14 @@
+%ul.nav-links
+ - if project_nav_tab? :pipelines
+ = nav_link(controller: :pipelines) do
+ = link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
+ %span
+ Pipelines
+ %span.badge.count.ci_counter= number_with_delimiter(@project.ci_commits.running_or_pending.count)
+
+ - if project_nav_tab? :builds
+ = nav_link(controller: %w(builds)) do
+ = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
+ %span
+ Builds
+ %span.badge.count.builds_counter= number_with_delimiter(@project.builds.running_or_pending.count(:all))
diff --git a/app/views/projects/pipelines/_header_title.html.haml b/app/views/projects/pipelines/_header_title.html.haml
deleted file mode 100644
index faf63d64a79..00000000000
--- a/app/views/projects/pipelines/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Pipelines", project_pipelines_path(@project))
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index 9d5b6d367c9..453767920b5 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -1,5 +1,5 @@
- page_title "Pipelines"
-= render "header_title"
+= render "projects/pipelines/head"
.top-area
%ul.nav-links
@@ -36,15 +36,7 @@
= icon('wrench')
%span CI Lint
-.row-content-block
- - if @scope == 'running'
- Running pipelines for this project
- - elsif @scope.nil?
- Pipelines for this project
- - else
- #{@scope.titleize} for this project
-
-%ul.content-list
+%ul.content-list.pipelines
- stages = @pipelines.stages
- if @pipelines.blank?
%li
@@ -56,10 +48,10 @@
%th ID
%th Commit
- stages.each do |stage|
- %th
- %span.pipeline-stage.has-tooltip{ title: "#{stage.titleize}" }
+ %th.stage
+ %span.has-tooltip{ title: "#{stage.titleize}" }
= stage.titleize.pluralize
- %th
+ %th Duration
%th
= render @pipelines, commit_sha: true, stage: true, allow_retry: true, stages: stages
diff --git a/app/views/projects/pipelines/new.html.haml b/app/views/projects/pipelines/new.html.haml
index b97c9f5f3b6..5f4ec2e40c8 100644
--- a/app/views/projects/pipelines/new.html.haml
+++ b/app/views/projects/pipelines/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New Pipeline"
-= render "header_title"
%h3.page-title
New Pipeline
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index b082d4d5da8..2aad5602414 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -1,6 +1,5 @@
- page_title "Pipeline"
-= render "header_title"
.prepend-top-default
- if @commit
= render "projects/pipelines/info"
diff --git a/app/views/projects/project_members/_header_title.html.haml b/app/views/projects/project_members/_header_title.html.haml
deleted file mode 100644
index a31f0a37fa2..00000000000
--- a/app/views/projects/project_members/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Members", namespace_project_project_members_path(@project.namespace, @project))
diff --git a/app/views/projects/project_members/import.html.haml b/app/views/projects/project_members/import.html.haml
index 189906498cb..eef97107d77 100644
--- a/app/views/projects/project_members/import.html.haml
+++ b/app/views/projects/project_members/import.html.haml
@@ -1,5 +1,4 @@
- page_title "Import members"
-= render "header_title"
%h3.page-title
Import members from another project
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index ebcfc907ebb..15dc064e7ea 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Members"
-= render "header_title"
.project-members-page.prepend-top-default
- if can?(current_user, :admin_project_member, @project)
diff --git a/app/views/projects/releases/edit.html.haml b/app/views/projects/releases/edit.html.haml
index 0d59cec322c..835398b6f98 100644
--- a/app/views/projects/releases/edit.html.haml
+++ b/app/views/projects/releases/edit.html.haml
@@ -1,5 +1,4 @@
- page_title "Edit", @tag.name, "Tags"
-= render "projects/commits/header_title"
= render "projects/commits/head"
.row-content-block
diff --git a/app/views/projects/repositories/_feed.html.haml b/app/views/projects/repositories/_feed.html.haml
index 6ca919f7f80..43a6fdfd103 100644
--- a/app/views/projects/repositories/_feed.html.haml
+++ b/app/views/projects/repositories/_feed.html.haml
@@ -12,7 +12,7 @@
= link_to namespace_project_commits_path(@project.namespace, @project, commit.id) do
%code= commit.short_id
= image_tag avatar_icon(commit.author_email), class: "", width: 16, alt: ''
- = markdown escape_once(truncate(commit.title, length: 40)), pipeline: :single_line
+ = markdown escape_once(truncate(commit.title, length: 40)), pipeline: :single_line, author: commit.author
%td
%span.pull-right.cgray
= time_ago_with_tooltip(commit.committed_date)
diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml
index 30cd1263a12..8ae9f0d95f7 100644
--- a/app/views/projects/runners/_specific_runners.html.haml
+++ b/app/views/projects/runners/_specific_runners.html.haml
@@ -8,7 +8,7 @@
Install GitLab Runner software.
Checkout the #{link_to 'GitLab Runner section', 'https://about.gitlab.com/gitlab-ci/#gitlab-runner', target: '_blank'} to install it
%li
- Specify following URL during runner setup:
+ Specify the following URL during runner setup:
%code #{ci_root_url(only_path: false)}
%li
Use the following registration token during setup:
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 1b70880043a..1f13ea28b4e 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -1,18 +1,16 @@
-%h3.page-title
- = @service.title
- = boolean_to_icon @service.activated?
+.row.prepend-top-default.append-bottom-default
+ .col-lg-3
+ %h4.prepend-top-0
+ = @service.title
+ = boolean_to_icon @service.activated?
-%p= @service.description
-
-%hr
-
-= form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form|
- = render 'shared/service_settings', form: form
-
- .form-actions
- = form.submit 'Save changes', class: 'btn btn-save'
- &nbsp;
- - if @service.valid? && @service.activated?
- - disabled = @service.can_test? ? '':'disabled'
- = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: "btn #{disabled}"
- = link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
+ %p= @service.description
+ .col-lg-9
+ = form_for(@service, as: :service, url: namespace_project_service_path(@project.namespace, @project, @service.to_param), method: :put, html: { class: 'form-horizontal' }) do |form|
+ = render 'shared/service_settings', form: form
+ = form.submit 'Save changes', class: 'btn btn-save'
+ &nbsp;
+ - if @service.valid? && @service.activated?
+ - disabled = @service.can_test? ? '':'disabled'
+ = link_to 'Test settings', test_namespace_project_service_path(@project.namespace, @project, @service.to_param), class: "btn #{disabled}"
+ = link_to "Cancel", namespace_project_services_path(@project.namespace, @project), class: "btn btn-cancel"
diff --git a/app/views/projects/services/index.html.haml b/app/views/projects/services/index.html.haml
index c1356f6db02..4a33a5bc6f6 100644
--- a/app/views/projects/services/index.html.haml
+++ b/app/views/projects/services/index.html.haml
@@ -1,24 +1,32 @@
- page_title "Services"
-%h3.page-title Project services
-%p.light Project services allow you to integrate GitLab with other applications
-.table-holder
- %table.table
- %thead
- %tr
- %th
- %th Service
- %th Description
- %th Last edit
- - @services.sort_by(&:title).each do |service|
- %tr
- %td
- = boolean_to_icon service.activated?
- %td
- = link_to edit_namespace_project_service_path(@project.namespace, @project, service.to_param) do
- %strong= service.title
- %td
- = service.description
- %td.light
- = time_ago_in_words service.updated_at
- ago
+.row.prepend-top-default.append-bottom-default
+ .col-lg-3
+ %h4.prepend-top-0
+ Project services
+ %p Project services allow you to integrate GitLab with other applications
+ .col-lg-9
+ %table.table
+ %colgroup
+ %col
+ %col
+ %col.hidden-xs
+ %col{ width: "120" }
+ %thead
+ %tr
+ %th
+ %th Service
+ %th.hidden-xs Description
+ %th Last edit
+ - @services.sort_by(&:title).each do |service|
+ %tr
+ %td
+ = boolean_to_icon service.activated?
+ %td
+ = link_to edit_namespace_project_service_path(@project.namespace, @project, service.to_param) do
+ %strong= service.title
+ %td.hidden-xs
+ = service.description
+ %td.light
+ = time_ago_in_words service.updated_at
+ ago
diff --git a/app/views/projects/show.atom.builder b/app/views/projects/show.atom.builder
index 9b3d3f069d9..11310d5e1e1 100644
--- a/app/views/projects/show.atom.builder
+++ b/app/views/projects/show.atom.builder
@@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.id namespace_project_url(@project.namespace, @project)
xml.updated @events[0].updated_at.xmlschema if @events[0]
- @events.each do |event|
- event_to_atom(xml, event)
- end
+ xml << render(@events) if @events.any?
end
diff --git a/app/views/projects/snippets/_actions.html.haml b/app/views/projects/snippets/_actions.html.haml
index 4a515469422..bf57beb9d07 100644
--- a/app/views/projects/snippets/_actions.html.haml
+++ b/app/views/projects/snippets/_actions.html.haml
@@ -1,11 +1,27 @@
-= link_to new_namespace_project_snippet_path(@project.namespace, @project), class: 'btn btn-grouped new-snippet-link', title: "New Snippet" do
- = icon('plus')
- New Snippet
-- if can?(current_user, :admin_project_snippet, @snippet)
- = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-remove", title: 'Delete Snippet' do
- = icon('trash-o')
- Delete
-- if can?(current_user, :update_project_snippet, @snippet)
- = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-grouped snippable-edit" do
- = icon('pencil-square-o')
- Edit
+.hidden-xs
+ = link_to new_namespace_project_snippet_path(@project.namespace, @project), class: 'btn btn-grouped btn-create new-snippet-link', title: "New Snippet" do
+ = icon('plus')
+ New Snippet
+ - if can?(current_user, :update_project_snippet, @snippet)
+ = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-grouped snippable-edit" do
+ Edit
+ - if can?(current_user, :update_project_snippet, @snippet)
+ = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-warning", title: 'Delete Snippet' do
+ Delete
+.visible-xs-block.dropdown
+ %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } }
+ Options
+ %span.caret
+ .dropdown-menu.dropdown-menu-full-width
+ %ul
+ %li
+ = link_to new_namespace_project_snippet_path(@project.namespace, @project), title: "New Snippet" do
+ New Snippet
+ - if can?(current_user, :update_project_snippet, @snippet)
+ %li
+ = link_to edit_namespace_project_snippet_path(@project.namespace, @project, @snippet) do
+ Edit
+ - if can?(current_user, :update_project_snippet, @snippet)
+ %li
+ = link_to namespace_project_snippet_path(@project.namespace, @project, @snippet), method: :delete, data: { confirm: "Are you sure?" }, title: 'Delete Snippet' do
+ Delete
diff --git a/app/views/projects/snippets/_header_title.html.haml b/app/views/projects/snippets/_header_title.html.haml
deleted file mode 100644
index 04f0bbe9853..00000000000
--- a/app/views/projects/snippets/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, "Snippets", namespace_project_snippets_path(@project.namespace, @project))
diff --git a/app/views/projects/snippets/edit.html.haml b/app/views/projects/snippets/edit.html.haml
index dc3ea1fcf12..216f70f5605 100644
--- a/app/views/projects/snippets/edit.html.haml
+++ b/app/views/projects/snippets/edit.html.haml
@@ -1,5 +1,4 @@
- page_title "Edit", @snippet.title, "Snippets"
-= render "header_title"
%h3.page-title
Edit Snippet
diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml
index 103ff447464..96fee3b17b2 100644
--- a/app/views/projects/snippets/index.html.haml
+++ b/app/views/projects/snippets/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Snippets"
-= render "header_title"
.row-content-block.top-block
.pull-right
diff --git a/app/views/projects/snippets/new.html.haml b/app/views/projects/snippets/new.html.haml
index e57237991b4..772a594269c 100644
--- a/app/views/projects/snippets/new.html.haml
+++ b/app/views/projects/snippets/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New Snippets"
-= render "header_title"
%h3.page-title
New Snippet
diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml
index 7c599563ce4..bae4d8f349f 100644
--- a/app/views/projects/snippets/show.html.haml
+++ b/app/views/projects/snippets/show.html.haml
@@ -1,18 +1,15 @@
- page_title @snippet.title, "Snippets"
-= render "header_title"
.snippet-holder
= render 'shared/snippets/header'
- %article.file-holder
- .file-title
+ %article.file-holder.file-holder-no-border.snippet-file-content
+ .file-title.file-title-clear
= blob_icon 0, @snippet.file_name
- %strong
- = @snippet.file_name
+ = @snippet.file_name
.file-actions.hidden-xs
= clipboard_button(clipboard_target: ".blob-content[data-blob-id='#{@snippet.id}']")
= link_to 'Raw', raw_namespace_project_snippet_path(@project.namespace, @project, @snippet), class: "btn btn-sm", target: "_blank"
-
= render 'shared/snippets/blob'
%div#notes= render "projects/notes/notes_with_form"
diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml
index dc6ece30dd2..8f381663e6e 100644
--- a/app/views/projects/tags/index.html.haml
+++ b/app/views/projects/tags/index.html.haml
@@ -1,5 +1,4 @@
- page_title "Tags"
-= render "projects/commits/header_title"
= render "projects/commits/head"
.row-content-block
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index f9306453297..3a097750d6e 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -1,5 +1,4 @@
- page_title "New Tag"
-= render "projects/commits/header_title"
- if @error
.alert.alert-danger
diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml
index 9f1424aecc7..b7d7d5c5382 100644
--- a/app/views/projects/tags/show.html.haml
+++ b/app/views/projects/tags/show.html.haml
@@ -1,5 +1,4 @@
- page_title @tag.name, "Tags"
-= render "projects/commits/header_title"
= render "projects/commits/head"
.row-content-block
diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml
index 91fb2a44594..7e9ba09c720 100644
--- a/app/views/projects/tree/show.html.haml
+++ b/app/views/projects/tree/show.html.haml
@@ -1,5 +1,4 @@
- page_title @path.presence || "Files", @ref
-- header_title project_title(@project, "Files", project_files_path(@project))
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
diff --git a/app/views/projects/triggers/index.html.haml b/app/views/projects/triggers/index.html.haml
index d73ac987161..7f3de47d7df 100644
--- a/app/views/projects/triggers/index.html.haml
+++ b/app/views/projects/triggers/index.html.haml
@@ -5,7 +5,7 @@
%h4.prepend-top-0
= page_title
%p
- Triggers can be used to force a rebuild of a specific branch or tag with an API call.
+ Triggers can force a specific branch or tag to rebuild with an API call.
.col-lg-9
%h5.prepend-top-0
Your triggers
@@ -19,7 +19,7 @@
= render partial: 'trigger', collection: @triggers, as: :trigger
- else
%p.settings-message.text-center.append-bottom-default
- There are no triggers to use, add one by the button below.
+ No triggers have been created yet. Add one using the button below.
= form_for @trigger, url: url_for(controller: 'projects/triggers', action: 'create') do |f|
= f.submit "Add Trigger", class: 'btn btn-success'
@@ -28,8 +28,7 @@
Use CURL
%p.light
- Copy the token above and set your branch or tag name. This is the reference that will be rebuild.
-
+ Copy the token above, set your branch or tag name, and that reference will be rebuilt.
%pre
:plain
@@ -41,10 +40,10 @@
Use .gitlab-ci.yml
%p.light
- Copy the snippet to
- %i .gitlab-ci.yml
- of dependent project.
- At the end of your build it will trigger this project to rebuilt.
+ In the
+ %code .gitlab-ci.yml
+ of the dependent project, include the following snippet.
+ The project will rebuild at the end of the build.
%pre
:plain
@@ -57,9 +56,8 @@
%p.light
Add
- %strong variables[VARIABLE]=VALUE
- to API request.
- The value of variable could then be used to distinguish triggered build from normal one.
+ %code variables[VARIABLE]=VALUE
+ to an API request. Variable values can be used to distinguish between triggered builds and normal builds.
%pre.append-bottom-0
:plain
diff --git a/app/views/projects/wikis/_header_title.html.haml b/app/views/projects/wikis/_header_title.html.haml
deleted file mode 100644
index 408adc36ca6..00000000000
--- a/app/views/projects/wikis/_header_title.html.haml
+++ /dev/null
@@ -1 +0,0 @@
-- header_title project_title(@project, 'Wiki', get_project_wiki_path(@project))
diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml
index 4dd818c7f67..aaa15dd3bbe 100644
--- a/app/views/projects/wikis/edit.html.haml
+++ b/app/views/projects/wikis/edit.html.haml
@@ -1,5 +1,4 @@
- page_title "Edit", @page.title.capitalize, "Wiki"
-= render "header_title"
= render 'nav'
.top-area
diff --git a/app/views/projects/wikis/empty.html.haml b/app/views/projects/wikis/empty.html.haml
index c7e490c3cd1..7dfa405d063 100644
--- a/app/views/projects/wikis/empty.html.haml
+++ b/app/views/projects/wikis/empty.html.haml
@@ -1,5 +1,4 @@
- page_title "Wiki"
-= render "header_title"
%h3.page-title Empty page
%hr
diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml
index ba3f2cadc48..ccceab6155e 100644
--- a/app/views/projects/wikis/git_access.html.haml
+++ b/app/views/projects/wikis/git_access.html.haml
@@ -1,5 +1,4 @@
- page_title "Git Access", "Wiki"
-= render "header_title"
= render 'nav'
.row-content-block
diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml
index dcaddae2b04..45460ed9f41 100644
--- a/app/views/projects/wikis/history.html.haml
+++ b/app/views/projects/wikis/history.html.haml
@@ -1,5 +1,4 @@
- page_title "History", @page.title.capitalize, "Wiki"
-= render "header_title"
= render 'nav'
.top-area
diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml
index 92b494a513c..2f6162fa3c5 100644
--- a/app/views/projects/wikis/pages.html.haml
+++ b/app/views/projects/wikis/pages.html.haml
@@ -1,5 +1,4 @@
- page_title "Pages", "Wiki"
-= render "header_title"
= render 'nav'
diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml
index 067fb7f8f54..1cb48a1e85d 100644
--- a/app/views/projects/wikis/show.html.haml
+++ b/app/views/projects/wikis/show.html.haml
@@ -1,5 +1,4 @@
- page_title @page.title.capitalize, "Wiki"
-= render "header_title"
= render 'nav'
.top-area
diff --git a/app/views/search/results/_issue.html.haml b/app/views/search/results/_issue.html.haml
index 640890fbe92..8f68d6d1b87 100644
--- a/app/views/search/results/_issue.html.haml
+++ b/app/views/search/results/_issue.html.haml
@@ -7,7 +7,7 @@
- if issue.description.present?
.description.term
= preserve do
- = search_md_sanitize(markdown(truncate(issue.description, length: 200, separator: " "), { project: issue.project }))
+ = search_md_sanitize(markdown(truncate(issue.description, length: 200, separator: " "), { project: issue.project, author: issue.author }))
%span.light
#{issue.project.name_with_namespace}
- if issue.closed?
diff --git a/app/views/search/results/_merge_request.html.haml b/app/views/search/results/_merge_request.html.haml
index 333f6533213..6331c2bd6b0 100644
--- a/app/views/search/results/_merge_request.html.haml
+++ b/app/views/search/results/_merge_request.html.haml
@@ -6,7 +6,7 @@
- if merge_request.description.present?
.description.term
= preserve do
- = search_md_sanitize(markdown(merge_request.description, { project: merge_request.project }))
+ = search_md_sanitize(markdown(merge_request.description, { project: merge_request.project, author: merge_request.author }))
%span.light
#{merge_request.project.name_with_namespace}
.pull-right
diff --git a/app/views/search/results/_note.html.haml b/app/views/search/results/_note.html.haml
index d9400b1d9fa..8163aff43b6 100644
--- a/app/views/search/results/_note.html.haml
+++ b/app/views/search/results/_note.html.haml
@@ -19,4 +19,4 @@
.note-search-result
.term
= preserve do
- = search_md_sanitize(markdown(note.note, {no_header_anchors: true}))
+ = search_md_sanitize(markdown(note.note, {no_header_anchors: true, author: note.author}))
diff --git a/app/views/shared/_event_filter.html.haml b/app/views/shared/_event_filter.html.haml
index c38d9313dba..30055002213 100644
--- a/app/views/shared/_event_filter.html.haml
+++ b/app/views/shared/_event_filter.html.haml
@@ -1,5 +1,7 @@
-%ul.nav-links.event-filter
+%ul.nav-links.event-filter.scrolling-tabs
+ .fade-left
= event_filter_link EventFilter.push, 'Push events'
= event_filter_link EventFilter.merged, 'Merge events'
= event_filter_link EventFilter.comments, 'Comments'
= event_filter_link EventFilter.team, 'Team'
+ .fade-right
diff --git a/app/views/shared/_sort_dropdown.html.haml b/app/views/shared/_sort_dropdown.html.haml
index d327bd0a96f..1e0f075b303 100644
--- a/app/views/shared/_sort_dropdown.html.haml
+++ b/app/views/shared/_sort_dropdown.html.haml
@@ -6,7 +6,7 @@
- else
= sort_title_recently_created
%b.caret
- %ul.dropdown-menu.dropdown-menu-align-right
+ %ul.dropdown-menu.dropdown-menu-align-right.dropdown-menu-sort
%li
= link_to page_filter_path(sort: sort_value_recently_created) do
= sort_title_recently_created
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index 9474462cbd1..cedff4af2e0 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -1,6 +1,8 @@
.issues-filters
.issues-details-filters.row-content-block.second-block
- = form_tag page_filter_path(without: [:assignee_id, :author_id, :milestone_title, :label_name]), method: :get, class: 'filter-form' do
+ = form_tag page_filter_path(without: [:assignee_id, :author_id, :milestone_title, :label_name, :issue_search]), method: :get, class: 'filter-form js-filter-form' do
+ - if params[:issue_search].present?
+ = hidden_field_tag :issue_search, params[:issue_search]
- if controller.controller_name == 'issues' && can?(current_user, :admin_issue, @project)
.check-all-holder
= check_box_tag "check_all_issues", nil, false,
@@ -10,7 +12,7 @@
- if params[:author_id].present?
= hidden_field_tag(:author_id, params[:author_id])
= dropdown_tag(user_dropdown_label(params[:author_id], "Author"), options: { toggle_class: "js-user-search js-filter-submit js-author-search", title: "Filter by author", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-author js-filter-submit",
- placeholder: "Search authors", data: { any_user: "Any Author", first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author_id], field_name: "author_id", default_label: "Author" } })
+ placeholder: "Search authors", data: { any_user: "Any Author", first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), selected: params[:author], field_name: "author_id", default_label: "Author" } })
.filter-item.inline
- if params[:assignee_id].present?
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index fc3410f425d..b430251dbf6 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -98,9 +98,7 @@
= label_tag :move_to_project_id, 'Move', class: 'control-label'
.col-sm-10
.issuable-form-select-holder
- - projects = project_options(issuable, current_user, ability: :admin_issue)
- = select_tag(:move_to_project_id, projects, include_blank: true,
- class: 'select2', data: { placeholder: 'Select project' })
+ = hidden_field_tag :move_to_project_id, nil, class: 'js-move-dropdown', data: { placeholder: 'Select project', projects_url: autocomplete_projects_path(project_id: @project.id) }
&nbsp;
%span{ data: { toggle: 'tooltip', placement: 'auto top' }, style: 'cursor: default',
title: 'Moving an issue will copy the discussion to a different project and close it here. All participants will be notified of the new location.' }
diff --git a/app/views/shared/issuable/_search_form.html.haml b/app/views/shared/issuable/_search_form.html.haml
index afad48499b7..186963b32b8 100644
--- a/app/views/shared/issuable/_search_form.html.haml
+++ b/app/views/shared/issuable/_search_form.html.haml
@@ -1,8 +1,2 @@
= form_tag(path, method: :get, id: "issue_search_form", class: 'issue-search-form') do
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by name ...', class: 'form-control issue_search search-text-input input-short', spellcheck: false }
- = hidden_field_tag :state, params['state']
- = hidden_field_tag :scope, params['scope']
- = hidden_field_tag :assignee_id, params['assignee_id']
- = hidden_field_tag :author_id, params['author_id']
- = hidden_field_tag :milestone_id, params['milestone_id']
- = hidden_field_tag :label_id, params['label_id']
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 9ef021747a5..b8b66d08db8 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -12,9 +12,6 @@
%li.project-row{ class: css_class }
= cache(cache_key) do
.controls
- - if project.main_language
- %span
- = project.main_language
- if project.commit.try(:status)
%span
= render_commit_status(project.commit)
diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml
index e65b1814872..af753496260 100644
--- a/app/views/shared/snippets/_header.html.haml
+++ b/app/views/shared/snippets/_header.html.haml
@@ -1,25 +1,24 @@
-.detail-page-header
- .snippet-box.has-tooltip{class: visibility_level_color(@snippet.visibility_level), title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: 'body' }}
+.detail-page-header.clearfix
+ .snippet-box.has-tooltip.inline.append-right-5{ title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: "body" } }
+ %span.sr-only
+ = visibility_level_label(@snippet.visibility_level)
= visibility_level_icon(@snippet.visibility_level, fw: false)
- = visibility_level_label(@snippet.visibility_level)
- %span.identifier
- Snippet ##{@snippet.id}
+ %strong.item-title
+ Snippet #{@snippet.to_reference}
%span.creator
- &middot; created by #{link_to_member(@project, @snippet.author, size: 24)}
- &middot;
+ created by #{link_to_member(@project, @snippet.author, size: 24, author_class: "author item-title")}
= time_ago_with_tooltip(@snippet.created_at, placement: 'bottom', html_class: 'snippet_updated_ago')
- if @snippet.updated_at != @snippet.created_at
%span
- &middot;
= icon('edit', title: 'edited')
= time_ago_with_tooltip(@snippet.updated_at, placement: 'bottom', html_class: 'snippet_edited_ago')
- .pull-right
+ .snippet-actions
- if @snippet.project_id?
= render "projects/snippets/actions"
- else
= render "snippets/actions"
-.detail-page-description.row-content-block.second-block
- %h2.title
- = markdown escape_once(@snippet.title), pipeline: :single_line
+.content-block.second-block
+ %h2.snippet-title.prepend-top-0.append-bottom-0
+ = markdown escape_once(@snippet.title), pipeline: :single_line, author: @snippet.author
diff --git a/app/views/snippets/_actions.html.haml b/app/views/snippets/_actions.html.haml
index 1979ae6d5bc..a7769654b61 100644
--- a/app/views/snippets/_actions.html.haml
+++ b/app/views/snippets/_actions.html.haml
@@ -1,11 +1,27 @@
-= link_to new_snippet_path, class: 'btn btn-grouped new-snippet-link', title: "New Snippet" do
- = icon('plus')
- New Snippet
-- if can?(current_user, :update_personal_snippet, @snippet)
- = link_to edit_snippet_path(@snippet), class: "btn btn-grouped snippable-edit" do
- = icon('pencil-square-o')
- Edit
-- if can?(current_user, :admin_personal_snippet, @snippet)
- = link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-remove", title: 'Delete Snippet' do
- = icon('trash-o')
- Delete
+.hidden-xs
+ = link_to new_snippet_path, class: "btn btn-grouped btn-create new-snippet-link", title: "New Snippet" do
+ = icon('plus')
+ New Snippet
+ - if can?(current_user, :update_personal_snippet, @snippet)
+ = link_to edit_snippet_path(@snippet), class: "btn btn-grouped snippable-edit" do
+ Edit
+ - if can?(current_user, :admin_personal_snippet, @snippet)
+ = link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-warning", title: 'Delete Snippet' do
+ Delete
+.visible-xs-block.dropdown
+ %button.btn.btn-default.btn-block.append-bottom-0.prepend-top-5{ data: { toggle: "dropdown" } }
+ Options
+ %span.caret
+ .dropdown-menu.dropdown-menu-full-width
+ %ul
+ %li
+ = link_to new_snippet_path, title: "New Snippet" do
+ New Snippet
+ - if can?(current_user, :update_personal_snippet, @snippet)
+ %li
+ = link_to edit_snippet_path(@snippet) do
+ Edit
+ - if can?(current_user, :admin_personal_snippet, @snippet)
+ %li
+ = link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, title: 'Delete Snippet' do
+ Delete
diff --git a/app/views/snippets/show.html.haml b/app/views/snippets/show.html.haml
index a2b36568770..ed3992650d4 100644
--- a/app/views/snippets/show.html.haml
+++ b/app/views/snippets/show.html.haml
@@ -3,11 +3,10 @@
.snippet-holder
= render 'shared/snippets/header'
- %article.file-holder
- .file-title
+ %article.file-holder.file-holder-no-border.snippet-file-content
+ .file-title.file-title-clear
= blob_icon 0, @snippet.file_name
- %strong
- = @snippet.file_name
+ = @snippet.file_name
.file-actions.hidden-xs
= clipboard_button(clipboard_target: ".blob-content[data-blob-id='#{@snippet.id}']")
= link_to 'Raw', raw_snippet_path(@snippet), class: "btn btn-sm", target: "_blank"
diff --git a/app/views/users/calendar.html.haml b/app/views/users/calendar.html.haml
index 1de71f37d1a..77f2ddefb1e 100644
--- a/app/views/users/calendar.html.haml
+++ b/app/views/users/calendar.html.haml
@@ -1,10 +1,9 @@
-#cal-heatmap.calendar
- :javascript
- new Calendar(
- #{@timestamps.to_json},
- #{@starting_year},
- #{@starting_month},
- '#{user_calendar_activities_path}'
- );
-
-.calendar-hint Summary of issues, merge requests, and push events
+.clearfix.calendar
+ .js-contrib-calendar
+ .calendar-hint
+ Summary of issues, merge requests, and push events
+:javascript
+ new Calendar(
+ #{@timestamps.to_json},
+ '#{user_calendar_activities_path}'
+ );
diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml
index 027a93a75fc..630d97e339d 100644
--- a/app/views/users/calendar_activities.html.haml
+++ b/app/views/users/calendar_activities.html.haml
@@ -1,23 +1,27 @@
%h4.prepend-top-20
- %span.light Contributions for
+ Contributions for
%strong #{@calendar_date.to_s(:short)}
-%ul.bordered-list
- - @events.sort_by(&:created_at).each do |event|
- %li
- %span.light
- %i.fa.fa-clock-o
- = event.created_at.to_s(:time)
- - if event.push?
- #{event.action_name} #{event.ref_type} #{event.ref_name}
- - else
- = event_action_name(event)
- - if event.target
- %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target]
-
- at
- %strong
- - if event.project
- = link_to_project event.project
+- if @events.any?
+ %ul.bordered-list
+ - @events.sort_by(&:created_at).each do |event|
+ %li
+ %span.light
+ %i.fa.fa-clock-o
+ = event.created_at.to_s(:time)
+ - if event.push?
+ #{event.action_name} #{event.ref_type} #{event.ref_name}
- else
- = event.project_name
+ = event_action_name(event)
+ - if event.target
+ %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target]
+
+ at
+ %strong
+ - if event.project
+ = link_to_project event.project
+ - else
+ = event.project_name
+- else
+ %p
+ No contributions found for #{@calendar_date.to_s(:short)}
diff --git a/app/views/users/show.atom.builder b/app/views/users/show.atom.builder
index e9e466c6350..6c85e5f9fbd 100644
--- a/app/views/users/show.atom.builder
+++ b/app/views/users/show.atom.builder
@@ -6,7 +6,5 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
xml.id user_url(@user)
xml.updated @events[0].updated_at.xmlschema if @events[0]
- @events.each do |event|
- event_to_atom(xml, event)
- end
+ xml << render(@events) if @events.any?
end
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 9017fd54fcc..8268380dafc 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -1,5 +1,6 @@
- page_title @user.name
- page_description @user.bio
+- page_specific_javascripts asset_path("users/application.js")
- header_title @user.name, user_path(@user)
- @no_container = true
@@ -89,10 +90,9 @@
.tab-content
#activity.tab-pane
.row-content-block.calender-block.white.second-block.hidden-xs
- %div{ class: container_class }
- .user-calendar{data: {href: user_calendar_path}}
- %h4.center.light
- %i.fa.fa-spinner.fa-spin
+ .user-calendar{data: {href: user_calendar_path}}
+ %h4.center.light
+ %i.fa.fa-spinner.fa-spin
.user-calendar-activities
.content_list{ data: {href: user_path} }
diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb
index fa959fc56e3..971f969e25e 100644
--- a/app/workers/emails_on_push_worker.rb
+++ b/app/workers/emails_on_push_worker.rb
@@ -1,6 +1,7 @@
class EmailsOnPushWorker
include Sidekiq::Worker
+ sidekiq_options queue: :mailers
attr_reader :email, :skip_premailer
def perform(project_id, recipients, push_data, options = {})