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:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-06-03 14:10:01 +0300
committerKamil Trzcinski <ayufan@ayufan.eu>2016-06-03 14:10:01 +0300
commit0a51c954641c99610e9eddd9323398fb00d273e2 (patch)
treece0e58fcec98f566d7c96af3234da1a8b644c267 /app
parent3577b57f6b03a0d3c3d32daab6dc6ccf5f6e45f7 (diff)
parent3f4ac2ff60c9d83ec65b19070e4d054e12e67dd2 (diff)
Merge remote-tracking branch 'origin/master' into rename-ci-commit
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/search_autocomplete.js.coffee22
-rw-r--r--app/assets/stylesheets/pages/detail_page.scss2
-rw-r--r--app/assets/stylesheets/pages/search.scss4
-rw-r--r--app/controllers/projects/branches_controller.rb2
-rw-r--r--app/helpers/todos_helper.rb4
-rw-r--r--app/models/ci/build.rb1
-rw-r--r--app/models/concerns/issuable.rb12
-rw-r--r--app/models/project.rb18
-rw-r--r--app/models/user.rb17
-rw-r--r--app/services/projects/create_service.rb26
-rw-r--r--app/services/projects/import_service.rb2
-rw-r--r--app/views/layouts/_search.html.haml7
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml4
-rw-r--r--app/views/layouts/nav/_project.html.haml19
-rw-r--r--app/views/projects/branches/destroy.js.haml1
-rw-r--r--app/views/projects/commits/_head.html.haml8
-rw-r--r--app/views/projects/pipelines/_head.html.haml2
-rw-r--r--app/views/projects/tags/destroy.js.haml1
-rw-r--r--app/views/projects/tree/show.html.haml1
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml10
-rw-r--r--app/workers/repository_fork_worker.rb6
-rw-r--r--app/workers/repository_import_worker.rb3
22 files changed, 113 insertions, 59 deletions
diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee
index 6a7b4ad1db7..2122e80f57a 100644
--- a/app/assets/javascripts/search_autocomplete.js.coffee
+++ b/app/assets/javascripts/search_autocomplete.js.coffee
@@ -20,8 +20,7 @@ class @SearchAutocomplete
@dropdown = @wrap.find('.dropdown')
@dropdownContent = @dropdown.find('.dropdown-content')
- @locationBadgeEl = @getElement('.search-location-badge')
- @locationText = @getElement('.location-text')
+ @locationBadgeEl = @getElement('.location-badge')
@scopeInputEl = @getElement('#scope')
@searchInput = @getElement('.search-input')
@projectInputEl = @getElement('#search_project_id')
@@ -133,7 +132,7 @@ class @SearchAutocomplete
scope: @scopeInputEl.val()
# Location badge
- _location: @locationText.text()
+ _location: @locationBadgeEl.text()
}
bindEvents: ->
@@ -143,12 +142,14 @@ class @SearchAutocomplete
@searchInput.on 'click', @onSearchInputClick
@searchInput.on 'focus', @onSearchInputFocus
@clearInput.on 'click', @onClearInputClick
+ @locationBadgeEl.on 'click', =>
+ @searchInput.focus()
onDocumentClick: (e) =>
# If clicking outside the search box
# And search input is not focused
# And we are not clicking inside a suggestion
- if not $.contains(@dropdown[0], e.target) and @isFocused and not $(e.target).parents('ul').length
+ if not $.contains(@dropdown[0], e.target) and @isFocused and not $(e.target).closest('.search-form').length
@onSearchInputBlur()
enableAutocomplete: ->
@@ -221,10 +222,8 @@ class @SearchAutocomplete
category = if item.category? then "#{item.category}: " else ''
value = if item.value? then item.value else ''
- html = "<span class='location-badge'>
- <i class='location-text'>#{category}#{value}</i>
- </span>"
- @locationBadgeEl.html(html)
+ badgeText = "#{category}#{value}"
+ @locationBadgeEl.text(badgeText).show()
@wrap.addClass('has-location-badge')
restoreOriginalState: ->
@@ -233,9 +232,8 @@ class @SearchAutocomplete
for input in inputs
@getElement("##{input}").val(@originalState[input])
-
if @originalState._location is ''
- @locationBadgeEl.empty()
+ @locationBadgeEl.hide()
else
@addLocationBadge(
value: @originalState._location
@@ -244,7 +242,7 @@ class @SearchAutocomplete
@dropdown.removeClass 'open'
badgePresent: ->
- @locationBadgeEl.children().length
+ @locationBadgeEl.length
resetSearchState: ->
inputs = Object.keys @originalState
@@ -257,7 +255,7 @@ class @SearchAutocomplete
@getElement("##{input}").val('')
removeLocationBadge: ->
- @locationBadgeEl.empty()
+ @locationBadgeEl.hide()
# Reset state
@resetSearchState()
diff --git a/app/assets/stylesheets/pages/detail_page.scss b/app/assets/stylesheets/pages/detail_page.scss
index 5e61e61d85c..1b389d83525 100644
--- a/app/assets/stylesheets/pages/detail_page.scss
+++ b/app/assets/stylesheets/pages/detail_page.scss
@@ -29,8 +29,6 @@
margin-top: 6px;
p {
- overflow-x: auto;
-
&:last-child {
margin-bottom: 0;
}
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 2bff70c8c64..037ad520545 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -28,6 +28,7 @@
}
.search-input {
+ padding-right: 20px;
border: none;
font-size: 14px;
outline: none;
@@ -47,6 +48,7 @@
display: inline-block;
background-color: $location-badge-bg;
vertical-align: top;
+ cursor: default;
}
.search-input-container {
@@ -55,7 +57,7 @@
position: relative;
}
- .search-location-badge, .search-input-wrap {
+ .search-input-wrap {
// Fallback if flexbox is not supported
display: inline-block;
}
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index d09e7375b67..dd9508da049 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -50,7 +50,7 @@ class Projects::BranchesController < Projects::ApplicationController
redirect_to namespace_project_branches_path(@project.namespace,
@project), status: 303
end
- format.js { render status: status[:return_code] }
+ format.js { render nothing: true, status: status[:return_code] }
end
end
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index b9d7edb4185..b4923fbb138 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -17,7 +17,9 @@ module TodosHelper
def todo_target_link(todo)
target = todo.target_type.titleize.downcase
- link_to "#{target} #{todo.target_reference}", todo_target_path(todo), { title: todo.target.title }
+ link_to "#{target} #{todo.target_reference}", todo_target_path(todo),
+ class: 'has-tooltip',
+ title: todo.target.title
end
def todo_target_path(todo)
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 77837e9384a..b8ada6361ac 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -313,6 +313,7 @@ module Ci
build_data = Gitlab::BuildDataBuilder.build(self)
project.execute_hooks(build_data.dup, :build_hooks)
project.execute_services(build_data.dup, :build_hooks)
+ project.running_or_pending_build_count(force: true)
end
def artifacts?
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 2326a395cb8..e86d5236abb 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -68,6 +68,14 @@ module Issuable
strip_attributes :title
acts_as_paranoid
+
+ after_save :update_assignee_cache_counts, if: :assignee_id_changed?
+
+ def update_assignee_cache_counts
+ # make sure we flush the cache for both the old *and* new assignee
+ User.find(assignee_id_was).update_cache_counts if assignee_id_was
+ assignee.update_cache_counts if assignee
+ end
end
module ClassMethods
@@ -205,6 +213,10 @@ module Issuable
hook_data
end
+ def labels_array
+ labels.to_a
+ end
+
def label_names
labels.order('title ASC').pluck(:title)
end
diff --git a/app/models/project.rb b/app/models/project.rb
index e0ea1026b9c..f47ef8a81de 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1011,4 +1011,22 @@ class Project < ActiveRecord::Base
update_attribute(:pending_delete, true)
end
+
+ def running_or_pending_build_count(force: false)
+ Rails.cache.fetch(['projects', id, 'running_or_pending_build_count'], force: force) do
+ builds.running_or_pending.count(:all)
+ end
+ end
+
+ def mark_import_as_failed(error_message)
+ original_errors = errors.dup
+ sanitized_message = Gitlab::UrlSanitizer.sanitize(error_message)
+
+ import_fail
+ update_column(:import_error, sanitized_message)
+ rescue ActiveRecord::ActiveRecordError => e
+ Rails.logger.error("Error setting import status to failed: #{e.message}. Original error: #{sanitized_message}")
+ ensure
+ @errors = original_errors
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 15b6cbc2255..172845c9d25 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -776,6 +776,23 @@ class User < ActiveRecord::Base
notification_settings.find_or_initialize_by(source: source)
end
+ def assigned_open_merge_request_count(force: false)
+ Rails.cache.fetch(['users', id, 'assigned_open_merge_request_count'], force: force) do
+ assigned_merge_requests.opened.count
+ end
+ end
+
+ def assigned_open_issues_count(force: false)
+ Rails.cache.fetch(['users', id, 'assigned_open_issues_count'], force: force) do
+ assigned_issues.opened.count
+ end
+ end
+
+ def update_cache_counts
+ assigned_open_merge_request_count(force: true)
+ assigned_open_issues_count(force: true)
+ end
+
private
def projects_union
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index 6728fabea1e..61cac5419ad 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -56,14 +56,14 @@ module Projects
after_create_actions if @project.persisted?
- @project.add_import_job if @project.import?
-
+ if @project.errors.empty?
+ @project.add_import_job if @project.import?
+ else
+ fail(error: @project.errors.full_messages.join(', '))
+ end
@project
rescue => e
- message = "Unable to save project: #{e.message}"
- Rails.logger.error(message)
- @project.errors.add(:base, message) if @project
- @project
+ fail(error: e.message)
end
protected
@@ -103,5 +103,19 @@ module Projects
end
end
end
+
+ def fail(error:)
+ message = "Unable to save project. Error: #{error}"
+ message << "Project ID: #{@project.id}" if @project && @project.id
+
+ Rails.logger.error(message)
+
+ if @project && @project.import?
+ @project.errors.add(:base, message)
+ @project.mark_import_as_failed(message)
+ end
+
+ @project
+ end
end
end
diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb
index ef15ef6a473..c4838d31f2f 100644
--- a/app/services/projects/import_service.rb
+++ b/app/services/projects/import_service.rb
@@ -39,7 +39,7 @@ module Projects
begin
gitlab_shell.import_repository(project.path_with_namespace, project.import_url)
rescue Gitlab::Shell::Error => e
- raise Error, e.message
+ raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}"
end
end
diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml
index 6b208c3d0bb..b49207fc315 100644
--- a/app/views/layouts/_search.html.haml
+++ b/app/views/layouts/_search.html.haml
@@ -6,11 +6,8 @@
.search.search-form{class: "#{'has-location-badge' if label.present?}"}
= form_tag search_path, method: :get, class: 'navbar-form' do |f|
.search-input-container
- .search-location-badge
- - if label.present?
- %span.location-badge
- %i.location-text
- = label
+ - if label.present?
+ .location-badge= label
.search-input-wrap
.dropdown{ data: {url: search_autocomplete_path } }
= search_field_tag "search", nil, placeholder: 'Search', class: "search-input dropdown-menu-toggle", spellcheck: false, tabindex: "1", autocomplete: 'off', data: { toggle: 'dropdown' }
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 43532b0c155..306ebd5fcf7 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -30,13 +30,13 @@
= icon('exclamation-circle fw')
%span
Issues
- %span.count= number_with_delimiter(current_user.assigned_issues.opened.count)
+ %span.count= number_with_delimiter(current_user.assigned_open_issues_count)
= nav_link(path: 'dashboard#merge_requests') do
= link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'dashboard-shortcuts-merge_requests' do
= icon('tasks fw')
%span
Merge Requests
- %span.count= number_with_delimiter(current_user.assigned_merge_requests.opened.count)
+ %span.count= number_with_delimiter(current_user.assigned_open_merge_request_count)
= nav_link(controller: :snippets) do
= link_to dashboard_snippets_path, title: 'Snippets' do
= icon('clipboard fw')
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index 2c9b9006668..9792c1c93b4 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -33,18 +33,11 @@
%span
Activity
- if project_nav_tab? :files
- = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
+ = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)) do
= link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree' do
- = icon('files-o fw')
+ = icon('code 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')
- %span
- Commits
+ Code
- if project_nav_tab? :pipelines
= nav_link(controller: :pipelines) do
@@ -129,4 +122,10 @@
= link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
Builds
+ -# Shortcut to commits page
+ - if project_nav_tab? :commits
+ %li.hidden
+ = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do
+ Commits
+
.fade-right
diff --git a/app/views/projects/branches/destroy.js.haml b/app/views/projects/branches/destroy.js.haml
deleted file mode 100644
index a21ddaf4930..00000000000
--- a/app/views/projects/branches/destroy.js.haml
+++ /dev/null
@@ -1 +0,0 @@
-$('.js-totalbranch-count').html("#{@repository.branch_count}")
diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml
index d1bd76ab529..1c136133ab0 100644
--- a/app/views/projects/commits/_head.html.haml
+++ b/app/views/projects/commits/_head.html.haml
@@ -1,9 +1,11 @@
%ul.nav-links
+ = nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
+ = link_to project_files_path(@project) do
+ Files
+
= nav_link(controller: [:commit, :commits]) do
= link_to namespace_project_commits_path(@project.namespace, @project, current_ref) do
Commits
- %span.badge
- = number_with_delimiter(@repository.commit_count)
= nav_link(controller: %w(network)) do
= link_to namespace_project_network_path(@project.namespace, @project, current_ref) do
@@ -16,9 +18,7 @@
= nav_link(html_options: {class: branches_tab_class}) do
= link_to namespace_project_branches_path(@project.namespace, @project) do
Branches
- %span.badge.js-totalbranch-count= @repository.branch_count
= nav_link(controller: [:tags, :releases]) do
= link_to namespace_project_tags_path(@project.namespace, @project) do
Tags
- %span.badge.js-totaltags-count= @repository.tag_count
diff --git a/app/views/projects/pipelines/_head.html.haml b/app/views/projects/pipelines/_head.html.haml
index 2c8ae625e67..6e757df5417 100644
--- a/app/views/projects/pipelines/_head.html.haml
+++ b/app/views/projects/pipelines/_head.html.haml
@@ -11,4 +11,4 @@
= 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))
+ %span.badge.count.builds_counter= number_with_delimiter(@project.running_or_pending_build_count)
diff --git a/app/views/projects/tags/destroy.js.haml b/app/views/projects/tags/destroy.js.haml
index ffeacb5a004..e4a78fadbeb 100644
--- a/app/views/projects/tags/destroy.js.haml
+++ b/app/views/projects/tags/destroy.js.haml
@@ -1,3 +1,2 @@
-$('.js-totaltags-count').html("#{@repository.tags.size}");
- if @repository.tags.empty?
$('.tags').load(document.URL + ' .nothing-here-block').hide().fadeIn(1000)
diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml
index 7e9ba09c720..59f60c4687c 100644
--- a/app/views/projects/tree/show.html.haml
+++ b/app/views/projects/tree/show.html.haml
@@ -3,6 +3,7 @@
- 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")
= render 'projects/last_push'
+= render "projects/commits/head"
.tree-controls
= render 'projects/find_file_link'
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index c1eec450193..d6552ae7f18 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -114,20 +114,20 @@
.sidebar-collapsed-icon
= icon('tags')
%span
- = issuable.labels.count
+ = issuable.labels_array.size
.title.hide-collapsed
Labels
= icon('spinner spin', class: 'block-loading')
- if can_edit_issuable
= link_to 'Edit', '#', class: 'edit-link pull-right'
- .value.bold.issuable-show-labels.hide-collapsed{ class: ("has-labels" if issuable.labels.any?) }
- - if issuable.labels.any?
- - issuable.labels.each do |label|
+ .value.bold.issuable-show-labels.hide-collapsed{ class: ("has-labels" if issuable.labels_array.any?) }
+ - if issuable.labels_array.any?
+ - issuable.labels_array.each do |label|
= link_to_label(label, type: issuable.to_ability_name)
- else
.light None
.selectbox.hide-collapsed
- - issuable.labels.each do |label|
+ - issuable.labels_array.each do |label|
= hidden_field_tag "#{issuable.to_ability_name}[label_names][]", label.id, id: nil
.dropdown
%button.dropdown-menu-toggle.js-label-select.js-multiselect{type: "button", data: {toggle: "dropdown", field_name: "#{issuable.to_ability_name}[label_names][]", ability_name: issuable.to_ability_name, show_no: "true", show_any: "true", project_id: (@project.id if @project), issue_update: issuable_json_path(issuable), labels: (namespace_project_labels_path(@project.namespace, @project, :json) if @project)}}
diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb
index f9e32337983..d947f105516 100644
--- a/app/workers/repository_fork_worker.rb
+++ b/app/workers/repository_fork_worker.rb
@@ -15,8 +15,7 @@ class RepositoryForkWorker
result = gitlab_shell.fork_repository(source_path, target_path)
unless result
logger.error("Unable to fork project #{project_id} for repository #{source_path} -> #{target_path}")
- project.update(import_error: "The project could not be forked.")
- project.import_fail
+ project.mark_import_as_failed('The project could not be forked.')
return
end
@@ -24,8 +23,7 @@ class RepositoryForkWorker
unless project.valid_repo?
logger.error("Project #{project_id} had an invalid repository after fork")
- project.update(import_error: "The forked repository is invalid.")
- project.import_fail
+ project.mark_import_as_failed('The forked repository is invalid.')
return
end
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index fbc7ed63c6a..7d819fe78f8 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -13,8 +13,7 @@ class RepositoryImportWorker
result = Projects::ImportService.new(project, current_user).execute
if result[:status] == :error
- project.update(import_error: Gitlab::UrlSanitizer.sanitize(result[:message]))
- project.import_fail
+ project.mark_import_as_failed(result[:message])
return
end