Class: Issuable::DiscussionsListService

Inherits:
Object
  • Object
show all
Includes:
Gitlab::Utils::StrongMemoize
Defined in:
app/services/issuable/discussions_list_service.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(current_user, issuable, params = {}) ⇒ DiscussionsListService

Returns a new instance of DiscussionsListService.



11
12
13
14
15
# File 'app/services/issuable/discussions_list_service.rb', line 11

def initialize(current_user, issuable, params = {})
  @current_user = current_user
  @issuable = issuable
  @params = params.dup
end

Instance Attribute Details

#current_userObject (readonly)

Returns the value of attribute current_user.



9
10
11
# File 'app/services/issuable/discussions_list_service.rb', line 9

def current_user
  @current_user
end

#issuableObject (readonly)

Returns the value of attribute issuable.



9
10
11
# File 'app/services/issuable/discussions_list_service.rb', line 9

def issuable
  @issuable
end

#paramsObject (readonly)

Returns the value of attribute params.



9
10
11
# File 'app/services/issuable/discussions_list_service.rb', line 9

def params
  @params
end

Instance Method Details

#can_read_issuable_notes?Boolean

Returns:

  • (Boolean)


68
69
70
71
72
73
# File 'app/services/issuable/discussions_list_service.rb', line 68

def can_read_issuable_notes?
  return Ability.allowed?(current_user, :read_security_resource, issuable) if issuable.is_a?(Vulnerability)

  Ability.allowed?(current_user, :"read_#{issuable.to_ability_name}", issuable) &&
    Ability.allowed?(current_user, :read_note, issuable)
end

#executeObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'app/services/issuable/discussions_list_service.rb', line 17

def execute
  return Note.none unless can_read_issuable_notes?

  notes = NotesFinder.new(current_user, params.merge({ target: issuable, project: issuable.project }))
            .execute.with_web_entity_associations.inc_relations_for_view(issuable).order_created_at_id_asc

  if paginator
    paginated_discussions_by_type = paginator.records.group_by(&:table_name)

    notes = if paginated_discussions_by_type['notes'].present?
              notes.id_in(paginated_discussions_by_type['notes'].flat_map(&:ids))
            else
              notes.none
            end
  end

  if params[:notes_filter] != UserPreference::NOTES_FILTERS[:only_comments]
    notes = ResourceEvents::MergeIntoNotesService.new(
      issuable, current_user, paginated_notes: paginated_discussions_by_type
    ).execute(notes)
  end

  # Here we assume all notes belong to the same project as the work item
  project = notes.first&.project
  notes = ::Preloaders::Projects::NotesPreloader.new(project, current_user).call(notes)

  # Permission check required for system notes only:
  # - System notes may reference resources the user cannot access
  # - see Note#all_referenced_mentionables_allowed?
  #
  # Regular user notes don't need this check because:
  # - If user can access the work item, they have `read_note` ability
  # - Internal notes are separately filtered in NotesFinder.redact_internal
  notes = notes.select { |n| !n.system? || n.system_note_visible_for?(current_user) }

  discussions = Discussion.build_collection(notes, issuable)
  discussions.reverse! if params[:sort] && params[:sort] == :created_desc

  discussions
end

#paginatorObject



58
59
60
61
62
63
64
65
66
# File 'app/services/issuable/discussions_list_service.rb', line 58

def paginator
  return if params[:per_page].blank?

  strong_memoize(:paginator) do
    issuable
      .discussion_root_note_ids(notes_filter: params[:notes_filter], sort: params[:sort])
      .keyset_paginate(cursor: params[:cursor], per_page: params[:per_page].to_i)
  end
end