Welcome to mirror list, hosted at ThFree Co, Russian Federation.

taskable.rb « concerns « models « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: bbb3b301a9f5a1392ed6a97cdb9946de79c3258e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
# Contains functionality for objects that can have task lists in their
# descriptions.  Task list items can be added with Markdown like "* [x] Fix
# bugs".
#
# Used by MergeRequest and Issue
module Taskable
  TASK_PATTERN_MD = /^(?<bullet> *[*-] *)\[(?<checked>[ xX])\]/.freeze
  TASK_PATTERN_HTML = /^<li>(?<p_tag>\s*<p>)?\[(?<checked>[ xX])\]/.freeze

  # Change the state of a task list item for this Taskable.  Edit the object's
  # description by finding the nth task item and changing its checkbox
  # placeholder to "[x]" if +checked+ is true, or "[ ]" if it's false.
  # Note: task numbering starts with 1
  def update_nth_task(n, checked)
    index = 0
    check_char = checked ? 'x' : ' '

    # Do this instead of using #gsub! so that ActiveRecord detects that a field
    # has changed.
    self.description = self.description.gsub(TASK_PATTERN_MD) do |match|
      index += 1
      case index
      when n then "#{$LAST_MATCH_INFO[:bullet]}[#{check_char}]"
      else match
      end
    end

    save
  end

  # Return true if this object's description has any task list items.
  def tasks?
    description && description.match(TASK_PATTERN_MD)
  end

  # Return a string that describes the current state of this Taskable's task
  # list items, e.g. "20 tasks (12 done, 8 unfinished)"
  def task_status
    return nil unless description

    num_tasks = 0
    num_done = 0

    description.scan(TASK_PATTERN_MD) do
      num_tasks += 1
      num_done += 1 unless $LAST_MATCH_INFO[:checked] == ' '
    end

    "#{num_tasks} tasks (#{num_done} done, #{num_tasks - num_done} unfinished)"
  end
end