Class: WorkItem
- Inherits:
-
Issue
- Object
- ActiveRecord::Base
- ApplicationRecord
- Issue
- WorkItem
- Includes:
- Gitlab::InternalEventsTracking, Gitlab::Utils::StrongMemoize, Import::HasImportSource
- Defined in:
- app/models/work_item.rb
Constant Summary collapse
- COMMON_QUICK_ACTIONS_COMMANDS =
[ :title, :reopen, :close, :tableflip, :shrug, :type, :promote_to, :checkin_reminder, :subscribe, :unsubscribe, :confidential, :award, :react, :move, :clone, :copy_metadata, :duplicate, :promote_to_incident, :board_move, :convert_to_ticket, :zoom, :remove_zoom ].freeze
Constants included from Import::HasImportSource
Import::HasImportSource::IMPORT_SOURCES
Constants inherited from Issue
Issue::AnyDueDate, Issue::DEFAULT_ISSUE_TYPE, Issue::DueDateStruct, Issue::DueNextMonthAndPreviousTwoWeeks, Issue::DueThisMonth, Issue::DueThisWeek, Issue::DueToday, Issue::DueTomorrow, Issue::IssueTypeOutOfSyncError, Issue::MAX_BRANCH_TEMPLATE, Issue::NoDueDate, Issue::Overdue, Issue::SORTING_PREFERENCE_FIELD, Issue::TYPES_FOR_BOARD_LIST, Issue::TYPES_FOR_LIST
Constants included from PgFullTextSearchable
PgFullTextSearchable::LONG_WORDS_REGEX, PgFullTextSearchable::TEXT_SEARCH_DICTIONARY, PgFullTextSearchable::TSVECTOR_MAX_LENGTH, PgFullTextSearchable::VERY_LONG_WORDS_WITH_AT_REGEX, PgFullTextSearchable::XML_TAG_REGEX
Constants included from ThrottledTouch
ThrottledTouch::TOUCH_INTERVAL
Constants included from Gitlab::RelativePositioning
Gitlab::RelativePositioning::IDEAL_DISTANCE, Gitlab::RelativePositioning::IllegalRange, Gitlab::RelativePositioning::InvalidPosition, Gitlab::RelativePositioning::IssuePositioningDisabled, Gitlab::RelativePositioning::MAX_GAP, Gitlab::RelativePositioning::MAX_POSITION, Gitlab::RelativePositioning::MIN_GAP, Gitlab::RelativePositioning::MIN_POSITION, Gitlab::RelativePositioning::NoSpaceLeft, Gitlab::RelativePositioning::START_POSITION, Gitlab::RelativePositioning::STEPS
Constants included from Noteable
Constants included from Issuable
Issuable::DESCRIPTION_LENGTH_MAX, Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS, Issuable::SEARCHABLE_FIELDS, Issuable::STATE_ID_MAP, Issuable::TITLE_LENGTH_MAX
Constants included from Taskable
Taskable::COMPLETED, Taskable::COMPLETE_PATTERN, Taskable::INCOMPLETE, Taskable::INCOMPLETE_PATTERN, Taskable::ITEM_PATTERN
Constants included from CacheMarkdownField
CacheMarkdownField::INVALIDATED_BY
Constants included from Redactable
Redactable::UNSUBSCRIBE_PATTERN
Constants included from Gitlab::SQL::Pattern
Gitlab::SQL::Pattern::MIN_CHARS_FOR_PARTIAL_MATCHING, Gitlab::SQL::Pattern::REGEX_QUOTED_TERM
Constants included from AtomicInternalId
AtomicInternalId::MissingValueError
Constants inherited from ApplicationRecord
Constants included from HasCheckConstraints
HasCheckConstraints::NOT_NULL_CHECK_PATTERN
Constants included from ResetOnColumnErrors
ResetOnColumnErrors::MAX_RESET_PERIOD
Instance Attribute Summary
Attributes included from Noteable
Attributes included from Transitionable
Attributes included from Importable
#importing, #user_contributions
Attributes included from CacheMarkdownField
#skip_markdown_cache_validation
Class Method Summary collapse
- .alternative_reference_prefix_with_postfix ⇒ Object
- .assignee_association_name ⇒ Object
- .find_by_namespace_and_iid!(namespace, iid) ⇒ Object
- .find_on_namespaces(ids:, resource_parent:) ⇒ Object
- .link_reference_pattern ⇒ Object
- .linked_items_for(target_ids, preload: nil, link_type: nil) ⇒ Object
- .linked_items_keyset_order ⇒ Object
- .namespace_reference_pattern ⇒ Object
- .non_widgets ⇒ Object
- .ordered_linked_items(select_query, ids: [], link_type: nil, preload: nil) ⇒ Object
- .reference_pattern ⇒ Object
- .related_link_class ⇒ Object
- .sync_callback_class(association_name) ⇒ Object
- .test_reports_join_column ⇒ Object
- .work_item_children_keyset_order(_work_item) ⇒ Object
- .work_item_children_keyset_order_config ⇒ Object
Instance Method Summary collapse
- #ancestors ⇒ Object
- #create_dates_source_from_current_dates ⇒ Object
- #custom_notification_target_name ⇒ Object
- #date_source_attributes_from_current_dates ⇒ Object
- #descendants ⇒ Object
- #due_date ⇒ Object
-
#get_widget(type) ⇒ Object
Returns widget object if available type parameter can be a symbol, for example,
:description. - #linked_items_count ⇒ Object
- #linked_work_items(current_user = nil, authorize: true, preload: nil, link_type: nil) ⇒ Object
- #max_depth_reached?(child_type) ⇒ Boolean
- #noteable_target_type_name ⇒ Object
- #same_type_base_and_ancestors ⇒ Object
- #same_type_descendants_depth ⇒ Object
- #start_date ⇒ Object
- #supported_quick_action_commands ⇒ Object
- #supports_parent? ⇒ Boolean
- #supports_time_tracking? ⇒ Boolean
-
#todoable_target_type_name ⇒ Object
Todo: remove method after target_type cleanup See gitlab.com/gitlab-org/gitlab/-/issues/416009.
-
#transform_quick_action_params(command_params) ⇒ Object
Widgets have a set of quick action params that they must process.
- #widget_definitions ⇒ Object
- #widgets(except_types: [], only_types: nil) ⇒ Object
Methods included from Import::HasImportSource
Methods included from Gitlab::InternalEventsTracking
Methods inherited from Issue
#==, #allow_possible_spam?, alternative_reference_prefix_without_postfix, #as_json, #autoclose_by_merged_closing_merge_request?, #banzai_render_context, #blocked_for_repositioning?, #can_be_worked_on?, #can_move?, #check_repositioning_allowed!, #clear_closure_reason_references, column_order_id_asc, column_order_relative_position, #design_collection, #discussions_rendered_on_frontend?, #duplicated?, #email_participants_emails, #email_participants_emails_downcase, #ensure_work_item_description, #epic_work_item?, #expire_etag_cache, #from_service_desk?, full_search, #gfm_reference, #group_epic_work_item?, #group_level?, #has_widget?, #hidden?, #hook_attrs, in_namespaces_with_cte, #invalidate_project_counter_caches, #issue_assignee_user_ids, #issue_link_type, #issue_type, #issuing_parent_id, #merge_requests_count, #moved?, #next_object_by_relative_position, order_by_relative_position, order_upvotes_asc, order_upvotes_desc, participant_includes, #previous_updated_at, project_foreign_key, #real_time_notes_enabled?, reference_postfix, reference_prefix, reference_valid?, #related_issues, relative_positioning_parent_column, #relative_positioning_parent_projects, relative_positioning_query_base, #relocation_target, #require_legacy_views?, #resource_parent, #show_as_work_item?, simple_sorts, #skip_metrics?, sort_by_attribute, #source_project, #suggested_branch_name, supported_keyset_orderings, #supports_assignee?, #supports_confidentiality?, #supports_move_and_clone?, #supports_recaptcha?, #to_branch_name, to_branch_name, #to_reference, #to_work_item_global_id, #update_upvotes_count, #use_work_item_url?, with_accessible_sub_namespace_ids_cte, #work_item_type_with_default
Methods included from Gitlab::Utils::Override
#extended, extensions, #included, #method_added, #override, #prepended, #queue_verification, verify!
Methods included from PgFullTextSearchable
Methods included from IssueAvailableFeatures
Methods included from Presentable
Methods included from ThrottledTouch
Methods included from TimeTrackable
#clear_memoized_total_time_spent, #human_time_change, #human_time_estimate, #human_total_time_spent, #reload, #reset, #set_time_estimate_default_value, #spend_time, #time_change, #time_estimate, #time_estimate=, #total_time_spent
Methods included from RelativePositioning
#check_repositioning_allowed!, #could_not_move, #exclude_self, #model_class, #move_after, #move_before, #move_between, #move_to_end, #move_to_start, mover, #next_object_by_relative_position, #relative_positioning_scoped_items, #reset_relative_position, #update_relative_siblings
Methods included from Gitlab::RelativePositioning
Methods included from FasterCacheKeys
Methods included from Spammable
#allow_possible_spam?, #check_for_spam, #check_for_spam?, #clear_spam_flags!, #invalidate_if_spam, #needs_recaptcha!, #recaptcha_error!, #render_recaptcha?, #spam, #spam!, #spam_description, #spam_title, #spammable_attribute_changed?, #spammable_entity_type, #spammable_text, #submittable_as_spam?, #submittable_as_spam_by?, #supports_recaptcha?, #unrecoverable_spam_error!
Methods included from Referable
#referable_inspect, #reference_link_text, #to_reference, #to_reference_base
Methods included from Noteable
#after_note_created, #after_note_destroyed, #base_class_name, #broadcast_notes_changed, #capped_notes_count, #commenters, #creatable_note_email_address, #discussion_ids_relation, #discussion_notes, #discussion_root_note_ids, #discussions, #discussions_can_be_resolved_by?, #discussions_rendered_on_frontend?, #discussions_resolvable?, #discussions_resolved?, #discussions_to_be_resolved, #grouped_diff_discussions, #has_any_diff_note_positions?, #human_class_name, #lockable?, #preloads_discussion_diff_highlighting?, #real_time_notes_enabled?, #resolvable_discussions, #supports_creating_notes_by_email?, #supports_discussions?, #supports_replying_to_individual_notes?, #supports_resolvable_notes?, #supports_suggestion?
Methods included from Issuable
#allows_scoped_labels?, #assignee?, #assignee_list, #assignee_or_author?, #assignee_username_list, #can_move?, #card_attributes, #draftless_title_changed, #first_contribution?, #hook_association_changes, #hook_reviewer_changes, #label_names, #labels_array, #labels_hook_attrs, #notes_for_participants, #notes_with_associations, #old_assignees, #old_escalation_status, #old_labels, #old_severity, #old_target_branch, #old_time_change, #old_total_time_spent, #open?, #overdue?, #read_ability_for, #resource_parent, #reviewers_hook_attrs, #state, #state=, #subscribed_without_subscriptions?, #supports_health_status?, #to_ability_name, #to_hook_data, #updated_tasks, #user_notes_count
Methods included from ReportableChanges
#as_json, #changes_applied, #clear_changes_information, #reload, #reportable_changes
Methods included from Exportable
#exportable_association?, #restricted_associations, #to_authorized_json
Methods included from AfterCommitQueue
#run_after_commit, #run_after_commit_or_now
Methods included from Editable
Methods included from Transitionable
#disable_transitioning, #enable_transitioning, #transitioning?
Methods included from Taskable
#complete_task_list_item_count, get_tasks, get_updated_tasks, #task_completion_status, #task_list_items, #task_status, #task_status_short, #tasks?
Methods included from Awardable
#awarded_emoji?, #downvotes, #emoji_awardable?, #grouped_awards, #upvotes, #user_authored?, #user_can_award?
Methods included from StripAttribute
Methods included from Subscribable
#lazy_subscription, #set_subscription, #subscribe, #subscribed?, #subscribed_without_subscriptions?, #subscribers, #toggle_subscription, #unsubscribe
Methods included from Milestoneable
#milestone_available?, #supports_milestone?
Methods included from Mentionable
#all_references, #create_cross_references!, #create_new_cross_references!, #directly_addressed_users, #extractors, #gfm_reference, #local_reference, #matches_cross_reference_regex?, #mentioned_users, #referenced_group_users, #referenced_groups, #referenced_mentionables, #referenced_projects, #referenced_users, #user_mention_class, #user_mention_identifier
Methods included from Participable
#participant?, #participants, #visible_participants
Methods included from CacheMarkdownField
#attribute_invalidated?, #banzai_render_context, #cached_html_for, #cached_html_up_to_date?, #can_cache_field?, #invalidated_markdown_cache?, #latest_cached_markdown_version, #mentionable_attributes_changed?, #mentioned_filtered_user_ids_for, #parent_user, #refresh_markdown_cache, #refresh_markdown_cache!, #rendered_field_content, #skip_project_check?, #store_mentions!, #store_mentions?, #store_mentions_after_commit?, #updated_cached_html_for
Methods included from Gitlab::SQL::Pattern
Methods included from IidRoutes
Methods included from AtomicInternalId
group_init, #internal_id_read_scope, #internal_id_scope_attrs, #internal_id_scope_usage, namespace_init, project_init, scope_attrs, scope_usage
Methods inherited from ApplicationRecord
===, cached_column_list, #create_or_load_association, current_transaction, declarative_enum, default_select_columns, delete_all_returning, #deleted_from_database?, id_in, id_not_in, iid_in, nullable_column?, 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
Methods included from Organizations::Sharding
Methods included from ResetOnColumnErrors
#reset_on_union_error, #reset_on_unknown_attribute_error
Methods included from Gitlab::SensitiveSerializableHash
Class Method Details
.alternative_reference_prefix_with_postfix ⇒ Object
127 128 129 |
# File 'app/models/work_item.rb', line 127 def alternative_reference_prefix_with_postfix '[work_item:' end |
.assignee_association_name ⇒ Object
112 113 114 |
# File 'app/models/work_item.rb', line 112 def assignee_association_name 'issue' end |
.find_by_namespace_and_iid!(namespace, iid) ⇒ Object
108 109 110 |
# File 'app/models/work_item.rb', line 108 def find_by_namespace_and_iid!(namespace, iid) find_by!(namespace: namespace, iid: iid) end |
.find_on_namespaces(ids:, resource_parent:) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'app/models/work_item.rb', line 249 def find_on_namespaces(ids:, resource_parent:) return none if resource_parent.nil? group_namespaces = resource_parent.self_and_descendants.select(:id) if resource_parent.is_a?(Group) project_namespaces = if resource_parent.is_a?(Project) Project.id_in(resource_parent) else resource_parent.all_projects end.select('projects.project_namespace_id as id') namespaces = Namespace.from_union( [group_namespaces, project_namespaces].compact, remove_duplicates: false ) Gitlab::SQL::CTE.new(:work_item_ids_cte, id_in(ids)) .apply_to(all) .in_namespaces_with_cte(namespaces) .includes(:work_item_type) end |
.link_reference_pattern ⇒ Object
153 154 155 156 157 158 159 |
# File 'app/models/work_item.rb', line 153 def link_reference_pattern @link_reference_pattern ||= project_or_group_link_reference_pattern( 'work_items', namespace_reference_pattern, Gitlab::Regex.work_item ) end |
.linked_items_for(target_ids, preload: nil, link_type: nil) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'app/models/work_item.rb', line 202 def linked_items_for(target_ids, preload: nil, link_type: nil) select_query = select('issues.*, issue_links.id AS issue_link_id, issue_links.link_type AS issue_link_type_value, issue_links.target_id AS issue_link_source_id, issue_links.source_id AS issue_link_target_id, issue_links.created_at AS issue_link_created_at, issue_links.updated_at AS issue_link_updated_at') ordered_linked_items(select_query, ids: target_ids, link_type: link_type, preload: preload) end |
.linked_items_keyset_order ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 |
# File 'app/models/work_item.rb', line 190 def linked_items_keyset_order ::Gitlab::Pagination::Keyset::Order.build( [ ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new( attribute_name: 'issue_link_id', column_expression: IssueLink.arel_table[:id], order_expression: IssueLink.arel_table[:id].desc, nullable: :not_nullable ) ]) end |
.namespace_reference_pattern ⇒ Object
120 121 122 123 124 125 |
# File 'app/models/work_item.rb', line 120 def namespace_reference_pattern %r{ (?<!#{Gitlab::PathRegex::PATH_START_CHAR}) ((?<group_or_project_namespace>#{Gitlab::PathRegex::FULL_NAMESPACE_FORMAT_REGEX})) }xo end |
.non_widgets ⇒ Object
226 227 228 |
# File 'app/models/work_item.rb', line 226 def [:pending_escalations] end |
.ordered_linked_items(select_query, ids: [], link_type: nil, preload: nil) ⇒ Object
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'app/models/work_item.rb', line 230 def ordered_linked_items(select_query, ids: [], link_type: nil, preload: nil) type_condition = if link_type == WorkItems::RelatedWorkItemLink::TYPE_RELATES_TO " AND issue_links.link_type = #{WorkItems::RelatedWorkItemLink.link_types[link_type]}" else "" end query_ids = sanitize_sql_array(['?', Array.wrap(ids)]) select_query .joins("INNER JOIN issue_links ON (issue_links.source_id = issues.id AND issue_links.target_id IN (#{query_ids})#{type_condition}) OR (issue_links.target_id = issues.id AND issue_links.source_id IN (#{query_ids})#{type_condition})") .preload(preload) .reorder(linked_items_keyset_order) end |
.reference_pattern ⇒ Object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'app/models/work_item.rb', line 131 def reference_pattern prefix_with_postfix = alternative_reference_prefix_with_postfix if prefix_with_postfix.empty? @reference_pattern ||= %r{ (?: (#{namespace_reference_pattern})?#{Regexp.escape(reference_prefix)} | #{Regexp.escape(alternative_reference_prefix_without_postfix)} )#{Gitlab::Regex.work_item} }x else %r{ ((?: (#{namespace_reference_pattern})?#{Regexp.escape(reference_prefix)} | #{alternative_reference_prefix_without_postfix} )#{Gitlab::Regex.work_item}) | ((?: #{Regexp.escape(prefix_with_postfix)}(#{namespace_reference_pattern}/)? )#{Gitlab::Regex.work_item(reference_postfix)}) }x end end |
.related_link_class ⇒ Object
216 217 218 |
# File 'app/models/work_item.rb', line 216 def WorkItems::RelatedWorkItemLink end |
.sync_callback_class(association_name) ⇒ Object
220 221 222 223 224 |
# File 'app/models/work_item.rb', line 220 def sync_callback_class(association_name) ::WorkItems::DataSync::NonWidgets.const_get(association_name.to_s.camelcase, false) rescue NameError nil end |
.test_reports_join_column ⇒ Object
116 117 118 |
# File 'app/models/work_item.rb', line 116 def test_reports_join_column 'issues.id' end |
.work_item_children_keyset_order(_work_item) ⇒ Object
184 185 186 187 188 |
# File 'app/models/work_item.rb', line 184 def work_item_children_keyset_order(_work_item) keyset_order = work_item_children_keyset_order_config keyset_order.apply_cursor_conditions(joins(:parent_link)).reorder(keyset_order) end |
.work_item_children_keyset_order_config ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'app/models/work_item.rb', line 161 def work_item_children_keyset_order_config Gitlab::Pagination::Keyset::Order.build( [ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new( attribute_name: 'state_id', column_expression: WorkItem.arel_table[:state_id], order_expression: WorkItem.arel_table[:state_id].asc ), Gitlab::Pagination::Keyset::ColumnOrderDefinition.new( attribute_name: 'parent_link_relative_position', column_expression: WorkItems::ParentLink.arel_table[:relative_position], order_expression: WorkItems::ParentLink.arel_table[:relative_position].asc.nulls_last, add_to_projections: true, nullable: :nulls_last ), Gitlab::Pagination::Keyset::ColumnOrderDefinition.new( attribute_name: 'work_item_id', order_expression: WorkItems::ParentLink.arel_table['work_item_id'].asc ) ] ) end |
Instance Method Details
#ancestors ⇒ Object
338 339 340 |
# File 'app/models/work_item.rb', line 338 def ancestors hierarchy.ancestors(hierarchy_order: :asc) end |
#create_dates_source_from_current_dates ⇒ Object
273 274 275 |
# File 'app/models/work_item.rb', line 273 def create_dates_source_from_current_dates create_dates_source(date_source_attributes_from_current_dates) end |
#custom_notification_target_name ⇒ Object
292 293 294 295 296 297 |
# File 'app/models/work_item.rb', line 292 def custom_notification_target_name # Also use `work_item` for issues. # Custom work_item notifications are mapped back to the issue category # until we properly transitioned the categories to work items. 'work_item' end |
#date_source_attributes_from_current_dates ⇒ Object
277 278 279 280 281 282 283 284 285 286 |
# File 'app/models/work_item.rb', line 277 def date_source_attributes_from_current_dates { due_date: due_date, start_date: start_date, start_date_is_fixed: due_date.present? || start_date.present?, due_date_is_fixed: due_date.present? || start_date.present?, start_date_fixed: start_date, due_date_fixed: due_date } end |
#descendants ⇒ Object
342 343 344 |
# File 'app/models/work_item.rb', line 342 def descendants hierarchy.descendants end |
#due_date ⇒ Object
412 413 414 |
# File 'app/models/work_item.rb', line 412 def due_date dates_source&.due_date || read_attribute(:due_date) end |
#get_widget(type) ⇒ Object
Returns widget object if available type parameter can be a symbol, for example, :description.
322 323 324 325 326 327 328 |
# File 'app/models/work_item.rb', line 322 def (type) strong_memoize_with(type) do break unless .key?(type.to_sym) [type].(self) end end |
#linked_items_count ⇒ Object
398 399 400 |
# File 'app/models/work_item.rb', line 398 def linked_items_count linked_work_items(authorize: false).size end |
#linked_work_items(current_user = nil, authorize: true, preload: nil, link_type: nil) ⇒ Object
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 |
# File 'app/models/work_item.rb', line 382 def linked_work_items(current_user = nil, authorize: true, preload: nil, link_type: nil) return [] if new_record? linked_items = self.class.ordered_linked_items(linked_issues_select, ids: id, link_type: link_type, preload: preload) return linked_items unless cross_project_filter = ->(work_items) { work_items.where(project: project) } Ability.work_items_readable_by_user( linked_items, current_user, filters: { read_cross_project: cross_project_filter } ) end |
#max_depth_reached?(child_type) ⇒ Boolean
420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'app/models/work_item.rb', line 420 def max_depth_reached?(child_type) restriction = ::WorkItems::TypesFramework::SystemDefined::HierarchyRestriction.find_by( parent_type_id: work_item_type_id, child_type_id: child_type.id ) return false unless restriction&.maximum_depth if work_item_type_id == child_type.id same_type_base_and_ancestors.count >= restriction.maximum_depth else hierarchy(different_type_id: child_type.id).base_and_ancestors.count >= restriction.maximum_depth end end |
#noteable_target_type_name ⇒ Object
288 289 290 |
# File 'app/models/work_item.rb', line 288 def noteable_target_type_name 'issue' end |
#same_type_base_and_ancestors ⇒ Object
346 347 348 |
# File 'app/models/work_item.rb', line 346 def same_type_base_and_ancestors hierarchy(same_type: true).base_and_ancestors(hierarchy_order: :asc) end |
#same_type_descendants_depth ⇒ Object
350 351 352 |
# File 'app/models/work_item.rb', line 350 def same_type_descendants_depth hierarchy(same_type: true).max_descendants_depth.to_i end |
#start_date ⇒ Object
416 417 418 |
# File 'app/models/work_item.rb', line 416 def start_date dates_source&.start_date || read_attribute(:start_date) end |
#supported_quick_action_commands ⇒ Object
354 355 356 357 358 |
# File 'app/models/work_item.rb', line 354 def supported_quick_action_commands = work_item_type.(resource_parent).flat_map(&:quick_action_commands).uniq COMMON_QUICK_ACTIONS_COMMANDS + end |
#supports_parent? ⇒ Boolean
406 407 408 409 410 |
# File 'app/models/work_item.rb', line 406 def supports_parent? return false if work_item_type.issue? hierarchy_supports_parent? end |
#supports_time_tracking? ⇒ Boolean
402 403 404 |
# File 'app/models/work_item.rb', line 402 def supports_time_tracking? work_item_type.supports_time_tracking?(resource_parent) end |
#todoable_target_type_name ⇒ Object
Todo: remove method after target_type cleanup See gitlab.com/gitlab-org/gitlab/-/issues/416009
301 302 303 |
# File 'app/models/work_item.rb', line 301 def todoable_target_type_name %w[Issue WorkItem] end |
#transform_quick_action_params(command_params) ⇒ Object
Widgets have a set of quick action params that they must process. Map them to widget_params so they can be picked up by widget services.
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'app/models/work_item.rb', line 362 def transform_quick_action_params(command_params) common_params = command_params.dup = {} work_item_type.(resource_parent) .filter { || .respond_to?(:quick_action_params) } .each do || .quick_action_params .filter { |param_name| common_params.key?(param_name) } .each do |param_name| [.api_symbol] ||= {} param_value = common_params.delete(param_name) [.api_symbol].merge!(.process_quick_action_param(param_name, param_value)) end end { common: common_params, widgets: } end |
#widget_definitions ⇒ Object
330 331 332 333 334 335 |
# File 'app/models/work_item.rb', line 330 def work_item_type .(resource_parent) .index_by(&:widget_type) .symbolize_keys end |
#widgets(except_types: [], only_types: nil) ⇒ Object
305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'app/models/work_item.rb', line 305 def (except_types: [], only_types: nil) raise ArgumentError, 'Only one filter is allowed' if only_types.present? && except_types.present? strong_memoize_with(:widgets, only_types, except_types) do except_types = Array.wrap(except_types) .keys.filter_map do |type| next if except_types.include?(type) next if only_types&.exclude?(type) (type) end end end |