diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-18 11:17:02 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-18 11:17:02 +0300 |
commit | b39512ed755239198a9c294b6a45e65c05900235 (patch) | |
tree | d234a3efade1de67c46b9e5a38ce813627726aa7 /app/services/system_notes | |
parent | d31474cf3b17ece37939d20082b07f6657cc79a9 (diff) |
Add latest changes from gitlab-org/gitlab@15-3-stable-eev15.3.0-rc42
Diffstat (limited to 'app/services/system_notes')
-rw-r--r-- | app/services/system_notes/issuables_service.rb | 84 | ||||
-rw-r--r-- | app/services/system_notes/time_tracking_service.rb | 71 |
2 files changed, 115 insertions, 40 deletions
diff --git a/app/services/system_notes/issuables_service.rb b/app/services/system_notes/issuables_service.rb index f9e5c3725d8..75903fde39e 100644 --- a/app/services/system_notes/issuables_service.rb +++ b/app/services/system_notes/issuables_service.rb @@ -178,6 +178,24 @@ module SystemNotes create_note(NoteSummary.new(noteable, project, author, body, action: 'title')) end + # Called when the hierarchy of a work item is changed + # + # noteable - Noteable object that responds to `work_item_parent` and `work_item_children` + # project - Project owning noteable + # author - User performing the change + # + # Example Note text: + # + # "added #1 as child Task" + # + # Returns the created Note object + def hierarchy_changed(work_item, action) + params = hierarchy_note_params(action, noteable, work_item) + + create_note(NoteSummary.new(noteable, project, author, params[:parent_note_body], action: params[:parent_action])) + create_note(NoteSummary.new(work_item, project, author, params[:child_note_body], action: params[:child_action])) + end + # Called when the description of a Noteable is changed # # noteable - Noteable object that responds to `description` @@ -255,12 +273,12 @@ module SystemNotes # # Example Note text: # - # "marked the task Whatever as completed." + # "marked the checklist item Whatever as completed." # # Returns the created Note object def change_task_status(new_task) status_label = new_task.complete? ? Taskable::COMPLETED : Taskable::INCOMPLETE - body = "marked the task **#{new_task.source}** as #{status_label}" + body = "marked the checklist item **#{new_task.source}** as #{status_label}" issue_activity_counter.track_issue_description_changed_action(author: author) if noteable.is_a?(Issue) @@ -294,13 +312,14 @@ module SystemNotes # # noteable_ref - Referenced noteable # direction - symbol, :to or :from + # created_at - timestamp for the system note, defaults to current time # # Example Note text: # # "cloned to some_namespace/project_new#11" # # Returns the created Note object - def noteable_cloned(noteable_ref, direction) + def noteable_cloned(noteable_ref, direction, created_at: nil) unless [:to, :from].include?(direction) raise ArgumentError, "Invalid direction `#{direction}`" end @@ -308,9 +327,11 @@ module SystemNotes cross_reference = noteable_ref.to_reference(project) body = "cloned #{direction} #{cross_reference}" - issue_activity_counter.track_issue_cloned_action(author: author) if noteable.is_a?(Issue) && direction == :to + if noteable.is_a?(Issue) && direction == :to + issue_activity_counter.track_issue_cloned_action(author: author, project: project) + end - create_note(NoteSummary.new(noteable, project, author, body, action: 'cloned')) + create_note(NoteSummary.new(noteable, project, author, body, action: 'cloned', created_at: created_at)) end # Called when the confidentiality changes @@ -367,36 +388,6 @@ module SystemNotes existing_mentions_for(mentioned_in, noteable, notes).exists? end - # Called when a user's attention has been requested for a Notable - # - # user - User's whos attention has been requested - # - # Example Note text: - # - # "requested attention from @eli.wisoky" - # - # Returns the created Note object - def request_attention(user) - body = "requested attention from #{user.to_reference}" - - create_note(NoteSummary.new(noteable, project, author, body, action: 'attention_requested')) - end - - # Called when a user's attention request has been removed for a Notable - # - # user - User's whos attention request has been removed - # - # Example Note text: - # - # "removed attention request from @eli.wisoky" - # - # Returns the created Note object - def remove_attention_request(user) - body = "removed attention request from #{user.to_reference}" - - create_note(NoteSummary.new(noteable, project, author, body, action: 'attention_request_removed')) - end - # Called when a Noteable has been marked as the canonical Issue of a duplicate # # duplicate_issue - Issue that was a duplicate of this @@ -506,6 +497,29 @@ module SystemNotes def track_cross_reference_action issue_activity_counter.track_issue_cross_referenced_action(author: author) if noteable.is_a?(Issue) end + + def hierarchy_note_params(action, parent, child) + return {} unless child && parent + + child_type = child.issue_type.humanize(capitalize: false) + parent_type = parent.issue_type.humanize(capitalize: false) + + if action == 'relate' + { + parent_note_body: "added #{child.to_reference} as child #{child_type}", + child_note_body: "added #{parent.to_reference} as parent #{parent_type}", + parent_action: 'relate_to_child', + child_action: 'relate_to_parent' + } + else + { + parent_note_body: "removed child #{child_type} #{child.to_reference}", + child_note_body: "removed parent #{parent_type} #{parent.to_reference}", + parent_action: 'unrelate_from_child', + child_action: 'unrelate_from_parent' + } + end + end end end diff --git a/app/services/system_notes/time_tracking_service.rb b/app/services/system_notes/time_tracking_service.rb index a9b1f6d3d37..68df52a03c7 100644 --- a/app/services/system_notes/time_tracking_service.rb +++ b/app/services/system_notes/time_tracking_service.rb @@ -2,8 +2,9 @@ module SystemNotes class TimeTrackingService < ::SystemNotes::BaseService - # Called when the due_date of a Noteable is changed + # Called when the start_date or due_date of an Issue/WorkItem is changed # + # start_date - Start date being assigned, or nil # due_date - Due date being assigned, or nil # # Example Note text: @@ -11,14 +12,23 @@ module SystemNotes # "removed due date" # # "changed due date to September 20, 2018" + + # "changed start date to September 20, 2018 and changed due date to September 25, 2018" # # Returns the created Note object - def change_due_date(due_date) - body = due_date ? "changed due date to #{due_date.to_s(:long)}" : 'removed due date' + def change_start_date_or_due_date(changed_dates = {}) + return if changed_dates.empty? + + # Using instance_of because WorkItem < Issue. We don't want to track work item updates as issue updates + if noteable.instance_of?(Issue) && changed_dates.key?('due_date') + issue_activity_counter.track_issue_due_date_changed_action(author: author) + end - issue_activity_counter.track_issue_due_date_changed_action(author: author) if noteable.is_a?(Issue) + work_item_activity_counter.track_work_item_date_changed_action(author: author) if noteable.is_a?(WorkItem) - create_note(NoteSummary.new(noteable, project, author, body, action: 'due_date')) + create_note( + NoteSummary.new(noteable, project, author, changed_date_body(changed_dates), action: 'start_date_or_due_date') + ) end # Called when the estimated time of a Noteable is changed @@ -76,6 +86,32 @@ module SystemNotes create_note(NoteSummary.new(noteable, project, author, body, action: 'time_tracking')) end + # Called when a timelog is added to an issuable + # + # timelog - Added timelog + # + # Example Note text: + # + # "subtracted 1h 15m of time spent" + # + # "added 2h 30m of time spent" + # + # Returns the created Note object + def created_timelog(timelog) + time_spent = timelog.time_spent + spent_at = timelog.spent_at&.to_date + parsed_time = Gitlab::TimeTrackingFormatter.output(time_spent.abs) + action = time_spent > 0 ? 'added' : 'subtracted' + + text_parts = ["#{action} #{parsed_time} of time spent"] + text_parts << "at #{spent_at}" if spent_at && spent_at != DateTime.current.to_date + body = text_parts.join(' ') + + issue_activity_counter.track_issue_time_spent_changed_action(author: author) if noteable.is_a?(Issue) + + create_note(NoteSummary.new(noteable, project, author, body, action: 'time_tracking')) + end + def remove_timelog(timelog) time_spent = timelog.time_spent spent_at = timelog.spent_at&.to_date @@ -90,8 +126,33 @@ module SystemNotes private + def changed_date_body(changed_dates) + %w[start_date due_date].each_with_object([]) do |date_field, word_array| + next unless changed_dates.key?(date_field) + + word_array << 'and' if word_array.any? + + word_array << message_for_changed_date(changed_dates, date_field) + end.join(' ') + end + + def message_for_changed_date(changed_dates, date_key) + changed_date = changed_dates[date_key].last + readable_date = date_key.humanize.downcase + + if changed_date.nil? + "removed #{readable_date}" + else + "changed #{readable_date} to #{changed_date.to_s(:long)}" + end + end + def issue_activity_counter Gitlab::UsageDataCounters::IssueActivityUniqueCounter end + + def work_item_activity_counter + Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter + end end end |