Module: Taskable

Included in:
Issue, MergeRequest
Defined in:
app/models/concerns/taskable.rb

Overview

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

Constant Summary collapse

COMPLETED =
'completed'.freeze
INCOMPLETE =
'incomplete'.freeze
ITEM_PATTERN =
/
  ^
  (?:\s*[-+*]|(?:\d+\.))? # optional list prefix
  \s*                     # optional whitespace prefix
  (\[\s\]|\[[xX]\])       # checkbox
  (\s.+)                  # followed by whitespace and some text.
/x

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.get_tasks(content) ⇒ Object


20
21
22
23
24
25
# File 'app/models/concerns/taskable.rb', line 20

def self.get_tasks(content)
  content.to_s.scan(ITEM_PATTERN).map do |checkbox, label|
    # ITEM_PATTERN strips out the hyphen, but Item requires it. Rabble rabble.
    TaskList::Item.new("- #{checkbox}", label.strip)
  end
end

.get_updated_tasks(old_content:, new_content:) ⇒ Object


27
28
29
30
31
32
33
34
35
36
# File 'app/models/concerns/taskable.rb', line 27

def self.get_updated_tasks(old_content:, new_content:)
  old_tasks, new_tasks = get_tasks(old_content), get_tasks(new_content)

  new_tasks.select.with_index do |new_task, i|
    old_task = old_tasks[i]
    next unless old_task

    new_task.source == old_task.source && new_task.complete? != old_task.complete?
  end
end

Instance Method Details

#task_list_itemsObject

Called by `TaskList::Summary`


39
40
41
42
43
# File 'app/models/concerns/taskable.rb', line 39

def task_list_items
  return [] if description.blank?

  @task_list_items ||= Taskable.get_tasks(description)
end

#task_statusObject

Return a string that describes the current state of this Taskable's task list items, e.g. “20 tasks (12 completed, 8 remaining)”


56
57
58
59
60
61
# File 'app/models/concerns/taskable.rb', line 56

def task_status
  return '' if description.blank?

  sum = tasks.summary
  "#{sum.item_count} tasks (#{sum.complete_count} completed, #{sum.incomplete_count} remaining)"
end

#tasksObject


45
46
47
# File 'app/models/concerns/taskable.rb', line 45

def tasks
  @tasks ||= TaskList.new(self)
end

#tasks?Boolean

Return true if this object's description has any task list items.

Returns:

  • (Boolean)

50
51
52
# File 'app/models/concerns/taskable.rb', line 50

def tasks?
  tasks.summary.items?
end