Class: WorkItems::Type
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- WorkItems::Type
- Includes:
- CacheMarkdownField, Gitlab::Utils::StrongMemoize, ReactiveCaching
- Defined in:
- app/models/work_items/type.rb
Constant Summary collapse
- DEFAULT_TYPES_NOT_SEEDED =
Class.new(StandardError)
- TYPE_NAMES =
type name is used in restrictions DB seeder to assure restrictions for default types are pre-filled
{ issue: 'Issue', incident: 'Incident', test_case: 'Test Case', requirement: 'Requirement', task: 'Task', objective: 'Objective', key_result: 'Key Result', epic: 'Epic', ticket: 'Ticket' }.freeze
- BASE_TYPES =
Base types need to exist on the DB on app startup This constant is used by the DB seeder TODO - where to add new icon names created?
{ issue: { name: TYPE_NAMES[:issue], icon_name: 'issue-type-issue', enum_value: 0, id: 1 }, incident: { name: TYPE_NAMES[:incident], icon_name: 'issue-type-incident', enum_value: 1, id: 2 }, test_case: { name: TYPE_NAMES[:test_case], icon_name: 'issue-type-test-case', enum_value: 2, id: 3 }, ## EE-only requirement: { name: TYPE_NAMES[:requirement], icon_name: 'issue-type-requirements', enum_value: 3, id: 4 }, ## EE task: { name: TYPE_NAMES[:task], icon_name: 'issue-type-task', enum_value: 4, id: 5 }, objective: { name: TYPE_NAMES[:objective], icon_name: 'issue-type-objective', enum_value: 5, id: 6 }, ## EE-only key_result: { name: TYPE_NAMES[:key_result], icon_name: 'issue-type-keyresult', enum_value: 6, id: 7 }, ## EE-only epic: { name: TYPE_NAMES[:epic], icon_name: 'issue-type-epic', enum_value: 7, id: 8 }, ## EE-only ticket: { name: TYPE_NAMES[:ticket], icon_name: 'issue-type-issue', enum_value: 8, id: 9 } }.freeze
- CHANGEABLE_BASE_TYPES =
A list of types user can change between - both original and new type must be included in this list. This is needed for legacy issues where it’s possible to switch between issue and incident.
%w[issue incident test_case].freeze
- EE_BASE_TYPES =
%w[objective epic key_result requirement].freeze
Constants included from ReactiveCaching
ReactiveCaching::ExceededReactiveCacheLimit, ReactiveCaching::InvalidateReactiveCache, ReactiveCaching::WORK_TYPE
Constants included from CacheMarkdownField
CacheMarkdownField::INVALIDATED_BY
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 CacheMarkdownField
#skip_markdown_cache_validation
Class Method Summary collapse
-
.allowed_group_level_types(resource_parent) ⇒ Object
method overridden in EE to perform the corresponding checks for the Epic type.
- .allowed_types_for_issues ⇒ Object
- .default_by_type(type) ⇒ Object
- .default_issue_type ⇒ Object
Instance Method Summary collapse
- #allowed_child_types(cache: false, authorize: false, resource_parent: nil) ⇒ Object
- #allowed_parent_types(cache: false, authorize: false, resource_parent: nil) ⇒ Object
- #calculate_reactive_cache ⇒ Object
- #default_issue? ⇒ Boolean
- #descendant_types ⇒ Object
- #supported_conversion_types(resource_parent, user) ⇒ Object
- #supports_assignee?(resource_parent) ⇒ Boolean
- #supports_time_tracking?(resource_parent) ⇒ Boolean
- #widget_classes(resource_parent) ⇒ Object
-
#widgets(_resource_parent) ⇒ Object
resource_parent is used in EE.
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_after_commit?, #updated_cached_html_for
Methods inherited from ApplicationRecord
===, cached_column_list, #create_or_load_association, declarative_enum, default_select_columns, id_in, id_not_in, iid_in, nullable_column?, 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
Methods included from ResetOnColumnErrors
#reset_on_union_error, #reset_on_unknown_attribute_error
Methods included from Gitlab::SensitiveSerializableHash
Class Method Details
.allowed_group_level_types(resource_parent) ⇒ Object
method overridden in EE to perform the corresponding checks for the Epic type
119 120 121 122 123 124 125 |
# File 'app/models/work_items/type.rb', line 119 def self.allowed_group_level_types(resource_parent) if Feature.enabled?(:create_group_level_work_items, resource_parent, type: :wip) base_types.keys.excluding('epic') else [] end end |
.allowed_types_for_issues ⇒ Object
114 115 116 |
# File 'app/models/work_items/type.rb', line 114 def self.allowed_types_for_issues base_types.keys.excluding('objective', 'key_result', 'epic') end |
.default_by_type(type) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'app/models/work_items/type.rb', line 94 def self.default_by_type(type) found_type = find_by(base_type: type) return found_type if found_type || !WorkItems::Type.base_types.key?(type.to_s) = <<~STRING Default work item types have not been created yet. Make sure the DB has been seeded successfully. See related documentation in https://docs.gitlab.com/omnibus/settings/database.html#seed-the-database-fresh-installs-only If you have additional questions, you can ask in https://gitlab.com/gitlab-org/gitlab/-/issues/423483 STRING raise DEFAULT_TYPES_NOT_SEEDED, end |
.default_issue_type ⇒ Object
110 111 112 |
# File 'app/models/work_items/type.rb', line 110 def self.default_issue_type default_by_type(:issue) end |
Instance Method Details
#allowed_child_types(cache: false, authorize: false, resource_parent: nil) ⇒ Object
160 161 162 163 164 165 166 167 168 |
# File 'app/models/work_items/type.rb', line 160 def allowed_child_types(cache: false, authorize: false, resource_parent: nil) cached_data = cache ? with_reactive_cache { |query_data| query_data[:allowed_child_types_by_name] } : nil types = cached_data || allowed_child_types_by_name return types unless (types, resource_parent, :child) end |
#allowed_parent_types(cache: false, authorize: false, resource_parent: nil) ⇒ Object
170 171 172 173 174 175 176 177 178 |
# File 'app/models/work_items/type.rb', line 170 def allowed_parent_types(cache: false, authorize: false, resource_parent: nil) cached_data = cache ? with_reactive_cache { |query_data| query_data[:allowed_parent_types_by_name] } : nil types = cached_data || allowed_parent_types_by_name return types unless (types, resource_parent, :parent) end |
#calculate_reactive_cache ⇒ Object
148 149 150 151 152 153 |
# File 'app/models/work_items/type.rb', line 148 def calculate_reactive_cache { allowed_child_types_by_name: allowed_child_types_by_name, allowed_parent_types_by_name: allowed_parent_types_by_name } end |
#default_issue? ⇒ Boolean
144 145 146 |
# File 'app/models/work_items/type.rb', line 144 def default_issue? name == WorkItems::Type::TYPE_NAMES[:issue] end |
#descendant_types ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'app/models/work_items/type.rb', line 180 def descendant_types descendant_types = [] next_level_child_types = allowed_child_types(cache: true) loop do descendant_types += next_level_child_types # We remove types that we've already seen to avoid circular dependencies next_level_child_types = next_level_child_types.flat_map do |type| type.allowed_child_types(cache: true) end - descendant_types break if next_level_child_types.empty? end descendant_types end |
#supported_conversion_types(resource_parent, user) ⇒ Object
155 156 157 158 |
# File 'app/models/work_items/type.rb', line 155 def supported_conversion_types(resource_parent, user) type_names = supported_conversion_base_types(resource_parent, user) - [base_type] WorkItems::Type.by_type(type_names).order_by_name_asc end |
#supports_assignee?(resource_parent) ⇒ Boolean
136 137 138 |
# File 'app/models/work_items/type.rb', line 136 def supports_assignee?(resource_parent) (resource_parent).include?(::WorkItems::Widgets::Assignees) end |
#supports_time_tracking?(resource_parent) ⇒ Boolean
140 141 142 |
# File 'app/models/work_items/type.rb', line 140 def supports_time_tracking?(resource_parent) (resource_parent).include?(::WorkItems::Widgets::TimeTracking) end |
#widget_classes(resource_parent) ⇒ Object
132 133 134 |
# File 'app/models/work_items/type.rb', line 132 def (resource_parent) (resource_parent).map(&:widget_class) end |
#widgets(_resource_parent) ⇒ Object
resource_parent is used in EE
128 129 130 |
# File 'app/models/work_items/type.rb', line 128 def (_resource_parent) .filter(&:widget_class) end |