diff options
author | Phil Hughes <me@iamphill.com> | 2016-08-30 11:21:29 +0100 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2016-08-30 11:21:29 +0100 |
commit | 7418873b41acb142d33443fcbbe45e4ca6bdfd08 (patch) | |
tree | d6086ee6ea4131406a5686638ff69ca51b6956bf /app/helpers | |
parent | a6e312bf1dd01aa653761c5bf1e848df9707c0cb (diff) | |
parent | 2778dec131c2afac9fcdb2c42365b69099a5ae5b (diff) | |
download | gitlab-ce-7418873b41acb142d33443fcbbe45e4ca6bdfd08.tar.gz |
Merge branch 'master' into revert-c676283b
Diffstat (limited to 'app/helpers')
26 files changed, 455 insertions, 236 deletions
diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb index e12a1052988..de13e7a1fc2 100644 --- a/app/helpers/appearances_helper.rb +++ b/app/helpers/appearances_helper.rb @@ -32,6 +32,8 @@ module AppearancesHelper end def custom_icon(icon_name, size: 16) + # We can't simply do the below, because there are some .erb SVGs. + # File.read(Rails.root.join("app/views/shared/icons/_#{icon_name}.svg")).html_safe render "shared/icons/#{icon_name}.svg", size: size end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 03495cf5ec4..f3733b01721 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -163,9 +163,13 @@ module ApplicationHelper # `html_class` argument is provided. # # Returns an HTML-safe String - def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false) + def time_ago_with_tooltip(time, placement: 'top', html_class: '', skip_js: false, short_format: false) + css_classes = short_format ? 'js-short-timeago' : 'js-timeago' + css_classes << " #{html_class}" unless html_class.blank? + css_classes << ' js-timeago-pending' unless skip_js + element = content_tag :time, time.to_s, - class: "#{html_class} js-timeago #{"js-timeago-pending" unless skip_js}", + class: css_classes, datetime: time.to_time.getutc.iso8601, title: time.to_time.in_time_zone.to_s(:medium), data: { toggle: 'tooltip', placement: placement, container: 'body' } @@ -245,7 +249,6 @@ module ApplicationHelper milestone_title: params[:milestone_title], assignee_id: params[:assignee_id], author_id: params[:author_id], - sort: params[:sort], issue_search: params[:issue_search], label_name: params[:label_name] } @@ -317,4 +320,8 @@ module ApplicationHelper capture(&block) end end + + def page_class + "issue-boards-page" if current_controller?(:boards) + end end diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 78c0b79d2bd..6de25bea654 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -31,6 +31,10 @@ module ApplicationSettingsHelper current_application_settings.akismet_enabled? end + def koding_enabled? + current_application_settings.koding_enabled? + end + def allowed_protocols_present? current_application_settings.enabled_git_access_protocol.present? end diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb new file mode 100644 index 00000000000..aa8acbe7567 --- /dev/null +++ b/app/helpers/avatars_helper.rb @@ -0,0 +1,26 @@ +module AvatarsHelper + def author_avatar(commit_or_event, options = {}) + user_avatar(options.merge({ + user: commit_or_event.author, + user_name: commit_or_event.author_name, + user_email: commit_or_event.author_email, + })) + end + + def user_avatar(options = {}) + avatar_size = options[:size] || 16 + user_name = options[:user].try(:name) || options[:user_name] + avatar = image_tag( + avatar_icon(options[:user] || options[:user_email], avatar_size), + class: "avatar has-tooltip hidden-xs s#{avatar_size}", + alt: "#{user_name}'s avatar", + title: user_name + ) + + if options[:user] + link_to(avatar, user_path(options[:user])) + elsif options[:user_email] + mail_to(options[:user_email], avatar) + end + end +end diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index abe115d8c68..e13b7cdd707 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -11,17 +11,14 @@ module BlobHelper def edit_blob_link(project = @project, ref = @ref, path = @path, options = {}) return unless current_user - blob = project.repository.blob_at(ref, path) rescue nil - - return unless blob && blob_text_viewable?(blob) + blob = options.delete(:blob) + blob ||= project.repository.blob_at(ref, path) rescue nil - from_mr = options[:from_merge_request_id] - link_opts = {} - link_opts[:from_merge_request_id] = from_mr if from_mr + return unless blob edit_path = namespace_project_edit_blob_path(project.namespace, project, tree_join(ref, path), - link_opts) + options[:link_opts]) if !on_top_of_branch?(project, ref) button_tag "Edit", class: "btn disabled has-tooltip btn-file-option", title: "You can only edit files when you are on a branch", data: { container: 'body' } @@ -182,17 +179,50 @@ module BlobHelper } end + def selected_template(issuable) + templates = issuable_templates(issuable) + params[:issuable_template] if templates.include?(params[:issuable_template]) + end + + def can_add_template?(issuable) + names = issuable_templates(issuable) + names.empty? && can?(current_user, :push_code, @project) && !@project.private? + end + + def merge_request_template_names + @merge_request_templates ||= Gitlab::Template::MergeRequestTemplate.dropdown_names(ref_project) + end + + def issue_template_names + @issue_templates ||= Gitlab::Template::IssueTemplate.dropdown_names(ref_project) + end + + def issuable_templates(issuable) + @issuable_templates ||= + if issuable.is_a?(Issue) + issue_template_names + elsif issuable.is_a?(MergeRequest) + merge_request_template_names + end + end + + def ref_project + @ref_project ||= @target_project || @project + end + def gitignore_names - @gitignore_names ||= - Gitlab::Template::Gitignore.categories.keys.map do |k| - [k, Gitlab::Template::Gitignore.by_category(k).map { |t| { name: t.name } }] - end.to_h + @gitignore_names ||= Gitlab::Template::GitignoreTemplate.dropdown_names end def gitlab_ci_ymls - @gitlab_ci_ymls ||= - Gitlab::Template::GitlabCiYml.categories.keys.map do |k| - [k, Gitlab::Template::GitlabCiYml.by_category(k).map { |t| { name: t.name } }] - end.to_h + @gitlab_ci_ymls ||= Gitlab::Template::GitlabCiYmlTemplate.dropdown_names + end + + def blob_editor_paths + { + 'relative-url-root' => Rails.application.config.relative_url_root, + 'assets-prefix' => Gitlab::Application.config.assets.prefix, + 'blob-language' => @blob && @blob.language.try(:ace_mode) + } end end diff --git a/app/helpers/branches_helper.rb b/app/helpers/branches_helper.rb index bfd23aa4e04..3fc85dc6b2b 100644 --- a/app/helpers/branches_helper.rb +++ b/app/helpers/branches_helper.rb @@ -9,6 +9,17 @@ module BranchesHelper end end + def filter_branches_path(options = {}) + exist_opts = { + search: params[:search], + sort: params[:sort] + } + + options = exist_opts.merge(options) + + namespace_project_branches_path(@project.namespace, @project, @id, options) + end + def can_push_branch?(project, branch_name) return false unless project.repository.branch_exists?(branch_name) diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 59a8365d60b..0327b476d18 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -15,8 +15,11 @@ module CiStatusHelper end def ci_label_for_status(status) - if status == 'success' + case status + when 'success' 'passed' + when 'success_with_warnings' + 'passed with warnings' else status end @@ -35,6 +38,10 @@ module CiStatusHelper 'icon_status_pending' when 'running' 'icon_status_running' + when 'play' + 'icon_play' + when 'created' + 'icon_status_pending' else 'icon_status_cancel' end @@ -42,16 +49,16 @@ module CiStatusHelper custom_icon(icon_name) end - def render_commit_status(commit, tooltip_placement: 'auto left', cssclass: '') + def render_commit_status(commit, tooltip_placement: 'auto left') project = commit.project path = builds_namespace_project_commit_path(project.namespace, project, commit) - render_status_with_link('commit', commit.status, path, tooltip_placement, cssclass: cssclass) + render_status_with_link('commit', commit.status, path, tooltip_placement: tooltip_placement) end def render_pipeline_status(pipeline, tooltip_placement: 'auto left') project = pipeline.project path = namespace_project_pipeline_path(project.namespace, project, pipeline) - render_status_with_link('pipeline', pipeline.status, path, tooltip_placement) + render_status_with_link('pipeline', pipeline.status, path, tooltip_placement: tooltip_placement) end def no_runners_for_project?(project) @@ -59,13 +66,17 @@ module CiStatusHelper Ci::Runner.shared.blank? end - private + def render_status_with_link(type, status, path = nil, tooltip_placement: 'auto left', cssclass: '', container: 'body') + klass = "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}" + title = "#{type.titleize}: #{ci_label_for_status(status)}" + data = { toggle: 'tooltip', placement: tooltip_placement, container: container } - def render_status_with_link(type, status, path, tooltip_placement, cssclass: '') - link_to ci_icon_for_status(status), - path, - class: "ci-status-link ci-status-icon-#{status.dasherize} #{cssclass}", - title: "#{type.titleize}: #{ci_label_for_status(status)}", - data: { toggle: 'tooltip', placement: tooltip_placement } + if path + link_to ci_icon_for_status(status), path, + class: klass, title: title, data: data + else + content_tag :span, ci_icon_for_status(status), + class: klass, title: title, data: data + end end end diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 474041eccbb..33dcee49aee 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -1,4 +1,3 @@ -# encoding: utf-8 module CommitsHelper # Returns a link to the commit author. If the author has a matching user and # is a member of the current @project it will link to the team member page. @@ -16,16 +15,6 @@ module CommitsHelper commit_person_link(commit, options.merge(source: :committer)) end - def commit_author_avatar(commit, options = {}) - options = options.merge(source: :author) - user = commit.send(options[:source]) - - source_email = clean(commit.send "#{options[:source]}_email".to_sym) - person_email = user.try(:email) || source_email - - image_tag(avatar_icon(person_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]} hidden-xs", width: options[:size], alt: "") - end - def image_diff_class(diff) if diff.deleted_file "deleted" @@ -109,28 +98,31 @@ module CommitsHelper end def link_to_browse_code(project, commit) - if current_controller?(:projects, :commits) - if @repo.blob_at(commit.id, @path) - return link_to( - "Browse File", - namespace_project_blob_path(project.namespace, project, - tree_join(commit.id, @path)), - class: "btn btn-default" - ) - elsif @path.present? - return link_to( - "Browse Directory", - namespace_project_tree_path(project.namespace, project, - tree_join(commit.id, @path)), - class: "btn btn-default" - ) - end + if @path.blank? + return link_to( + "Browse Files", + namespace_project_tree_path(project.namespace, project, commit), + class: "btn btn-default" + ) + end + + return unless current_controller?(:projects, :commits) + + if @repo.blob_at(commit.id, @path) + return link_to( + "Browse File", + namespace_project_blob_path(project.namespace, project, + tree_join(commit.id, @path)), + class: "btn btn-default" + ) + elsif @path.present? + return link_to( + "Browse Directory", + namespace_project_tree_path(project.namespace, project, + tree_join(commit.id, @path)), + class: "btn btn-default" + ) end - link_to( - "Browse Files", - namespace_project_tree_path(project.namespace, project, commit), - class: "btn btn-default" - ) end def revert_commit_link(commit, continue_to_path, btn_class: nil, has_tooltip: true) @@ -217,10 +209,10 @@ module CommitsHelper end end - def view_file_btn(commit_sha, diff, project) + def view_file_btn(commit_sha, diff_new_path, project) link_to( namespace_project_blob_path(project.namespace, project, - tree_join(commit_sha, diff.new_path)), + tree_join(commit_sha, diff_new_path)), class: 'btn view-file js-view-file btn-file-option' ) do raw('View file @') + content_tag(:span, commit_sha[0..6], diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb index 75b029365f9..0725c3f4c56 100644 --- a/app/helpers/diff_helper.rb +++ b/app/helpers/diff_helper.rb @@ -13,12 +13,11 @@ module DiffHelper end def diff_view - diff_views = %w(inline parallel) - - if diff_views.include?(cookies[:diff_view]) - cookies[:diff_view] - else - diff_views.first + @diff_view ||= begin + diff_views = %w(inline parallel) + diff_view = cookies[:diff_view] + diff_view = diff_views.first unless diff_views.include?(diff_view) + diff_view.to_sym end end @@ -30,19 +29,26 @@ module DiffHelper options[:paths] = params.values_at(:old_path, :new_path) end - Commit.max_diff_options.merge(options) + options end - def safe_diff_files(diffs, diff_refs: nil, repository: nil) - diffs.decorate! { |diff| Gitlab::Diff::File.new(diff, diff_refs: diff_refs, repository: repository) } - end + def diff_match_line(old_pos, new_pos, text: '', view: :inline, bottom: false) + content = content_tag :td, text, class: "line_content match #{view == :inline ? '' : view}" + cls = ['diff-line-num', 'unfold', 'js-unfold'] + cls << 'js-unfold-bottom' if bottom - def unfold_bottom_class(bottom) - bottom ? 'js-unfold js-unfold-bottom' : '' - end + html = '' + if old_pos + html << content_tag(:td, '...', class: cls + ['old_line'], data: { linenumber: old_pos }) + html << content unless view == :inline + end - def unfold_class(unfold) - unfold ? 'unfold js-unfold' : '' + if new_pos + html << content_tag(:td, '...', class: cls + ['new_line'], data: { linenumber: new_pos }) + html << content + end + + html.html_safe end def diff_line_content(line, line_type = nil) @@ -54,26 +60,28 @@ module DiffHelper end end - def organize_comments(left, right) - notes_left = notes_right = nil + def parallel_diff_discussions(left, right, diff_file) + discussion_left = discussion_right = nil - unless left[:type].nil? && right[:type] == 'new' - notes_left = @grouped_diff_notes[left[:line_code]] + if left && (left.unchanged? || left.removed?) + line_code = diff_file.line_code(left) + discussion_left = @grouped_diff_discussions[line_code] end - unless left[:type].nil? && right[:type].nil? - notes_right = @grouped_diff_notes[right[:line_code]] + if right && right.added? + line_code = diff_file.line_code(right) + discussion_right = @grouped_diff_discussions[line_code] end - [notes_left, notes_right] + [discussion_left, discussion_right] end def inline_diff_btn - diff_btn('Inline', 'inline', diff_view == 'inline') + diff_btn('Inline', 'inline', diff_view == :inline) end def parallel_diff_btn - diff_btn('Side-by-side', 'parallel', diff_view == 'parallel') + diff_btn('Side-by-side', 'parallel', diff_view == :parallel) end def submodule_link(blob, ref, repository = @repository) @@ -101,11 +109,11 @@ module DiffHelper end end - def diff_file_html_data(project, diff_file) - commit = commit_for_diff(diff_file) + def diff_file_html_data(project, diff_file_path, diff_commit_id) { blob_diff_path: namespace_project_blob_diff_path(project.namespace, project, - tree_join(commit.id, diff_file.file_path)) + tree_join(diff_commit_id, diff_file_path)), + view: diff_view } end @@ -142,8 +150,6 @@ module DiffHelper toggle_whitespace_link(url, options) end - private - def hide_whitespace? params[:w] == '1' end diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb index 337b0aacbb5..2b1f3825adc 100644 --- a/app/helpers/explore_helper.rb +++ b/app/helpers/explore_helper.rb @@ -1,5 +1,5 @@ module ExploreHelper - def filter_projects_path(options={}) + def filter_projects_path(options = {}) exist_opts = { sort: params[:sort], scope: params[:scope], diff --git a/app/helpers/external_wiki_helper.rb b/app/helpers/external_wiki_helper.rb index 1f3401f2906..defd87d6bbe 100644 --- a/app/helpers/external_wiki_helper.rb +++ b/app/helpers/external_wiki_helper.rb @@ -1,8 +1,7 @@ module ExternalWikiHelper def get_project_wiki_path(project) - external_wiki_service = project.services. - find { |service| service.to_param == 'external_wiki' } - if external_wiki_service.present? && external_wiki_service.active? + external_wiki_service = project.external_wiki + if external_wiki_service external_wiki_service.properties['external_wiki_url'] else namespace_project_wiki_path(project.namespace, project, :home) diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb index ae2a4c80706..3a3fda2bb92 100644 --- a/app/helpers/issuables_helper.rb +++ b/app/helpers/issuables_helper.rb @@ -66,6 +66,15 @@ module IssuablesHelper end end + def issuable_labels_tooltip(labels, limit: 5) + first, last = labels.partition.with_index{ |_, i| i < limit } + + label_names = first.collect(&:name) + label_names << "and #{last.size} more" unless last.empty? + + label_names.join(', ') + end + private def sidebar_gutter_collapsed? diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 2b0defd1dda..8b212b0327a 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -13,38 +13,6 @@ module IssuesHelper OpenStruct.new(id: 0, title: 'None (backlog)', name: 'Unassigned') end - def url_for_project_issues(project = @project, options = {}) - return '' if project.nil? - - url = - if options[:only_path] - project.issues_tracker.project_path - else - project.issues_tracker.project_url - end - - # Ensure we return a valid URL to prevent possible XSS. - URI.parse(url).to_s - rescue URI::InvalidURIError - '' - end - - def url_for_new_issue(project = @project, options = {}) - return '' if project.nil? - - url = - if options[:only_path] - project.issues_tracker.new_issue_path - else - project.issues_tracker.new_issue_url - end - - # Ensure we return a valid URL to prevent possible XSS. - URI.parse(url).to_s - rescue URI::InvalidURIError - '' - end - def url_for_issue(issue_iid, project = @project, options = {}) return '' if project.nil? @@ -146,9 +114,17 @@ module IssuesHelper end def award_user_list(awards, current_user) - awards.map do |award| - award.user == current_user ? 'me' : award.user.name - end.join(', ') + names = awards.map do |award| + award.user == current_user ? 'You' : award.user.name + end + + # Take first 9 OR current user + first 9 + current_user_name = names.delete('You') + names = names.first(9).insert(0, current_user_name).compact + + names << "#{awards.size - names.size} more." if awards.size > names.size + + names.to_sentence end def award_active_class(awards, current_user) diff --git a/app/helpers/lfs_helper.rb b/app/helpers/lfs_helper.rb new file mode 100644 index 00000000000..eb651e3687e --- /dev/null +++ b/app/helpers/lfs_helper.rb @@ -0,0 +1,67 @@ +module LfsHelper + def require_lfs_enabled! + return if Gitlab.config.lfs.enabled + + render( + json: { + message: 'Git LFS is not enabled on this GitLab server, contact your admin.', + documentation_url: "#{Gitlab.config.gitlab.url}/help", + }, + status: 501 + ) + end + + def lfs_check_access! + return if download_request? && lfs_download_access? + return if upload_request? && lfs_upload_access? + + if project.public? || (user && user.can?(:read_project, project)) + render_lfs_forbidden + else + render_lfs_not_found + end + end + + def lfs_download_access? + project.public? || ci? || (user && user.can?(:download_code, project)) + end + + def lfs_upload_access? + user && user.can?(:push_code, project) + end + + def render_lfs_forbidden + render( + json: { + message: 'Access forbidden. Check your access level.', + documentation_url: "#{Gitlab.config.gitlab.url}/help", + }, + content_type: "application/vnd.git-lfs+json", + status: 403 + ) + end + + def render_lfs_not_found + render( + json: { + message: 'Not found.', + documentation_url: "#{Gitlab.config.gitlab.url}/help", + }, + content_type: "application/vnd.git-lfs+json", + status: 404 + ) + end + + def storage_project + @storage_project ||= begin + result = project + + loop do + break unless result.forked? + result = result.forked_from_project + end + + result + end + end +end diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb index ec106418f2d..877c77050be 100644 --- a/app/helpers/members_helper.rb +++ b/app/helpers/members_helper.rb @@ -6,12 +6,6 @@ module MembersHelper "#{action}_#{member.type.underscore}".to_sym end - def default_show_roles(member) - can?(current_user, action_member_permission(:update, member), member) || - can?(current_user, action_member_permission(:destroy, member), member) || - can?(current_user, action_member_permission(:admin, member), member.source) - end - def remove_member_message(member, user: nil) user = current_user if defined?(current_user) diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb index 3ff8be5e284..6c1cc6ef072 100644 --- a/app/helpers/nav_helper.rb +++ b/app/helpers/nav_helper.rb @@ -24,6 +24,7 @@ module NavHelper current_path?('merge_requests#diffs') || current_path?('merge_requests#commits') || current_path?('merge_requests#builds') || + current_path?('merge_requests#conflicts') || current_path?('issues#show') if cookies[:collapsed_gutter] == 'true' "page-gutter right-sidebar-collapsed" diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb index 98143dcee9b..da230f76bae 100644 --- a/app/helpers/notes_helper.rb +++ b/app/helpers/notes_helper.rb @@ -1,9 +1,4 @@ module NotesHelper - # Helps to distinguish e.g. commit notes in mr notes list - def note_for_main_target?(note) - @noteable.class.name == note.noteable_type && !note.diff_note? - end - def note_target_fields(note) if note.noteable hidden_field_tag(:target_type, note.noteable.class.name.underscore) + @@ -12,7 +7,7 @@ module NotesHelper end def note_editable?(note) - note.editable? && can?(current_user, :admin_note, note) + Ability.can_edit_note?(current_user, note) end def noteable_json(noteable) @@ -44,8 +39,8 @@ module NotesHelper # If we didn't, diff notes that would show for the same line on the changes # tab, would show in different discussions on the discussion tab. use_legacy_diff_note ||= begin - line_diff_notes = @grouped_diff_notes[line_code] - line_diff_notes && line_diff_notes.any?(&:legacy_diff_note?) + discussion = @grouped_diff_discussions[line_code] + discussion && discussion.legacy_diff_discussion? end data = { @@ -54,7 +49,7 @@ module NotesHelper } if use_legacy_diff_note - discussion_id = LegacyDiffNote.build_discussion_id( + discussion_id = LegacyDiffNote.discussion_id( @comments_target[:noteable_type], @comments_target[:noteable_id] || @comments_target[:commit_id], line_code @@ -65,7 +60,7 @@ module NotesHelper discussion_id: discussion_id ) else - discussion_id = DiffNote.build_discussion_id( + discussion_id = DiffNote.discussion_id( @comments_target[:noteable_type], @comments_target[:noteable_id] || @comments_target[:commit_id], position @@ -81,46 +76,35 @@ module NotesHelper data end - def link_to_reply_discussion(note, line_type = nil) + def link_to_reply_discussion(discussion, line_type = nil) return unless current_user - data = { - noteable_type: note.noteable_type, - noteable_id: note.noteable_id, - commit_id: note.commit_id, - discussion_id: note.discussion_id, - line_type: line_type - } + data = discussion.reply_attributes.merge(line_type: line_type) - if note.diff_note? - data[:note_type] = note.type + button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button', + data: data, title: 'Add a reply' + end - data.merge!(note.diff_attributes) - end + def preload_max_access_for_authors(notes, project) + user_ids = notes.map(&:author_id) + project.team.max_member_access_for_user_ids(user_ids) + end - content_tag(:div, class: "discussion-reply-holder") do - button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button', - data: data, title: 'Add a reply' - end + def preload_noteable_for_regular_notes(notes) + ActiveRecord::Associations::Preloader.new.preload(notes.select { |note| !note.for_commit? }, :noteable) end def note_max_access_for_user(note) - @max_access_by_user_id ||= Hash.new do |hash, key| - project = key[:project] - hash[key] = project.team.human_max_access(key[:user_id]) - end - - full_key = { project: note.project, user_id: note.author_id } - @max_access_by_user_id[full_key] + note.project.team.human_max_access(note.author_id) end - def diff_note_path(note) - return unless note.diff_note? + def discussion_diff_path(discussion) + return unless discussion.diff_discussion? - if note.for_merge_request? && note.active? - diffs_namespace_project_merge_request_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) - elsif note.for_commit? - namespace_project_commit_path(note.project.namespace, note.project, note.noteable, anchor: note.line_code) + if discussion.for_merge_request? && discussion.active? + diffs_namespace_project_merge_request_path(discussion.project.namespace, discussion.project, discussion.noteable, anchor: discussion.line_code) + elsif discussion.for_commit? + namespace_project_commit_path(discussion.project.namespace, discussion.project, discussion.noteable, anchor: discussion.line_code) end end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index a733dff1579..356f27f2d5d 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -116,6 +116,17 @@ module ProjectsHelper license.nickname || license.name end + def last_push_event + return unless current_user + + project_ids = [@project.id] + if fork = current_user.fork_of(@project) + project_ids << fork.id + end + + current_user.recent_push(project_ids) + end + private def get_project_nav_tabs(project, current_user) @@ -236,6 +247,60 @@ module ProjectsHelper ) end + def add_koding_stack_path(project) + namespace_project_new_blob_path( + project.namespace, + project, + project.default_branch || 'master', + file_name: '.koding.yml', + commit_message: "Add Koding stack script", + content: <<-CONTENT.strip_heredoc + provider: + aws: + access_key: '${var.aws_access_key}' + secret_key: '${var.aws_secret_key}' + resource: + aws_instance: + #{project.path}-vm: + instance_type: t2.nano + user_data: |- + + # Created by GitLab UI for :> + + echo _KD_NOTIFY_@Installing Base packages...@ + + apt-get update -y + apt-get install git -y + + echo _KD_NOTIFY_@Cloning #{project.name}...@ + + export KODING_USER=${var.koding_user_username} + export REPO_URL=#{root_url}${var.koding_queryString_repo}.git + export BRANCH=${var.koding_queryString_branch} + + sudo -i -u $KODING_USER git clone $REPO_URL -b $BRANCH + + echo _KD_NOTIFY_@#{project.name} cloned.@ + CONTENT + ) + end + + def koding_project_url(project = nil, branch = nil, sha = nil) + if project + import_path = "/Home/Stacks/import" + + repo = project.path_with_namespace + branch ||= project.default_branch + sha ||= project.commit.short_id + + path = "#{import_path}?repo=#{repo}&branch=#{branch}&sha=#{sha}" + + return URI.join(current_application_settings.koding_url, path).to_s + end + + current_application_settings.koding_url + end + def contribution_guide_path(project) if project && contribution_guide = project.repository.contribution_guide namespace_project_blob_path( @@ -263,6 +328,10 @@ module ProjectsHelper filename_path(project, :version) end + def ci_configuration_path(project) + filename_path(project, :gitlab_ci_yml) + end + def project_wiki_path_with_version(proj, page, version, is_newest) url_params = is_newest ? {} : { version_id: version } namespace_project_wiki_path(proj.namespace, proj, page, url_params) @@ -293,16 +362,6 @@ module ProjectsHelper namespace_project_new_blob_path(@project.namespace, @project, tree_join(ref), file_name: 'LICENSE') end - def last_push_event - return unless current_user - - if fork = current_user.fork_of(@project) - current_user.recent_push(fork.id) - else - current_user.recent_push(@project.id) - end - end - def readme_cache_key sha = @project.commit.try(:sha) || 'nil' [@project.path_with_namespace, sha, "readme"].join('-') diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index fcb2703e837..4549c2e5bb6 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -44,7 +44,7 @@ module SearchHelper def help_autocomplete [ { category: "Help", label: "API Help", url: help_page_path("api/README") }, - { category: "Help", label: "Markdown Help", url: help_page_path("markdown/markdown") }, + { category: "Help", label: "Markdown Help", url: help_page_path("user/markdown") }, { category: "Help", label: "Permissions Help", url: help_page_path("user/permissions") }, { category: "Help", label: "Public Access Help", url: help_page_path("public_access/public_access") }, { category: "Help", label: "Rake Tasks Help", url: help_page_path("raketasks/README") }, @@ -107,12 +107,13 @@ module SearchHelper Sanitize.clean(str) end - def search_filter_path(options={}) + def search_filter_path(options = {}) exist_opts = { search: params[:search], project_id: params[:project_id], group_id: params[:group_id], - scope: params[:scope] + scope: params[:scope], + repository_ref: params[:repository_ref] } options = exist_opts.merge(options) diff --git a/app/helpers/selects_helper.rb b/app/helpers/selects_helper.rb index bb395e37884..5f27e33c6ad 100644 --- a/app/helpers/selects_helper.rb +++ b/app/helpers/selects_helper.rb @@ -5,21 +5,9 @@ module SelectsHelper css_class << "skip_ldap " if opts[:skip_ldap] css_class << (opts[:class] || '') value = opts[:selected] || '' - - first_user = opts[:first_user] && current_user ? current_user.username : false - html = { class: css_class, - data: { - placeholder: opts[:placeholder] || 'Search for a user', - null_user: opts[:null_user] || false, - any_user: opts[:any_user] || false, - email_user: opts[:email_user] || false, - first_user: first_user, - current_user: opts[:current_user] || false, - "push-code-to-protected-branches" => opts[:push_code_to_protected_branches], - author_id: opts[:author_id] || '' - } + data: users_select_data_attributes(opts) } unless opts[:scope] == :all @@ -68,4 +56,20 @@ module SelectsHelper hidden_field_tag(id, value, class: css_class) end + + private + + def users_select_data_attributes(opts) + { + placeholder: opts[:placeholder] || 'Search for a user', + null_user: opts[:null_user] || false, + any_user: opts[:any_user] || false, + email_user: opts[:email_user] || false, + first_user: opts[:first_user] && current_user ? current_user.username : false, + current_user: opts[:current_user] || false, + "push-code-to-protected-branches" => opts[:push_code_to_protected_branches], + author_id: opts[:author_id] || '', + skip_users: opts[:skip_users] ? opts[:skip_users].map(&:id) : nil, + } + end end diff --git a/app/helpers/sentry_helper.rb b/app/helpers/sentry_helper.rb new file mode 100644 index 00000000000..f8cccade15b --- /dev/null +++ b/app/helpers/sentry_helper.rb @@ -0,0 +1,27 @@ +module SentryHelper + def sentry_enabled? + Rails.env.production? && current_application_settings.sentry_enabled? + end + + def sentry_context + return unless sentry_enabled? + + if current_user + Raven.user_context( + id: current_user.id, + email: current_user.email, + username: current_user.username, + ) + end + + Raven.tags_context(program: sentry_program_context) + end + + def sentry_program_context + if Sidekiq.server? + 'sidekiq' + else + 'rails' + end + end +end diff --git a/app/helpers/services_helper.rb b/app/helpers/services_helper.rb new file mode 100644 index 00000000000..2dd0bf5d71e --- /dev/null +++ b/app/helpers/services_helper.rb @@ -0,0 +1,25 @@ +module ServicesHelper + def service_event_description(event) + case event + when "push" + "Event will be triggered by a push to the repository" + when "tag_push" + "Event will be triggered when a new tag is pushed to the repository" + when "note" + "Event will be triggered when someone adds a comment" + when "issue" + "Event will be triggered when an issue is created/updated/merged" + when "merge_request" + "Event will be triggered when a merge request is created/updated/merged" + when "build" + "Event will be triggered when a build status changes" + when "wiki_page" + "Event will be triggered when a wiki page is created/updated" + end + end + + def service_event_field_name(event) + event = event.pluralize if %w[merge_request issue].include?(event) + "#{event}_events" + end +end diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb index d86f1999f5c..8b138a8e69f 100644 --- a/app/helpers/sorting_helper.rb +++ b/app/helpers/sorting_helper.rb @@ -20,13 +20,19 @@ module SortingHelper end def projects_sort_options_hash - { + options = { sort_value_name => sort_title_name, sort_value_recently_updated => sort_title_recently_updated, sort_value_oldest_updated => sort_title_oldest_updated, sort_value_recently_created => sort_title_recently_created, sort_value_oldest_created => sort_title_oldest_created, } + + if current_controller?('admin/projects') + options.merge!(sort_value_largest_repo => sort_title_largest_repo) + end + + options end def sort_title_priority @@ -102,11 +108,11 @@ module SortingHelper end def sort_value_oldest_created - 'id_asc' + 'created_asc' end def sort_value_recently_created - 'id_desc' + 'created_desc' end def sort_value_milestone_soon diff --git a/app/helpers/time_helper.rb b/app/helpers/time_helper.rb index 1926f03af07..271e839692a 100644 --- a/app/helpers/time_helper.rb +++ b/app/helpers/time_helper.rb @@ -1,5 +1,6 @@ module TimeHelper def time_interval_in_words(interval_in_seconds) + interval_in_seconds = interval_in_seconds.to_i minutes = interval_in_seconds / 60 seconds = interval_in_seconds - minutes * 60 @@ -14,20 +15,9 @@ module TimeHelper "#{from.to_s(:short)} - #{to.to_s(:short)}" end - def duration_in_numbers(finished_at, started_at) - interval = interval_in_seconds(started_at, finished_at) - time_format = interval < 1.hour ? "%M:%S" : "%H:%M:%S" + def duration_in_numbers(duration) + time_format = duration < 1.hour ? "%M:%S" : "%H:%M:%S" - Time.at(interval).utc.strftime(time_format) - end - - private - - def interval_in_seconds(started_at, finished_at = nil) - if started_at && finished_at - finished_at.to_i - started_at.to_i - elsif started_at - Time.now.to_i - started_at.to_i - end + Time.at(duration).utc.strftime(time_format) end end diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb index e3a208f826a..0465327060e 100644 --- a/app/helpers/todos_helper.rb +++ b/app/helpers/todos_helper.rb @@ -1,10 +1,10 @@ module TodosHelper def todos_pending_count - @todos_pending_count ||= TodosFinder.new(current_user, state: :pending).execute.count + @todos_pending_count ||= current_user.todos_pending_count end def todos_done_count - @todos_done_count ||= TodosFinder.new(current_user, state: :done).execute.count + @todos_done_count ||= current_user.todos_done_count end def todo_action_name(todo) diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index dbedf417fa5..4a76c679bad 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -4,23 +4,11 @@ module TreeHelper # # contents - A Grit::Tree object for the current tree def render_tree(tree) - # Render Folders before Files/Submodules + # Sort submodules and folders together by name ahead of files folders, files, submodules = tree.trees, tree.blobs, tree.submodules - tree = "" - - # Render folders if we have any - tree << render(partial: 'projects/tree/tree_item', collection: folders, - locals: { type: 'folder' }) if folders.present? - - # Render files if we have any - tree << render(partial: 'projects/tree/blob_item', collection: files, - locals: { type: 'file' }) if files.present? - - # Render submodules if we have any - tree << render(partial: 'projects/tree/submodule_item', - collection: submodules) if submodules.present? - + items = (folders + submodules).sort_by(&:name) + files + tree << render(partial: "projects/tree/tree_row", collection: items) if items.present? tree.html_safe end |