Class: Todo

Inherits:
ApplicationRecord show all
Includes:
FromUnion, Sortable
Defined in:
app/models/todo.rb

Constant Summary collapse

WAIT_FOR_DELETE =

Time to wait for todos being removed when not visible for user anymore. Prevents TODOs being removed by mistake, for example, removing access from a user and giving it back again.

1.hour
ASSIGNED =
1
MENTIONED =
2
BUILD_FAILED =
3
MARKED =
4
APPROVAL_REQUIRED =

This is an EE-only feature

5
UNMERGEABLE =
6
DIRECTLY_ADDRESSED =
7
MERGE_TRAIN_REMOVED =

This is an EE-only feature

8
REVIEW_REQUESTED =
9
ACTION_NAMES =
{
  ASSIGNED => :assigned,
  REVIEW_REQUESTED => :review_requested,
  MENTIONED => :mentioned,
  BUILD_FAILED => :build_failed,
  MARKED => :marked,
  APPROVAL_REQUIRED => :approval_required,
  UNMERGEABLE => :unmergeable,
  DIRECTLY_ADDRESSED => :directly_addressed,
  MERGE_TRAIN_REMOVED => :merge_train_removed
}.freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ApplicationRecord

at_most, id_in, id_not_in, iid_in, pluck_primary_key, primary_key_in, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, underscore, without_order

Class Method Details

.any_for_target?(target, state = nil) ⇒ Boolean

Returns `true` if the current user has any todos for the given target with the optional given state.

target - The value of the `target_type` column, such as `Issue`. state - The value of the `state` column, such as `pending` or `done`.

Returns:

  • (Boolean)

105
106
107
# File 'app/models/todo.rb', line 105

def any_for_target?(target, state = nil)
  state.nil? ? exists?(target: target) : exists?(target: target, state: state)
end

.batch_update(**new_attributes) ⇒ Object

Updates attributes of a relation of todos to the new state.

new_attributes - The new attributes of the todos.

Returns an `Array` containing the IDs of the updated todos.


114
115
116
117
118
119
120
121
122
# File 'app/models/todo.rb', line 114

def batch_update(**new_attributes)
  # Only update those that have different state
  base = where.not(state: new_attributes[:state]).except(:order)
  ids = base.pluck(:id)

  base.update_all(new_attributes.merge(updated_at: Time.current))

  ids
end

.for_group_ids_and_descendants(group_ids) ⇒ Object

Returns all todos for the given group ids and their descendants.

group_ids - Group Ids to retrieve todos for.

Returns an `ActiveRecord::Relation`.


92
93
94
95
96
97
98
99
# File 'app/models/todo.rb', line 92

def for_group_ids_and_descendants(group_ids)
  groups = Group.groups_including_descendants_by(group_ids)

  from_union([
    for_project(Project.for_group(groups)),
    for_group(groups)
  ])
end

.order_by_labels_priorityObject

Order by priority depending on which issue/merge request the Todo belongs to Todos with highest priority first then oldest todos Need to order by created_at last because of differences on Mysql and Postgres when joining by type “Merge_request/Issue”


141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'app/models/todo.rb', line 141

def order_by_labels_priority
  params = {
    target_type_column: "todos.target_type",
    target_column: "todos.target_id",
    project_column: "todos.project_id"
  }

  highest_priority = highest_label_priority(params).to_sql

  select("#{table_name}.*, (#{highest_priority}) AS highest_priority")
    .order(Gitlab::Database.nulls_last_order('highest_priority', 'ASC'))
    .order('todos.created_at')
end

.sort_by_attribute(method) ⇒ Object

Priority sorting isn't displayed in the dropdown, because we don't show milestones, but still show something if the user has a URL with that selected.


127
128
129
130
131
132
133
134
135
136
# File 'app/models/todo.rb', line 127

def sort_by_attribute(method)
  sorted =
    case method.to_s
    when 'priority', 'label_priority' then order_by_labels_priority
    else order_by(method)
    end

  # Break ties with the ID column for pagination
  sorted.order(id: :desc)
end

Instance Method Details

#action_nameObject


184
185
186
# File 'app/models/todo.rb', line 184

def action_name
  ACTION_NAMES[action]
end

#assigned?Boolean

Returns:

  • (Boolean)

168
169
170
# File 'app/models/todo.rb', line 168

def assigned?
  action == ASSIGNED
end

#bodyObject


188
189
190
191
192
193
194
# File 'app/models/todo.rb', line 188

def body
  if note.present?
    note.note
  else
    target.title
  end
end

#build_failed?Boolean

Returns:

  • (Boolean)

164
165
166
# File 'app/models/todo.rb', line 164

def build_failed?
  action == BUILD_FAILED
end

#done?Boolean

Returns:

  • (Boolean)

180
181
182
# File 'app/models/todo.rb', line 180

def done?
  state == 'done'
end

#for_alert?Boolean

Returns:

  • (Boolean)

204
205
206
# File 'app/models/todo.rb', line 204

def for_alert?
  target_type == AlertManagement::Alert.name
end

#for_commit?Boolean

Returns:

  • (Boolean)

196
197
198
# File 'app/models/todo.rb', line 196

def for_commit?
  target_type == "Commit"
end

#for_design?Boolean

Returns:

  • (Boolean)

200
201
202
# File 'app/models/todo.rb', line 200

def for_design?
  target_type == DesignManagement::Design.name
end

#merge_train_removed?Boolean

Returns:

  • (Boolean)

176
177
178
# File 'app/models/todo.rb', line 176

def merge_train_removed?
  action == MERGE_TRAIN_REMOVED
end

#resource_parentObject


156
157
158
# File 'app/models/todo.rb', line 156

def resource_parent
  project
end

#review_requested?Boolean

Returns:

  • (Boolean)

172
173
174
# File 'app/models/todo.rb', line 172

def review_requested?
  action == REVIEW_REQUESTED
end

#self_added?Boolean

Returns:

  • (Boolean)

225
226
227
# File 'app/models/todo.rb', line 225

def self_added?
  author == user
end

#self_assigned?Boolean

Returns:

  • (Boolean)

229
230
231
# File 'app/models/todo.rb', line 229

def self_assigned?
  assigned? && self_added?
end

#targetObject

override to return commits, which are not active record


209
210
211
212
213
214
215
# File 'app/models/todo.rb', line 209

def target
  if for_commit?
    project.commit(commit_id) rescue nil
  else
    super
  end
end

#target_referenceObject


217
218
219
220
221
222
223
# File 'app/models/todo.rb', line 217

def target_reference
  if for_commit?
    target.reference_link_text
  else
    target.to_reference
  end
end

#unmergeable?Boolean

Returns:

  • (Boolean)

160
161
162
# File 'app/models/todo.rb', line 160

def unmergeable?
  action == UNMERGEABLE
end