diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 19:05:49 +0300 |
commit | 43a25d93ebdabea52f99b05e15b06250cd8f07d7 (patch) | |
tree | dceebdc68925362117480a5d672bcff122fb625b /app/presenters | |
parent | 20c84b99005abd1c82101dfeff264ac50d2df211 (diff) |
Add latest changes from gitlab-org/gitlab@16-0-stable-eev16.0.0-rc42
Diffstat (limited to 'app/presenters')
-rw-r--r-- | app/presenters/README.md | 12 | ||||
-rw-r--r-- | app/presenters/ci/build_presenter.rb | 4 | ||||
-rw-r--r-- | app/presenters/ci/build_runner_presenter.rb | 6 | ||||
-rw-r--r-- | app/presenters/ci/pipeline_presenter.rb | 1 | ||||
-rw-r--r-- | app/presenters/commit_presenter.rb | 4 | ||||
-rw-r--r-- | app/presenters/event_presenter.rb | 2 | ||||
-rw-r--r-- | app/presenters/label_presenter.rb | 18 | ||||
-rw-r--r-- | app/presenters/merge_request_presenter.rb | 20 | ||||
-rw-r--r-- | app/presenters/ml/candidate_details_presenter.rb | 88 | ||||
-rw-r--r-- | app/presenters/ml/candidates_csv_presenter.rb | 49 | ||||
-rw-r--r-- | app/presenters/packages/npm/package_presenter.rb | 85 | ||||
-rw-r--r-- | app/presenters/pages_domain_presenter.rb | 7 | ||||
-rw-r--r-- | app/presenters/project_presenter.rb | 262 | ||||
-rw-r--r-- | app/presenters/search_service_presenter.rb | 3 | ||||
-rw-r--r-- | app/presenters/snippet_blob_presenter.rb | 8 |
15 files changed, 332 insertions, 237 deletions
diff --git a/app/presenters/README.md b/app/presenters/README.md index e2461580107..5b600e8f2b2 100644 --- a/app/presenters/README.md +++ b/app/presenters/README.md @@ -165,15 +165,15 @@ however, there is a risk that it accidentally overrides important logic. For example, [this production incident](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/5498) was caused by [including `ActionView::Helpers::UrlHelper` in a presenter](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69537/diffs#4b581cff00ef3cc9780efd23682af383de302e7d_3_3). -The `tag` accesor in `Ci::Build` was accidentally overridden by `ActionView::Helpers::TagHelper#tag`, -and as a conseuqence, a wrong `tag` value was persited into database. +The `tag` accessor in `Ci::Build` was accidentally overridden by `ActionView::Helpers::TagHelper#tag`, +and as a consequence, a wrong `tag` value was persisted into database. -Starting from GitLab 14.4, we validate the presenters (specifically all of the subclasses of `Gitlab::View::Presenter::Delegated`) +Starting from GitLab 14.4, we [validate](../../lib/gitlab/utils/delegator_override/validator.rb) the presenters (specifically all of the subclasses of `Gitlab::View::Presenter::Delegated`) that they do not accidentally override core/backend logic. In such case, a pipeline in merge requests fails with an error message, here is an example: ```plaintext -We've detected that a presetner is overriding a specific method(s) on a subject model. +We've detected that a presenter is overriding a specific method(s) on a subject model. There is a risk that it accidentally modifies the backend/core logic that leads to production incident. Please follow https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/presenters/README.md#validate-accidental-overrides to resolve this error with caution. @@ -193,7 +193,7 @@ Here are the potential solutions: ### How to use the `Gitlab::Utils::DelegatorOverride` validator -If a presenter class inhertis from `Gitlab::View::Presenter::Delegated`, +If a presenter class inherits from `Gitlab::View::Presenter::Delegated`, you should define what object class is presented: ```ruby @@ -201,7 +201,7 @@ class WebHookLogPresenter < Gitlab::View::Presenter::Delegated presents ::WebHookLog, as: :web_hook_log # This defines that the presenter presents `WebHookLog` Active Record model. ``` -These presenters are validated not to accidentaly override the methods in the presented object. +These presenters are validated not to accidentally override the methods in the presented object. You can run the validation locally with: ```shell diff --git a/app/presenters/ci/build_presenter.rb b/app/presenters/ci/build_presenter.rb index 513fcd90cf8..b89e8db334d 100644 --- a/app/presenters/ci/build_presenter.rb +++ b/app/presenters/ci/build_presenter.rb @@ -27,6 +27,10 @@ module Ci scheduled? && scheduled_at && [0, scheduled_at - Time.now].max end + def failure_message + callout_failure_message if build.failed? + end + private def tooltip_for_badge(status) diff --git a/app/presenters/ci/build_runner_presenter.rb b/app/presenters/ci/build_runner_presenter.rb index 9a586a1733f..79c1946f3d2 100644 --- a/app/presenters/ci/build_runner_presenter.rb +++ b/app/presenters/ci/build_runner_presenter.rb @@ -34,9 +34,7 @@ module Ci def runner_variables variables - .sort_and_expand_all(keep_undefined: true, - expand_file_refs: false, - expand_raw_refs: false) + .sort_and_expand_all(keep_undefined: true, expand_file_refs: false, expand_raw_refs: false) .to_runner_variables end @@ -58,7 +56,7 @@ module Ci # rubocop: disable CodeReuse/ActiveRecord def all_dependencies dependencies = super - ActiveRecord::Associations::Preloader.new.preload(dependencies, :job_artifacts_archive) + ActiveRecord::Associations::Preloader.new(records: dependencies, associations: :job_artifacts_archive).call dependencies end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb index aa0cd476191..8c9ff49b0e7 100644 --- a/app/presenters/ci/pipeline_presenter.rb +++ b/app/presenters/ci/pipeline_presenter.rb @@ -13,7 +13,6 @@ module Ci config_error: 'The pipeline failed due to an error on the CI/CD configuration file.', external_validation_failure: 'The external pipeline validation failed.', user_not_verified: 'The pipeline failed due to the user not being verified', - activity_limit_exceeded: 'The pipeline activity limit was exceeded.', size_limit_exceeded: 'The pipeline size limit was exceeded.', job_activity_limit_exceeded: 'The pipeline job activity limit was exceeded.', deployments_limit_exceeded: 'The pipeline deployments limit was exceeded.', diff --git a/app/presenters/commit_presenter.rb b/app/presenters/commit_presenter.rb index 2cb88179845..2879326ff8a 100644 --- a/app/presenters/commit_presenter.rb +++ b/app/presenters/commit_presenter.rb @@ -25,6 +25,10 @@ class CommitPresenter < Gitlab::View::Presenter::Delegated commit.pipelines.any? end + def tags_for_display + commit.referenced_by&.map { |tag_name| Gitlab::Git.ref_name(tag_name) } + end + def signature_html return unless commit.has_signature? diff --git a/app/presenters/event_presenter.rb b/app/presenters/event_presenter.rb index 2f2fb1aa3ba..a098db7fbbc 100644 --- a/app/presenters/event_presenter.rb +++ b/app/presenters/event_presenter.rb @@ -9,7 +9,7 @@ class EventPresenter < Gitlab::View::Presenter::Delegated @visible_to_user_cache = ActiveSupport::Cache::MemoryStore.new end - # Caching `visible_to_user?` method in the presenter beause it might be called multiple times. + # Caching `visible_to_user?` method in the presenter because it might be called multiple times. delegator_override :visible_to_user? def visible_to_user?(user = nil) @visible_to_user_cache.fetch(user&.id) { super(user) } diff --git a/app/presenters/label_presenter.rb b/app/presenters/label_presenter.rb index e60cdf4088c..56d986a9c23 100644 --- a/app/presenters/label_presenter.rb +++ b/app/presenters/label_presenter.rb @@ -27,14 +27,18 @@ class LabelPresenter < Gitlab::View::Presenter::Delegated def filter_path(type: :issue) case context_subject when Group - send("#{type.to_s.pluralize}_group_path", # rubocop:disable GitlabSecurity/PublicSend - context_subject, - label_name: [label.name]) + send( # rubocop:disable GitlabSecurity/PublicSend + "#{type.to_s.pluralize}_group_path", + context_subject, + label_name: [label.name] + ) when Project - send("namespace_project_#{type.to_s.pluralize}_path", # rubocop:disable GitlabSecurity/PublicSend - context_subject.namespace, - context_subject, - label_name: [label.name]) + send( # rubocop:disable GitlabSecurity/PublicSend + "namespace_project_#{type.to_s.pluralize}_path", + context_subject.namespace, + context_subject, + label_name: [label.name] + ) end end diff --git a/app/presenters/merge_request_presenter.rb b/app/presenters/merge_request_presenter.rb index 353e0fad6fb..12f4b0496e4 100644 --- a/app/presenters/merge_request_presenter.rb +++ b/app/presenters/merge_request_presenter.rb @@ -57,9 +57,7 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated notice_now: edit_in_new_fork_notice_now } - project_forks_path(merge_request.project, - namespace_key: current_user.namespace.id, - continue: continue_params) + project_forks_path(merge_request.project, namespace_key: current_user.namespace.id, continue: continue_params) end end @@ -71,9 +69,7 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated notice_now: edit_in_new_fork_notice_now } - project_forks_path(project, - namespace_key: current_user.namespace.id, - continue: continue_params) + project_forks_path(project, namespace_key: current_user.namespace.id, continue: continue_params) end end @@ -155,12 +151,12 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated def assign_to_closing_issues_count # rubocop: disable CodeReuse/ServiceClass - issues = MergeRequests::AssignIssuesService.new(project: project, - current_user: current_user, - params: { - merge_request: merge_request, - closes_issues: closing_issues - }).assignable_issues + issues = MergeRequests::AssignIssuesService.new( + project: project, + current_user: current_user, + params: { merge_request: merge_request, closes_issues: closing_issues } + ).assignable_issues + issues.count # rubocop: enable CodeReuse/ServiceClass end diff --git a/app/presenters/ml/candidate_details_presenter.rb b/app/presenters/ml/candidate_details_presenter.rb new file mode 100644 index 00000000000..58ec2aee471 --- /dev/null +++ b/app/presenters/ml/candidate_details_presenter.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Ml + class CandidateDetailsPresenter + include Rails.application.routes.url_helpers + + def initialize(candidate) + @candidate = candidate + end + + def present + data = { + candidate: { + info: { + iid: candidate.iid, + eid: candidate.eid, + path_to_artifact: link_to_artifact, + experiment_name: candidate.experiment.name, + path_to_experiment: link_to_experiment, + path: link_to_details, + status: candidate.status, + ci_job: job_info + }, + params: candidate.params, + metrics: candidate.latest_metrics, + metadata: candidate.metadata + } + } + + Gitlab::Json.generate(data) + end + + private + + attr_reader :candidate + + def job_info + return unless candidate.from_ci? + + build = candidate.ci_build + + { + path: project_job_path(build.project, build), + name: build.name, + **user_info(build.user) || {}, + **mr_info(build.pipeline.merge_request) || {} + } + end + + def user_info(user) + return unless user + + { + user: { + path: user_path(user), + username: user.username + } + } + end + + def mr_info(mr) + return unless mr + + { + merge_request: { + path: project_merge_request_path(mr.project, mr), + title: mr.title + } + } + end + + def link_to_artifact + artifact = candidate.artifact + + return unless artifact.present? + + project_package_path(candidate.project, artifact) + end + + def link_to_details + project_ml_candidate_path(candidate.project, candidate.iid) + end + + def link_to_experiment + project_ml_experiment_path(candidate.project, candidate.experiment.iid) + end + end +end diff --git a/app/presenters/ml/candidates_csv_presenter.rb b/app/presenters/ml/candidates_csv_presenter.rb new file mode 100644 index 00000000000..8e2baf6bd28 --- /dev/null +++ b/app/presenters/ml/candidates_csv_presenter.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Ml + class CandidatesCsvPresenter + CANDIDATE_ASSOCIATIONS = [:latest_metrics, :params, :experiment].freeze + # This file size limit is mainly to avoid the generation to hog resources from the server. The value is arbitrary + # can be update once we have better insight into usage. + TARGET_FILESIZE = 2.megabytes + + def initialize(candidates) + @candidates = candidates + end + + def present + CsvBuilder.new(@candidates, headers, CANDIDATE_ASSOCIATIONS).render(TARGET_FILESIZE) + end + + private + + def headers + metric_names = columns_names(&:metrics) + param_names = columns_names(&:params) + + candidate_to_metrics = @candidates.to_h do |candidate| + [candidate.id, candidate.latest_metrics.to_h { |m| [m.name, m.value] }] + end + + candidate_to_params = @candidates.to_h do |candidate| + [candidate.id, candidate.params.to_h { |m| [m.name, m.value] }] + end + + { + project_id: 'project_id', + experiment_iid: ->(c) { c.experiment.iid }, + candidate_iid: 'internal_id', + name: 'name', + external_id: 'eid', + start_time: 'start_time', + end_time: 'end_time', + **param_names.index_with { |name| ->(c) { candidate_to_params.dig(c.id, name) } }, + **metric_names.index_with { |name| ->(c) { candidate_to_metrics.dig(c.id, name) } } + } + end + + def columns_names(&selector) + @candidates.flat_map(&selector).map(&:name).uniq + end + end +end diff --git a/app/presenters/packages/npm/package_presenter.rb b/app/presenters/packages/npm/package_presenter.rb index 57bdd373309..42f61182ab8 100644 --- a/app/presenters/packages/npm/package_presenter.rb +++ b/app/presenters/packages/npm/package_presenter.rb @@ -3,94 +3,25 @@ module Packages module Npm class PackagePresenter - include API::Helpers::RelatedResourcesHelpers - - # Allowed fields are those defined in the abbreviated form - # defined here: https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md#abbreviated-version-object - # except: name, version, dist, dependencies and xDependencies. Those are generated by this presenter. - PACKAGE_JSON_ALLOWED_FIELDS = %w[deprecated bin directories dist engines _hasShrinkwrap].freeze - - attr_reader :name, :packages + def initialize(metadata) + @metadata = metadata + end - def initialize(name, packages) - @name = name - @packages = packages + def name + metadata[:name] end def versions - package_versions = {} - - packages.each_batch do |relation| - batched_packages = relation.including_dependency_links - .preload_files - .preload_npm_metadatum - - batched_packages.each do |package| - package_file = package.installable_package_files.last - - next unless package_file - - package_versions[package.version] = build_package_version(package, package_file) - end - end - - package_versions + metadata[:versions] end def dist_tags - build_package_tags.tap { |t| t["latest"] ||= sorted_versions.last } + metadata[:dist_tags] end private - def build_package_tags - package_tags.to_h { |tag| [tag.name, tag.package.version] } - end - - def build_package_version(package, package_file) - abbreviated_package_json(package).merge( - name: package.name, - version: package.version, - dist: { - shasum: package_file.file_sha1, - tarball: tarball_url(package, package_file) - } - ).tap do |package_version| - package_version.merge!(build_package_dependencies(package)) - end - end - - def tarball_url(package, package_file) - expose_url "#{api_v4_projects_path(id: package.project_id)}" \ - "/packages/npm/#{package.name}" \ - "/-/#{package_file.file_name}" - end - - def build_package_dependencies(package) - dependencies = Hash.new { |h, key| h[key] = {} } - - package.dependency_links.each do |dependency_link| - dependency = dependency_link.dependency - dependencies[dependency_link.dependency_type][dependency.name] = dependency.version_pattern - end - - dependencies - end - - def sorted_versions - versions = packages.pluck_versions.compact - VersionSorter.sort(versions) - end - - def package_tags - Packages::Tag.for_package_ids(packages.last_of_each_version_ids) - .preload_package - end - - def abbreviated_package_json(package) - json = package.npm_metadatum&.package_json || {} - json.slice(*PACKAGE_JSON_ALLOWED_FIELDS) - end + attr_reader :metadata end end end diff --git a/app/presenters/pages_domain_presenter.rb b/app/presenters/pages_domain_presenter.rb index d730608cc27..49322ad6b43 100644 --- a/app/presenters/pages_domain_presenter.rb +++ b/app/presenters/pages_domain_presenter.rb @@ -13,4 +13,11 @@ class PagesDomainPresenter < Gitlab::View::Presenter::Delegated ::Gitlab::LetsEncrypt.enabled? && auto_ssl_failed end + + def user_defined_certificate? + persisted? && + certificate.present? && + certificate_user_provided? && + errors[:certificate].blank? + end end diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb index 392a2fcd390..856eba5aadc 100644 --- a/app/presenters/project_presenter.rb +++ b/app/presenters/project_presenter.rb @@ -99,11 +99,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated def contribution_guide_path if project && contribution_guide = repository.contribution_guide - project_blob_path( - project, - tree_join(project.default_branch, - contribution_guide.name) - ) + project_blob_path(project, tree_join(project.default_branch, contribution_guide.name)) end end @@ -166,14 +162,16 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated def storage_anchor_data can_show_quota = can?(current_user, :admin_project, project) && !empty_repo? - AnchorData.new(true, - statistic_icon('disk') + - _('%{strong_start}%{human_size}%{strong_end} Project Storage').html_safe % { - human_size: storage_counter(statistics.storage_size), - strong_start: '<strong class="project-stat-value">'.html_safe, - strong_end: '</strong>'.html_safe - }, - can_show_quota ? project_usage_quotas_path(project) : nil) + AnchorData.new( + true, + statistic_icon('disk') + + _('%{strong_start}%{human_size}%{strong_end} Project Storage').html_safe % { + human_size: storage_counter(statistics.storage_size), + strong_start: '<strong class="project-stat-value">'.html_safe, + strong_end: '</strong>'.html_safe + }, + can_show_quota ? project_usage_quotas_path(project) : nil + ) end def releases_anchor_data @@ -182,14 +180,16 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated releases_count = project.releases.count return if releases_count < 1 - AnchorData.new(true, - statistic_icon('deployments') + - n_('%{strong_start}%{release_count}%{strong_end} Release', '%{strong_start}%{release_count}%{strong_end} Releases', releases_count).html_safe % { - release_count: number_with_delimiter(releases_count), - strong_start: '<strong class="project-stat-value">'.html_safe, - strong_end: '</strong>'.html_safe - }, - project_releases_path(project)) + AnchorData.new( + true, + statistic_icon('rocket-launch') + + n_('%{strong_start}%{release_count}%{strong_end} Release', '%{strong_start}%{release_count}%{strong_end} Releases', releases_count).html_safe % { + release_count: number_with_delimiter(releases_count), + strong_start: '<strong class="project-stat-value">'.html_safe, + strong_end: '</strong>'.html_safe + }, + project_releases_path(project) + ) end def environments_anchor_data @@ -198,67 +198,76 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated environments_count = project.environments.available.count return if environments_count == 0 - AnchorData.new(true, - statistic_icon('environment') + - n_('%{strong_start}%{count}%{strong_end} Environment', '%{strong_start}%{count}%{strong_end} Environments', environments_count).html_safe % { - count: number_with_delimiter(environments_count), - strong_start: '<strong class="project-stat-value">'.html_safe, - strong_end: '</strong>'.html_safe - }, - project_environments_path(project)) + AnchorData.new( + true, + statistic_icon('environment') + + n_('%{strong_start}%{count}%{strong_end} Environment', '%{strong_start}%{count}%{strong_end} Environments', environments_count).html_safe % { + count: number_with_delimiter(environments_count), + strong_start: '<strong class="project-stat-value">'.html_safe, + strong_end: '</strong>'.html_safe + }, + project_environments_path(project) + ) end def commits_anchor_data - AnchorData.new(true, - statistic_icon('commit') + - n_('%{strong_start}%{commit_count}%{strong_end} Commit', '%{strong_start}%{commit_count}%{strong_end} Commits', statistics.commit_count).html_safe % { - commit_count: number_with_delimiter(statistics.commit_count), - strong_start: '<strong class="project-stat-value">'.html_safe, - strong_end: '</strong>'.html_safe - }, - empty_repo? ? nil : project_commits_path(project, default_branch_or_main)) + AnchorData.new( + true, + statistic_icon('commit') + + n_('%{strong_start}%{commit_count}%{strong_end} Commit', '%{strong_start}%{commit_count}%{strong_end} Commits', statistics.commit_count).html_safe % { + commit_count: number_with_delimiter(statistics.commit_count), + strong_start: '<strong class="project-stat-value">'.html_safe, + strong_end: '</strong>'.html_safe + }, + empty_repo? ? nil : project_commits_path(project, default_branch_or_main) + ) end def branches_anchor_data - AnchorData.new(true, - statistic_icon('branch') + - n_('%{strong_start}%{branch_count}%{strong_end} Branch', '%{strong_start}%{branch_count}%{strong_end} Branches', repository.branch_count).html_safe % { - branch_count: number_with_delimiter(repository.branch_count), - strong_start: '<strong class="project-stat-value">'.html_safe, - strong_end: '</strong>'.html_safe - }, - empty_repo? ? nil : project_branches_path(project)) + AnchorData.new( + true, + statistic_icon('branch') + + n_('%{strong_start}%{branch_count}%{strong_end} Branch', '%{strong_start}%{branch_count}%{strong_end} Branches', repository.branch_count).html_safe % { + branch_count: number_with_delimiter(repository.branch_count), + strong_start: '<strong class="project-stat-value">'.html_safe, + strong_end: '</strong>'.html_safe + }, + empty_repo? ? nil : project_branches_path(project) + ) end def tags_anchor_data - AnchorData.new(true, - statistic_icon('label') + - n_('%{strong_start}%{tag_count}%{strong_end} Tag', '%{strong_start}%{tag_count}%{strong_end} Tags', repository.tag_count).html_safe % { - tag_count: number_with_delimiter(repository.tag_count), - strong_start: '<strong class="project-stat-value">'.html_safe, - strong_end: '</strong>'.html_safe - }, - empty_repo? ? nil : project_tags_path(project)) + AnchorData.new( + true, + statistic_icon('label') + + n_('%{strong_start}%{tag_count}%{strong_end} Tag', '%{strong_start}%{tag_count}%{strong_end} Tags', repository.tag_count).html_safe % { + tag_count: number_with_delimiter(repository.tag_count), + strong_start: '<strong class="project-stat-value">'.html_safe, + strong_end: '</strong>'.html_safe + }, + empty_repo? ? nil : project_tags_path(project) + ) end def upload_anchor_data strong_memoize(:upload_anchor_data) do next unless can_current_user_push_to_default_branch? - AnchorData.new(false, - statistic_icon('upload') + _('Upload file'), - '#modal-upload-blob', - 'js-upload-file-trigger', - nil, - nil, - { - 'target_branch' => default_branch_or_main, - 'original_branch' => default_branch_or_main, - 'can_push_code' => 'true', - 'path' => project_create_blob_path(project, default_branch_or_main), - 'project_path' => project.full_path - } - ) + AnchorData.new( + false, + statistic_icon('upload') + _('Upload file'), + '#modal-upload-blob', + 'js-upload-file-trigger', + nil, + nil, + { + 'target_branch' => default_branch_or_main, + 'original_branch' => default_branch_or_main, + 'can_push_code' => 'true', + 'path' => project_create_blob_path(project, default_branch_or_main), + 'project_path' => project.full_path + } + ) end end @@ -266,37 +275,38 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated if can_current_user_push_to_default_branch? new_file_path = empty_repo? ? ide_edit_path(project, default_branch_or_main) : project_new_blob_path(project, default_branch_or_main) - AnchorData.new(false, - statistic_icon + _('New file'), - new_file_path, - 'btn-dashed') + AnchorData.new(false, statistic_icon + _('New file'), new_file_path, 'btn-dashed') end end def readme_anchor_data if can_current_user_push_to_default_branch? && readme_path.nil? - AnchorData.new(false, - statistic_icon + _('Add README'), - empty_repo? ? add_readme_ide_path : add_readme_path) + AnchorData.new(false, statistic_icon + _('Add README'), empty_repo? ? add_readme_ide_path : add_readme_path) elsif readme_path - AnchorData.new(false, - statistic_icon('doc-text') + _('README'), - default_view != 'readme' ? readme_path : '#readme', - 'btn-default', - 'doc-text') + AnchorData.new( + false, + statistic_icon('doc-text') + _('README'), + default_view != 'readme' ? readme_path : '#readme', + 'btn-default', + 'doc-text' + ) end end def changelog_anchor_data if can_current_user_push_to_default_branch? && repository.changelog.blank? - AnchorData.new(false, - statistic_icon + _('Add CHANGELOG'), - empty_repo? ? add_changelog_ide_path : add_changelog_path) + AnchorData.new( + false, + statistic_icon + _('Add CHANGELOG'), + empty_repo? ? add_changelog_ide_path : add_changelog_path + ) elsif repository.changelog.present? - AnchorData.new(false, - statistic_icon('doc-text') + _('CHANGELOG'), - changelog_path, - 'btn-default') + AnchorData.new( + false, + statistic_icon('doc-text') + _('CHANGELOG'), + changelog_path, + 'btn-default' + ) end end @@ -304,29 +314,37 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated icon = statistic_icon('scale') if repository.license_blob.present? - AnchorData.new(false, - icon + content_tag(:span, license_short_name, class: 'project-stat-value'), - license_path, - 'btn-default', - nil, - 'license') + AnchorData.new( + false, + icon + content_tag(:span, license_short_name, class: 'project-stat-value'), + license_path, + 'btn-default', + nil, + 'license' + ) elsif can_current_user_push_to_default_branch? - AnchorData.new(false, - content_tag(:span, statistic_icon + _('Add LICENSE'), class: 'add-license-link d-flex'), - empty_repo? ? add_license_ide_path : add_license_path) + AnchorData.new( + false, + content_tag(:span, statistic_icon + _('Add LICENSE'), class: 'add-license-link d-flex'), + empty_repo? ? add_license_ide_path : add_license_path + ) end end def contribution_guide_anchor_data if can_current_user_push_to_default_branch? && repository.contribution_guide.blank? - AnchorData.new(false, - statistic_icon + _('Add CONTRIBUTING'), - empty_repo? ? add_contribution_guide_ide_path : add_contribution_guide_path) + AnchorData.new( + false, + statistic_icon + _('Add CONTRIBUTING'), + empty_repo? ? add_contribution_guide_ide_path : add_contribution_guide_path + ) elsif repository.contribution_guide.present? - AnchorData.new(false, - statistic_icon('doc-text') + _('CONTRIBUTING'), - contribution_guide_path, - 'btn-default') + AnchorData.new( + false, + statistic_icon('doc-text') + _('CONTRIBUTING'), + contribution_guide_path, + 'btn-default' + ) end end @@ -335,35 +353,32 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated if current_user && can?(current_user, :admin_pipeline, project) && repository.gitlab_ci_yml.blank? && !show_auto_devops_callout if auto_devops_enabled? - AnchorData.new(false, - statistic_icon('settings') + _('Auto DevOps enabled'), - project_settings_ci_cd_path(project, anchor: 'autodevops-settings'), - 'btn-default') + AnchorData.new( + false, + statistic_icon('settings') + _('Auto DevOps enabled'), + project_settings_ci_cd_path(project, anchor: 'autodevops-settings'), + 'btn-default' + ) else - AnchorData.new(false, - statistic_icon + _('Enable Auto DevOps'), - project_settings_ci_cd_path(project, anchor: 'autodevops-settings')) + AnchorData.new( + false, + statistic_icon + _('Enable Auto DevOps'), + project_settings_ci_cd_path(project, anchor: 'autodevops-settings') + ) end elsif auto_devops_enabled? - AnchorData.new(false, - _('Auto DevOps enabled'), - nil) + AnchorData.new(false, _('Auto DevOps enabled'), nil) end end def kubernetes_cluster_anchor_data if can_instantiate_cluster? if clusters.empty? - AnchorData.new(false, - statistic_icon + _('Add Kubernetes cluster'), - project_clusters_path(project)) + AnchorData.new(false, statistic_icon + _('Add Kubernetes cluster'), project_clusters_path(project)) else cluster_link = clusters.count == 1 ? project_cluster_path(project, clusters.first) : project_clusters_path(project) - AnchorData.new(false, - _('Kubernetes'), - cluster_link, - 'btn-default') + AnchorData.new(false, _('Kubernetes'), cluster_link, 'btn-default') end end end @@ -372,14 +387,9 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated return unless can_view_pipeline_editor?(project) if cicd_missing? - AnchorData.new(false, - statistic_icon + _('Set up CI/CD'), - project_ci_pipeline_editor_path(project)) + AnchorData.new(false, statistic_icon + _('Set up CI/CD'), project_ci_pipeline_editor_path(project)) elsif repository.gitlab_ci_yml.present? - AnchorData.new(false, - statistic_icon('doc-text') + _('CI/CD configuration'), - project_ci_pipeline_editor_path(project), - 'btn-default') + AnchorData.new(false, statistic_icon('doc-text') + _('CI/CD configuration'), project_ci_pipeline_editor_path(project), 'btn-default') end end diff --git a/app/presenters/search_service_presenter.rb b/app/presenters/search_service_presenter.rb index d7d959217b0..91e67c379c4 100644 --- a/app/presenters/search_service_presenter.rb +++ b/app/presenters/search_service_presenter.rb @@ -2,6 +2,7 @@ class SearchServicePresenter < Gitlab::View::Presenter::Delegated include RendersCommits + include RendersProjectsList presents ::SearchService, as: :search_service @@ -28,6 +29,8 @@ class SearchServicePresenter < Gitlab::View::Presenter::Delegated objects.respond_to?(:eager_load) ? objects.eager_load(:status) : objects # rubocop:disable CodeReuse/ActiveRecord when 'commits' prepare_commits_for_rendering(objects) + when 'projects' + prepare_projects_for_rendering(objects) else objects end diff --git a/app/presenters/snippet_blob_presenter.rb b/app/presenters/snippet_blob_presenter.rb index 2e5d3ae21d9..84e98e18e32 100644 --- a/app/presenters/snippet_blob_presenter.rb +++ b/app/presenters/snippet_blob_presenter.rb @@ -40,9 +40,11 @@ class SnippetBlobPresenter < BlobPresenter end def render_rich_partial - renderer.render("projects/blob/viewers/_#{blob.rich_viewer.partial_name}", - locals: { viewer: blob.rich_viewer, blob: blob, blob_raw_path: raw_path, blob_raw_url: raw_url, parent_dir_raw_path: raw_directory }, - layout: false) + renderer.render( + "projects/blob/viewers/_#{blob.rich_viewer.partial_name}", + locals: { viewer: blob.rich_viewer, blob: blob, blob_raw_path: raw_path, blob_raw_url: raw_url, parent_dir_raw_path: raw_directory }, + layout: false + ) end def renderer |