Module: ProjectsHelper
- Included in:
- GitlabRoutingHelper, MergeRequestWidgetEntity
- Defined in:
- app/helpers/projects_helper.rb
Instance Method Summary collapse
- #able_to_see_issues?(project, user) ⇒ Boolean
- #able_to_see_merge_requests?(project, user) ⇒ Boolean
-
#any_projects?(projects) ⇒ Boolean
Returns true if any projects are present.
- #author_content_tag(author, opts = {}) ⇒ Object
- #autodeploy_flash_notice(branch_name) ⇒ Object
- #can_admin_project_member?(project) ⇒ Boolean
- #can_change_visibility_level?(project, current_user) ⇒ Boolean
- #can_disable_emails?(project, current_user) ⇒ Boolean
-
#delete_confirm_phrase(project) ⇒ Object
Returns the confirm phrase the user needs to type in order to delete the project.
- #directory? ⇒ Boolean
- #error_tracking_setting_project_json ⇒ Object
- #explore_projects_tab? ⇒ Boolean
- #external_classification_label_help_message ⇒ Object
- #fork_button_disabled_tooltip(project) ⇒ Object
- #grafana_integration_enabled? ⇒ Boolean
- #grafana_integration_masked_token ⇒ Object
- #grafana_integration_url ⇒ Object
- #import_from_bitbucket_message ⇒ Object
- #import_from_gitlab_message ⇒ Object
- #last_push_event ⇒ Object
- #link_to_autodeploy_doc ⇒ Object
- #link_to_member(project, author, opts = {}, &block) ⇒ Object
- #link_to_member_avatar(author, opts = {}) ⇒ Object
- #link_to_project(project) ⇒ Object
- #load_pipeline_status(projects) ⇒ Object
- #membership_locked? ⇒ Boolean
- #metrics_dashboard_timezone ⇒ Object
- #metrics_external_dashboard_url ⇒ Object
- #no_password_message ⇒ Object
- #project_can_be_shared? ⇒ Boolean
- #project_classes(project) ⇒ Object
- #project_incident_management_setting ⇒ Object
- #project_license_name(project) ⇒ Object
- #project_list_cache_key(project, pipeline_status: true) ⇒ Object
- #project_permissions_panel_data(project) ⇒ Object
- #project_search_tabs?(tab) ⇒ Boolean
- #project_title(project) ⇒ Object
- #push_to_create_project_command(user = current_user) ⇒ Object
- #remove_fork_project_confirm_json(project, remove_form_id) ⇒ Object
- #remove_fork_project_description_message(project) ⇒ Object
- #remove_fork_project_warning_message(project) ⇒ Object
- #remove_project_message(project) ⇒ Object
- #share_project_description(project) ⇒ Object
- #show_auto_devops_implicitly_enabled_banner?(project, user) ⇒ Boolean
- #show_issue_count?(disabled: false, compact_mode: false) ⇒ Boolean
- #show_merge_request_count?(disabled: false, compact_mode: false) ⇒ Boolean
- #show_no_password_message? ⇒ Boolean
- #show_no_ssh_key_message? ⇒ Boolean
-
#show_projects?(projects, params) ⇒ Boolean
TODO: Remove this method when removing the feature flag gitlab.com/gitlab-org/gitlab/merge_requests/11209#note_162234863 make sure to remove from the EE specific controller as well: ee/app/controllers/ee/dashboard/projects_controller.rb.
- #show_terraform_banner?(project) ⇒ Boolean
- #show_xcode_link?(project = @project) ⇒ Boolean
- #transfer_project_message(project) ⇒ Object
- #visible_fork_source(project) ⇒ Object
- #xcode_uri_to_repo(project = @project) ⇒ Object
Instance Method Details
#able_to_see_issues?(project, user) ⇒ Boolean
423 424 425 |
# File 'app/helpers/projects_helper.rb', line 423 def able_to_see_issues?(project, user) project.issues_enabled? && can?(user, :read_issue, project) end |
#able_to_see_merge_requests?(project, user) ⇒ Boolean
427 428 429 |
# File 'app/helpers/projects_helper.rb', line 427 def able_to_see_merge_requests?(project, user) project.merge_requests_enabled? && can?(user, :read_merge_request, project) end |
#any_projects?(projects) ⇒ Boolean
Returns true if any projects are present.
If the relation has a LIMIT applied we'll cast the relation to an Array since repeated any? checks would otherwise result in multiple COUNT queries being executed.
If no limit is applied we'll just issue a COUNT since the result set could be too large to load into memory.
244 245 246 247 248 249 250 251 252 |
# File 'app/helpers/projects_helper.rb', line 244 def any_projects?(projects) return projects.any? if projects.is_a?(Array) if projects.limit_value projects.to_a.any? else projects.except(:offset).any? end end |
#author_content_tag(author, opts = {}) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'app/helpers/projects_helper.rb', line 34 def (, opts = {}) default_opts = { author_class: 'author', tooltip: false, by_username: false } opts = default_opts.merge(opts) has_tooltip = !opts[:by_username] && opts[:tooltip] username = opts[:by_username] ? .to_reference : .name = { class: [opts[:author_class]] } if has_tooltip [:title] = .to_reference [:data] = { placement: 'top' } [:class] << 'has-tooltip' end # NOTE: ActionView::Helpers::TagHelper#content_tag HTML escapes username content_tag(:span, username, ) end |
#autodeploy_flash_notice(branch_name) ⇒ Object
166 167 168 169 |
# File 'app/helpers/projects_helper.rb', line 166 def autodeploy_flash_notice(branch_name) html_escape(_("Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}")) % { branch_name: tag.strong(truncate(sanitize(branch_name))), link_to_autodeploy_doc: link_to_autodeploy_doc } end |
#can_admin_project_member?(project) ⇒ Boolean
322 323 324 |
# File 'app/helpers/projects_helper.rb', line 322 def can_admin_project_member?(project) Ability.allowed?(current_user, :admin_project_member, project) && !membership_locked? end |
#can_change_visibility_level?(project, current_user) ⇒ Boolean
148 149 150 |
# File 'app/helpers/projects_helper.rb', line 148 def can_change_visibility_level?(project, current_user) can?(current_user, :change_visibility_level, project) end |
#can_disable_emails?(project, current_user) ⇒ Boolean
152 153 154 155 156 |
# File 'app/helpers/projects_helper.rb', line 152 def can_disable_emails?(project, current_user) return false if project.group&.emails_disabled? can?(current_user, :set_emails_disabled, project) end |
#delete_confirm_phrase(project) ⇒ Object
Returns the confirm phrase the user needs to type in order to delete the project
Thus the phrase should include the namespace to make it very clear to the user which project is subject to deletion. Relevant issue: gitlab.com/gitlab-org/gitlab/-/issues/343591
419 420 421 |
# File 'app/helpers/projects_helper.rb', line 419 def delete_confirm_phrase(project) project.path_with_namespace end |
#directory? ⇒ Boolean
308 309 310 |
# File 'app/helpers/projects_helper.rb', line 308 def directory? @path.present? end |
#error_tracking_setting_project_json ⇒ Object
294 295 296 297 298 299 300 301 302 303 304 305 306 |
# File 'app/helpers/projects_helper.rb', line 294 def error_tracking_setting_project_json setting = @project.error_tracking_setting return if setting.blank? || setting.project_slug.blank? || setting.organization_slug.blank? { name: setting.project_name, organization_name: setting.organization_name, organization_slug: setting.organization_slug, slug: setting.project_slug }.to_json end |
#explore_projects_tab? ⇒ Boolean
280 281 282 283 284 |
# File 'app/helpers/projects_helper.rb', line 280 def explore_projects_tab? current_page?(explore_projects_path) || current_page?(trending_explore_projects_path) || current_page?(starred_explore_projects_path) end |
#external_classification_label_help_message ⇒ Object
312 313 314 315 316 317 318 319 320 |
# File 'app/helpers/projects_helper.rb', line 312 def default_label = ::Gitlab::CurrentSettings.current_application_settings . s_( "ExternalAuthorizationService|When no classification label is set the "\ "default label `%{default_label}` will be used." ) % { default_label: default_label } end |
#fork_button_disabled_tooltip(project) ⇒ Object
431 432 433 434 435 436 437 438 439 |
# File 'app/helpers/projects_helper.rb', line 431 def (project) return unless current_user if !current_user.can?(:fork_project, project) s_("ProjectOverview|You don't have permission to fork this project") elsif !current_user.can?(:create_fork) s_('ProjectOverview|You have reached your project limit') end end |
#grafana_integration_enabled? ⇒ Boolean
366 367 368 |
# File 'app/helpers/projects_helper.rb', line 366 def grafana_integration_enabled? @project.grafana_integration&.enabled? end |
#grafana_integration_masked_token ⇒ Object
362 363 364 |
# File 'app/helpers/projects_helper.rb', line 362 def grafana_integration_masked_token @project.grafana_integration&.masked_token end |
#grafana_integration_url ⇒ Object
358 359 360 |
# File 'app/helpers/projects_helper.rb', line 358 def grafana_integration_url @project.grafana_integration&.grafana_url end |
#import_from_bitbucket_message ⇒ Object
441 442 443 |
# File 'app/helpers/projects_helper.rb', line 441 def ('Bitbucket', help_page_path("integration/bitbucket")) end |
#import_from_gitlab_message ⇒ Object
445 446 447 |
# File 'app/helpers/projects_helper.rb', line 445 def ('GitLab.com', help_page_path("integration/gitlab")) end |
#last_push_event ⇒ Object
158 159 160 |
# File 'app/helpers/projects_helper.rb', line 158 def last_push_event current_user&.recent_push(@project) end |
#link_to_autodeploy_doc ⇒ Object
162 163 164 |
# File 'app/helpers/projects_helper.rb', line 162 def link_to_autodeploy_doc link_to _('About auto deploy'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank', rel: 'noopener' end |
#link_to_member(project, author, opts = {}, &block) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'app/helpers/projects_helper.rb', line 53 def link_to_member(project, , opts = {}, &block) default_opts = { avatar: true, name: true, title: ":name" } opts = default_opts.merge(opts) return "(deleted)" unless data_attrs = { user_id: .id, username: .username, name: .name } inject_classes = ["author-link", opts[:extra_class]] if opts[:name] inject_classes.concat(["js-user-link", opts[:mobile_classes]]) else inject_classes.append( "has-tooltip" ) end inject_classes = inject_classes.compact.join(" ") = [] # Build avatar image tag << link_to_member_avatar(, opts) if opts[:avatar] # Build name span tag << (, opts) if opts[:name] << capture(&block) if block = .join.html_safe if opts[:name] link_to(, user_path(), class: inject_classes, data: data_attrs).html_safe else title = opts[:title].sub(":name", sanitize(.name)) link_to(, user_path(), class: inject_classes, title: title, data: { container: 'body', qa_selector: 'assignee_link' }).html_safe end end |
#link_to_member_avatar(author, opts = {}) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 |
# File 'app/helpers/projects_helper.rb', line 22 def link_to_member_avatar(, opts = {}) default_opts = { size: 16 } opts = default_opts.merge(opts) classes = %W[avatar avatar-inline s#{opts[:size]}] classes << opts[:avatar_class] if opts[:avatar_class] avatar = avatar_icon_for_user(, opts[:size]) image_tag(avatar, width: opts[:size], class: classes, alt: '') end |
#link_to_project(project) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'app/helpers/projects_helper.rb', line 9 def link_to_project(project) link_to namespace_project_path(namespace_id: project.namespace, id: project), title: h(project.name), class: 'gl-link' do title = content_tag(:span, project.name, class: 'project-name') if project.namespace namespace = content_tag(:span, "#{project.namespace.human_name} / ", class: 'namespace-name') title = namespace + title end title end end |
#load_pipeline_status(projects) ⇒ Object
191 192 193 194 |
# File 'app/helpers/projects_helper.rb', line 191 def load_pipeline_status(projects) Gitlab::Cache::Ci::ProjectPipelineStatus .load_in_batch_for_projects(projects) end |
#membership_locked? ⇒ Boolean
330 331 332 |
# File 'app/helpers/projects_helper.rb', line 330 def membership_locked? false end |
#metrics_dashboard_timezone ⇒ Object
354 355 356 |
# File 'app/helpers/projects_helper.rb', line 354 def metrics_dashboard_timezone @project.metrics_setting_dashboard_timezone end |
#metrics_external_dashboard_url ⇒ Object
350 351 352 |
# File 'app/helpers/projects_helper.rb', line 350 def metrics_external_dashboard_url @project.metrics_setting_external_dashboard_url end |
#no_password_message ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'app/helpers/projects_helper.rb', line 214 def push_pull_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('topics/git/terminology', anchor: 'pull-and-push') } clone_with_https_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('gitlab-basics/start-using-git', anchor: 'clone-with-https') } set_password_link_start = '<a href="%{url}">'.html_safe % { url: edit_profile_password_path } set_up_pat_link_start = '<a href="%{url}">'.html_safe % { url: profile_personal_access_tokens_path } = if current_user.require_password_creation_for_git? _('Your account is authenticated with SSO or SAML. To %{push_pull_link_start}push and pull%{link_end} over %{protocol} with Git using this account, you must %{set_password_link_start}set a password%{link_end} or %{set_up_pat_link_start}set up a Personal Access Token%{link_end} to use instead of a password. For more information, see %{clone_with_https_link_start}Clone with HTTPS%{link_end}.') else _('Your account is authenticated with SSO or SAML. To %{push_pull_link_start}push and pull%{link_end} over %{protocol} with Git using this account, you must %{set_up_pat_link_start}set up a Personal Access Token%{link_end} to use instead of a password. For more information, see %{clone_with_https_link_start}Clone with HTTPS%{link_end}.') end html_escape() % { push_pull_link_start: push_pull_link_start, protocol: gitlab_config.protocol.upcase, clone_with_https_link_start: clone_with_https_link_start, set_password_link_start: set_password_link_start, set_up_pat_link_start: set_up_pat_link_start, link_end: '</a>'.html_safe } end |
#project_can_be_shared? ⇒ Boolean
326 327 328 |
# File 'app/helpers/projects_helper.rb', line 326 def project_can_be_shared? !membership_locked? || @project.allowed_to_share_with_group? end |
#project_classes(project) ⇒ Object
408 409 410 411 412 |
# File 'app/helpers/projects_helper.rb', line 408 def project_classes(project) return "project-highlight-puc" if project.warn_about_potentially_unwanted_characters? "" end |
#project_incident_management_setting ⇒ Object
4 5 6 7 |
# File 'app/helpers/projects_helper.rb', line 4 def project_incident_management_setting @project_incident_management_setting ||= @project.incident_management_setting || @project.build_incident_management_setting end |
#project_license_name(project) ⇒ Object
370 371 372 373 374 375 376 377 378 379 |
# File 'app/helpers/projects_helper.rb', line 370 def project_license_name(project) key = "project:#{project.id}:license_name" Gitlab::SafeRequestStore.fetch(key) { project.repository.license&.name } rescue GRPC::Unavailable, GRPC::DeadlineExceeded, Gitlab::Git::CommandError => e Gitlab::ErrorTracking.track_exception(e) Gitlab::SafeRequestStore[key] = nil nil end |
#project_list_cache_key(project, pipeline_status: true) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'app/helpers/projects_helper.rb', line 171 def project_list_cache_key(project, pipeline_status: true) key = [ project.route.cache_key, project.cache_key, project.last_activity_date, controller.controller_name, controller.action_name, Gitlab::CurrentSettings.cache_key, "cross-project:#{can?(current_user, :read_cross_project)}", max_project_member_access_cache_key(project), pipeline_status, Gitlab::I18n.locale, 'v2.6' ] key << pipeline_status_cache_key(project.pipeline_status) if pipeline_status && project.pipeline_status.has_status? key end |
#project_permissions_panel_data(project) ⇒ Object
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'app/helpers/projects_helper.rb', line 385 def (project) { packagesAvailable: ::Gitlab.config.packages.enabled, packagesHelpPath: help_page_path('user/packages/index'), currentSettings: (project), canDisableEmails: can_disable_emails?(project, current_user), canChangeVisibilityLevel: can_change_visibility_level?(project, current_user), allowedVisibilityOptions: project_allowed_visibility_levels(project), visibilityHelpPath: help_page_path('public_access/public_access'), registryAvailable: Gitlab.config.registry.enabled, registryHelpPath: help_page_path('user/packages/container_registry/index'), lfsAvailable: Gitlab.config.lfs.enabled, lfsHelpPath: help_page_path('topics/git/lfs/index'), lfsObjectsExist: project.lfs_objects.exists?, lfsObjectsRemovalHelpPath: help_page_path('topics/git/lfs/index', anchor: 'removing-objects-from-lfs'), pagesAvailable: Gitlab.config.pages.enabled, pagesAccessControlEnabled: Gitlab.config.pages.access_control, pagesAccessControlForced: ::Gitlab::Pages.access_control_is_forced?, pagesHelpPath: help_page_path('user/project/pages/introduction', anchor: 'gitlab-pages-access-control'), issuesHelpPath: help_page_path('user/project/issues/index') } end |
#project_search_tabs?(tab) ⇒ Boolean
142 143 144 145 146 |
# File 'app/helpers/projects_helper.rb', line 142 def project_search_tabs?(tab) abilities = Array(search_tab_ability_map[tab]) abilities.any? { |ability| can?(current_user, ability, @project) } end |
#project_title(project) ⇒ Object
91 92 93 94 95 96 97 98 99 |
# File 'app/helpers/projects_helper.rb', line 91 def project_title(project) namespace_link = (project) project_link = (project) namespace_link = (namespace_link) unless project.group project_link = project_link "#{namespace_link} #{project_link}".html_safe end |
#push_to_create_project_command(user = current_user) ⇒ Object
261 262 263 264 265 266 267 268 269 270 |
# File 'app/helpers/projects_helper.rb', line 261 def push_to_create_project_command(user = current_user) repository_url = if Gitlab::CurrentSettings.current_application_settings.enabled_git_access_protocol == 'http' user_url(user) else Gitlab.config.gitlab_shell.ssh_path_prefix + user.username end "git push --set-upstream #{repository_url}/$(git rev-parse --show-toplevel | xargs basename).git $(git rev-parse --abbrev-ref HEAD)" end |
#remove_fork_project_confirm_json(project, remove_form_id) ⇒ Object
129 130 131 132 133 134 135 136 |
# File 'app/helpers/projects_helper.rb', line 129 def remove_fork_project_confirm_json(project, remove_form_id) { remove_form_id: remove_form_id, button_text: _('Remove fork relationship'), confirm_danger_message: (project), phrase: @project.path } end |
#remove_fork_project_description_message(project) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'app/helpers/projects_helper.rb', line 111 def (project) source = visible_fork_source(project) if source msg = _('This will remove the fork relationship between this project and %{fork_source}.') % { fork_source: link_to(source.full_name, project_path(source)) } msg.html_safe else _('This will remove the fork relationship between this project and other projects in the fork network.') end end |
#remove_fork_project_warning_message(project) ⇒ Object
124 125 126 127 |
# File 'app/helpers/projects_helper.rb', line 124 def (project) _("You are going to remove the fork relationship from %{project_full_name}. Are you ABSOLUTELY sure?") % { project_full_name: project.full_name } end |
#remove_project_message(project) ⇒ Object
101 102 103 104 |
# File 'app/helpers/projects_helper.rb', line 101 def (project) _("You are going to delete %{project_full_name}. Deleted projects CANNOT be restored! Are you ABSOLUTELY sure?") % { project_full_name: project.full_name } end |
#share_project_description(project) ⇒ Object
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'app/helpers/projects_helper.rb', line 334 def share_project_description(project) share_with_group = project.allowed_to_share_with_group? share_with_members = !membership_locked? description = if share_with_group && share_with_members _("You can invite a new member to %{project_name} or invite another group.") elsif share_with_group _("You can invite another group to %{project_name}.") elsif share_with_members _("You can invite a new member to %{project_name}.") end html_escape(description) % { project_name: tag.strong(project.name) } end |
#show_auto_devops_implicitly_enabled_banner?(project, user) ⇒ Boolean
208 209 210 211 212 |
# File 'app/helpers/projects_helper.rb', line 208 def (project, user) return false unless (project, user) ["hide_auto_devops_implicitly_enabled_banner_#{project.id}".to_sym].blank? end |
#show_issue_count?(disabled: false, compact_mode: false) ⇒ Boolean
290 291 292 |
# File 'app/helpers/projects_helper.rb', line 290 def show_issue_count?(disabled: false, compact_mode: false) !disabled && !compact_mode end |
#show_merge_request_count?(disabled: false, compact_mode: false) ⇒ Boolean
286 287 288 |
# File 'app/helpers/projects_helper.rb', line 286 def show_merge_request_count?(disabled: false, compact_mode: false) !disabled && !compact_mode end |
#show_no_password_message? ⇒ Boolean
203 204 205 206 |
# File 'app/helpers/projects_helper.rb', line 203 def [:hide_no_password_message].blank? && !current_user.hide_no_password && current_user.require_extra_setup_for_git_auth? end |
#show_no_ssh_key_message? ⇒ Boolean
196 197 198 199 200 201 |
# File 'app/helpers/projects_helper.rb', line 196 def Gitlab::CurrentSettings. && [:hide_no_ssh_message].blank? && !current_user.hide_no_ssh_key && current_user.require_ssh_key? end |
#show_projects?(projects, params) ⇒ Boolean
TODO: Remove this method when removing the feature flag gitlab.com/gitlab-org/gitlab/merge_requests/11209#note_162234863 make sure to remove from the EE specific controller as well: ee/app/controllers/ee/dashboard/projects_controller.rb
257 258 259 |
# File 'app/helpers/projects_helper.rb', line 257 def show_projects?(projects, params) Feature.enabled?(:project_list_filter_bar) || !!(params[:personal] || params[:name] || any_projects?(projects)) end |
#show_terraform_banner?(project) ⇒ Boolean
381 382 383 |
# File 'app/helpers/projects_helper.rb', line 381 def (project) Feature.enabled?(:show_terraform_banner, type: :ops) && project.repository_languages.with_programming_language('HCL').exists? && project.terraform_states.empty? end |
#show_xcode_link?(project = @project) ⇒ Boolean
272 273 274 |
# File 'app/helpers/projects_helper.rb', line 272 def show_xcode_link?(project = @project) browser.platform.mac? && project.repository.xcode_project? end |
#transfer_project_message(project) ⇒ Object
106 107 108 109 |
# File 'app/helpers/projects_helper.rb', line 106 def (project) _("You are going to transfer %{project_full_name} to another namespace. Are you ABSOLUTELY sure?") % { project_full_name: project.full_name } end |
#visible_fork_source(project) ⇒ Object
138 139 140 |
# File 'app/helpers/projects_helper.rb', line 138 def visible_fork_source(project) project.fork_source if project.fork_source && can?(current_user, :read_project, project.fork_source) end |
#xcode_uri_to_repo(project = @project) ⇒ Object
276 277 278 |
# File 'app/helpers/projects_helper.rb', line 276 def xcode_uri_to_repo(project = @project) "xcode://clone?repo=#{CGI.escape(default_url_to_repo(project))}" end |