Class: Taf
- Inherits:
-
Object
- Object
- Taf
- Defined in:
- lib/taf/models/taf.rb
Class Method Summary collapse
-
.backup(file) ⇒ Object
Creates a backup of the file.
-
.restore(file) ⇒ Object
Restores the backup file and deletes it.
Instance Method Summary collapse
-
#add_todo(text, tag: nil, parent_id: nil) ⇒ Object
Adds a new item.
-
#cleanup ⇒ Object
Sorts all items (todo items before done items) and saves.
-
#delete(item) ⇒ Object
Deletes the item (and all its children).
-
#display_item_recursive(item, indent_level, highlight_signatures) ⇒ Object
Recursively displays an item and its children with proper indentation.
-
#find_item_by_id(id) ⇒ Object
Finds a todo item by its index across all tags (searches recursively).
-
#initialize(file) ⇒ Taf
constructor
A new instance of Taf.
-
#mark_ancestors_todo(item) ⇒ Object
Recursively marks all ancestors as todo and returns those that changed.
-
#mark_descendants_done(item) ⇒ Object
Recursively marks all descendants as done and returns those that changed.
-
#purge ⇒ Object
Deletes all done items (and their children) and saves.
-
#show_all(highlight_signatures: nil) ⇒ Object
Shows all tags and items.
-
#show_tag(tag, highlight_signatures: nil) ⇒ Object
Shows given tag and its items.
-
#toggle(item) ⇒ Object
Toggles the status of the item Toggles ancestors and descendants accordingly.
Constructor Details
#initialize(file) ⇒ Taf
Returns a new instance of Taf.
8 9 10 11 12 13 |
# File 'lib/taf/models/taf.rb', line 8 def initialize(file) @file = file @taf = MarkdownAdapter.read(file) assign_indices @presenter = TerminalPresenter.new end |
Class Method Details
.backup(file) ⇒ Object
Creates a backup of the file
16 17 18 |
# File 'lib/taf/models/taf.rb', line 16 def self.backup(file) FileUtils.cp(file, "#{file}.backup") if File.exist?(file) end |
.restore(file) ⇒ Object
Restores the backup file and deletes it
21 22 23 24 25 26 27 28 29 |
# File 'lib/taf/models/taf.rb', line 21 def self.restore(file) backup_file = "#{file}.backup" unless File.exist?(backup_file) raise ArgumentError, "No backup file found" end FileUtils.cp(backup_file, file) File.delete(backup_file) end |
Instance Method Details
#add_todo(text, tag: nil, parent_id: nil) ⇒ Object
Adds a new item
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/taf/models/taf.rb', line 32 def add_todo(text, tag: nil, parent_id: nil) # Avoids flag typos raise ArgumentError, "Text must be #{Todo::MIN_LENGTH} or more characters" unless text.size >= Todo::MIN_LENGTH # Default tag if neither tag nor parent specified if tag.nil? && parent_id.nil? tag = TafHelper::DEFAULT_TAG end changed = [] if parent_id parent_item = find_item_by_id(parent_id) unless parent_item raise ArgumentError, "Parent with id #{parent_id} not found" end new_item = Todo.new( status: "todo", text: text, children: [], parent: parent_item ) parent_item.children << new_item changed = mark_ancestors_todo(parent_item) else new_item = Todo.new( status: "todo", text: text, children: [] ) if @taf[tag] # Tag exists, append to root level @taf[tag] << new_item else # Create new tag @taf[tag] = [new_item] end end changed << new_item assign_indices save changed.map(&:signature) end |
#cleanup ⇒ Object
Sorts all items (todo items before done items) and saves
178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/taf/models/taf.rb', line 178 def cleanup # Sort items: within each parent, todo items before done items @taf.each_value do |items| items.each do |item| sort_children_recursive(item) end # Sort root level items items.sort_by! { |item| item.status == "done" ? 1 : 0 } end save end |
#delete(item) ⇒ Object
Deletes the item (and all its children)
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/taf/models/taf.rb', line 150 def delete(item) if item.parent # Remove from parent's children item.parent.children.delete(item) else # Remove from root level @taf.each_value do |items| if items.delete(item) break end end end save end |
#display_item_recursive(item, indent_level, highlight_signatures) ⇒ Object
Recursively displays an item and its children with proper indentation
103 104 105 106 107 108 |
# File 'lib/taf/models/taf.rb', line 103 def display_item_recursive(item, indent_level, highlight_signatures) @presenter.display_todo(item, indent_level, highlighted: highlight_signatures&.include?(item.signature)) item.children.each do |child| display_item_recursive(child, indent_level + 1, highlight_signatures) end end |
#find_item_by_id(id) ⇒ Object
Finds a todo item by its index across all tags (searches recursively)
167 168 169 170 171 172 173 174 175 |
# File 'lib/taf/models/taf.rb', line 167 def find_item_by_id(id) @taf.each_value do |items| items.each do |item| result = find_in_subtree(item, id) return result if result end end nil end |
#mark_ancestors_todo(item) ⇒ Object
Recursively marks all ancestors as todo and returns those that changed
138 139 140 141 142 143 144 145 146 147 |
# File 'lib/taf/models/taf.rb', line 138 def mark_ancestors_todo(item) changed = [] current = item while current changed << current if current.status != "todo" current.status = "todo" current = current.parent end changed end |
#mark_descendants_done(item) ⇒ Object
Recursively marks all descendants as done and returns those that changed
127 128 129 130 131 132 133 134 135 |
# File 'lib/taf/models/taf.rb', line 127 def mark_descendants_done(item) changed = [] item.children.each do |child| changed << child if child.status != "done" child.status = "done" changed.concat(mark_descendants_done(child)) end changed end |
#purge ⇒ Object
Deletes all done items (and their children) and saves
192 193 194 195 196 197 198 199 200 201 |
# File 'lib/taf/models/taf.rb', line 192 def purge @taf.each_value do |items| items.reject! { |item| item.status == "done" } items.each do |item| purge_done_children(item) end end save end |
#show_all(highlight_signatures: nil) ⇒ Object
Shows all tags and items
92 93 94 95 96 97 98 99 100 |
# File 'lib/taf/models/taf.rb', line 92 def show_all(highlight_signatures: nil) @taf.each do |key, items| @presenter.display_tag(key) items.each do |item| display_item_recursive(item, 0, highlight_signatures) end puts "" end end |
#show_tag(tag, highlight_signatures: nil) ⇒ Object
Shows given tag and its items
79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/taf/models/taf.rb', line 79 def show_tag(tag, highlight_signatures: nil) @taf.each do |key, items| next unless key == tag @presenter.display_tag(key) items.each do |item| display_item_recursive(item, 0, highlight_signatures) end puts "" end end |
#toggle(item) ⇒ Object
Toggles the status of the item Toggles ancestors and descendants accordingly
112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/taf/models/taf.rb', line 112 def toggle(item) item.status = item.status == "done" ? "todo" : "done" affected_items = [item] if item.status == "done" affected_items.concat(mark_descendants_done(item)) elsif item.parent affected_items.concat(mark_ancestors_todo(item.parent)) end save affected_items.map(&:signature) end |