Class: Todo
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
- ATTENTION_REQUESTED =
10
- 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,
ATTENTION_REQUESTED => :attention_requested
}.freeze
- ACTIONS_MULTIPLE_ALLOWED =
[Todo::MENTIONED, Todo::DIRECTLY_ADDRESSED].freeze
ApplicationRecord::MAX_PLUCK
Class Method Summary
collapse
Instance Method Summary
collapse
cached_column_list, #create_or_load_association, declarative_enum, default_select_columns, id_in, id_not_in, iid_in, pluck_primary_key, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order
#serializable_hash
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`.
110
111
112
|
# File 'app/models/todo.rb', line 110
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.
119
120
121
122
123
124
125
126
127
|
# File 'app/models/todo.rb', line 119
def batch_update(**new_attributes)
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
|
.count_grouped_by_user_id_and_state ⇒ Object
Count todos grouped by user_id and state, using an UNION query so we can utilize the partial indexes for each state.
164
165
166
167
168
169
170
171
172
173
174
|
# File 'app/models/todo.rb', line 164
def count_grouped_by_user_id_and_state
grouped_count = select(:user_id, 'count(id) AS count').group(:user_id)
done = grouped_count.where(state: :done).select("'done' AS state")
pending = grouped_count.where(state: :pending).select("'pending' AS state")
union = unscoped.from_union([done, pending], remove_duplicates: false)
connection.select_all(union).each_with_object({}) do |row, counts|
counts[[row['user_id'], row['state']]] = row['count']
end
end
|
.distinct_user_ids ⇒ Object
158
159
160
|
# File 'app/models/todo.rb', line 158
def distinct_user_ids
distinct.pluck(:user_id)
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`.
97
98
99
100
101
102
103
104
|
# File 'app/models/todo.rb', line 97
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_priority ⇒ Object
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”
146
147
148
149
150
151
152
153
154
155
156
|
# File 'app/models/todo.rb', line 146
def order_by_labels_priority
highest_priority = highest_label_priority(
target_type_column: "todos.target_type",
target_column: "todos.target_id",
project_column: "todos.project_id"
).arel.as('highest_priority')
select(arel_table[Arel.star], highest_priority)
.order(Arel.sql('highest_priority').asc.nulls_last)
.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.
132
133
134
135
136
137
138
139
140
141
|
# File 'app/models/todo.rb', line 132
def sort_by_attribute(method)
sorted =
case method.to_s
when 'priority', 'label_priority' then order_by_labels_priority
else order_by(method)
end
sorted.order(id: :desc)
end
|
Instance Method Details
#action_name ⇒ Object
209
210
211
|
# File 'app/models/todo.rb', line 209
def action_name
ACTION_NAMES[action]
end
|
#assigned? ⇒ Boolean
189
190
191
|
# File 'app/models/todo.rb', line 189
def assigned?
action == ASSIGNED
end
|
#attention_requested? ⇒ Boolean
197
198
199
|
# File 'app/models/todo.rb', line 197
def attention_requested?
action == ATTENTION_REQUESTED
end
|
#body ⇒ Object
213
214
215
216
217
218
219
|
# File 'app/models/todo.rb', line 213
def body
if note.present?
note.note
else
target.title
end
end
|
#build_failed? ⇒ Boolean
185
186
187
|
# File 'app/models/todo.rb', line 185
def build_failed?
action == BUILD_FAILED
end
|
#done? ⇒ Boolean
205
206
207
|
# File 'app/models/todo.rb', line 205
def done?
state == 'done'
end
|
#for_alert? ⇒ Boolean
229
230
231
|
# File 'app/models/todo.rb', line 229
def for_alert?
target_type == AlertManagement::Alert.name
end
|
#for_commit? ⇒ Boolean
221
222
223
|
# File 'app/models/todo.rb', line 221
def for_commit?
target_type == "Commit"
end
|
#for_design? ⇒ Boolean
225
226
227
|
# File 'app/models/todo.rb', line 225
def for_design?
target_type == DesignManagement::Design.name
end
|
#merge_train_removed? ⇒ Boolean
201
202
203
|
# File 'app/models/todo.rb', line 201
def merge_train_removed?
action == MERGE_TRAIN_REMOVED
end
|
#resource_parent ⇒ Object
177
178
179
|
# File 'app/models/todo.rb', line 177
def resource_parent
project
end
|
#review_requested? ⇒ Boolean
193
194
195
|
# File 'app/models/todo.rb', line 193
def review_requested?
action == REVIEW_REQUESTED
end
|
#self_added? ⇒ Boolean
250
251
252
|
# File 'app/models/todo.rb', line 250
def self_added?
author == user
end
|
#self_assigned? ⇒ Boolean
254
255
256
|
# File 'app/models/todo.rb', line 254
def self_assigned?
self_added? && (assigned? || review_requested?)
end
|
#target ⇒ Object
override to return commits, which are not active record
234
235
236
237
238
239
240
|
# File 'app/models/todo.rb', line 234
def target
if for_commit?
project.commit(commit_id) rescue nil
else
super
end
end
|
#target_reference ⇒ Object
242
243
244
245
246
247
248
|
# File 'app/models/todo.rb', line 242
def target_reference
if for_commit?
target.reference_link_text
else
target.to_reference
end
end
|
#unmergeable? ⇒ Boolean
181
182
183
|
# File 'app/models/todo.rb', line 181
def unmergeable?
action == UNMERGEABLE
end
|