Class: DesignManagement::Design
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- DesignManagement::Design
- Includes:
- AtomicInternalId, CacheMarkdownField, Gitlab::FileTypeDetection, Gitlab::Utils::StrongMemoize, Import::HasImportSource, Importable, Mentionable, Noteable, Participable, Referable, RelativePositioning, Subscribable, Todoable, WhereComposite
- Defined in:
- app/models/design_management/design.rb
Constant Summary
Constants included from CacheMarkdownField
CacheMarkdownField::INVALIDATED_BY
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 Gitlab::FileTypeDetection
Gitlab::FileTypeDetection::DANGEROUS_AUDIO_EXT, Gitlab::FileTypeDetection::DANGEROUS_IMAGE_EXT, Gitlab::FileTypeDetection::DANGEROUS_VIDEO_EXT, Gitlab::FileTypeDetection::PDF_EXT, Gitlab::FileTypeDetection::SAFE_AUDIO_EXT, Gitlab::FileTypeDetection::SAFE_IMAGE_EXT, Gitlab::FileTypeDetection::SAFE_IMAGE_FOR_SCALING_EXT, Gitlab::FileTypeDetection::SAFE_VIDEO_EXT
Constants included from Noteable
Constants included from Import::HasImportSource
Import::HasImportSource::IMPORT_SOURCES
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 CacheMarkdownField
#skip_markdown_cache_validation
Attributes included from Noteable
Attributes included from Importable
#importing, #user_contributions
Class Method Summary collapse
- .build_full_path(issue, design) ⇒ Object
- .link_reference_pattern ⇒ Object
- .reference_pattern ⇒ Object
- .relative_positioning_parent_column ⇒ Object
- .relative_positioning_query_base(design) ⇒ Object
- .to_ability_name ⇒ Object
Instance Method Summary collapse
- #after_note_changed(note) ⇒ Object (also: #after_note_created, #after_note_destroyed)
- #clear_version_cache ⇒ Object
- #deleted? ⇒ Boolean
- #diff_refs ⇒ Object
- #full_path ⇒ Object
- #most_recent_action ⇒ Object
- #new_design? ⇒ Boolean
- #notes_with_associations ⇒ Object
- #repository ⇒ Object
-
#resource_parent ⇒ Object
Part of the interface of objects we can create events about.
- #status ⇒ Object
-
#to_reference(from = nil, full: false) ⇒ Object
A reference for a design is the issue reference, indexed by the filename with an optional infix when full.
- #user_notes_count ⇒ Object
-
#visible_in?(version) ⇒ Boolean
A design is visible_in? a version if: * it was created before that version * the most recent action before the version was not a deletion.
Methods included from Subscribable
#lazy_subscription, #set_subscription, #subscribe, #subscribed?, #subscribed_without_subscriptions?, #subscribers, #toggle_subscription, #unsubscribe
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!, #updated_cached_html_for
Methods included from Participable
#participant?, #participants, #visible_participants
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 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_project_users, #referenced_projects, #referenced_users, #user_mention_class, #user_mention_identifier
Methods included from Referable
#referable_inspect, #reference_link_text, #to_reference_base
Methods included from Gitlab::FileTypeDetection
#audio?, #dangerous_audio?, #dangerous_embeddable?, #dangerous_image?, #dangerous_video?, #embeddable?, extension_match?, #image?, #image_safe_for_scaling?, #pdf?, #video?
Methods included from Noteable
#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?, #noteable_target_type_name, #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 Import::HasImportSource
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, 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
.build_full_path(issue, design) ⇒ Object
187 188 189 |
# File 'app/models/design_management/design.rb', line 187 def self.build_full_path(issue, design) File.join(DesignManagement.designs_directory, "issue-#{issue.iid}", design.filename) end |
.link_reference_pattern ⇒ Object
174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'app/models/design_management/design.rb', line 174 def self.link_reference_pattern @link_reference_pattern ||= begin path_segment = %r{issues/#{Gitlab::Regex.issue}/designs} ext = Regexp.new(Regexp.union(SAFE_IMAGE_EXT + DANGEROUS_IMAGE_EXT).source, Regexp::IGNORECASE) valid_char = %r{[[:word:]\.\-\+]} filename_pattern = %r{ (?<url_filename> #{valid_char}+ \. #{ext}) }x compose_link_reference_pattern(path_segment, filename_pattern) end end |
.reference_pattern ⇒ Object
170 171 172 |
# File 'app/models/design_management/design.rb', line 170 def self.reference_pattern # no-op: We only support link_reference_pattern parsing end |
.relative_positioning_parent_column ⇒ Object
120 121 122 |
# File 'app/models/design_management/design.rb', line 120 def self.relative_positioning_parent_column :issue_id end |
.relative_positioning_query_base(design) ⇒ Object
116 117 118 |
# File 'app/models/design_management/design.rb', line 116 def self.relative_positioning_query_base(design) default_scoped.on_issue(design.issue_id) end |
.to_ability_name ⇒ Object
191 192 193 |
# File 'app/models/design_management/design.rb', line 191 def self.to_ability_name 'design' end |
Instance Method Details
#after_note_changed(note) ⇒ Object Also known as: after_note_created, after_note_destroyed
222 223 224 |
# File 'app/models/design_management/design.rb', line 222 def after_note_changed(note) user_notes_count_service.delete_cache unless note.system? end |
#clear_version_cache ⇒ Object
207 208 209 210 211 212 |
# File 'app/models/design_management/design.rb', line 207 def clear_version_cache [versions, actions].each(&:reset) %i[new_design diff_refs head_sha visible_in most_recent_action].each do |key| clear_memoization(key) end end |
#deleted? ⇒ Boolean
134 135 136 |
# File 'app/models/design_management/design.rb', line 134 def deleted? most_recent_action&.deletion? end |
#diff_refs ⇒ Object
203 204 205 |
# File 'app/models/design_management/design.rb', line 203 def diff_refs strong_memoize(:diff_refs) { head_version&.diff_refs } end |
#full_path ⇒ Object
199 200 201 |
# File 'app/models/design_management/design.rb', line 199 def full_path @full_path ||= self.class.build_full_path(issue, self) end |
#most_recent_action ⇒ Object
151 152 153 |
# File 'app/models/design_management/design.rb', line 151 def most_recent_action strong_memoize(:most_recent_action) { actions.ordered.last } end |
#new_design? ⇒ Boolean
195 196 197 |
# File 'app/models/design_management/design.rb', line 195 def new_design? strong_memoize(:new_design) { actions.none? } end |
#notes_with_associations ⇒ Object
233 234 235 |
# File 'app/models/design_management/design.rb', line 233 def notes_with_associations notes.includes(:author) end |
#repository ⇒ Object
214 215 216 |
# File 'app/models/design_management/design.rb', line 214 def repository project.design_repository end |
#resource_parent ⇒ Object
Part of the interface of objects we can create events about
229 230 231 |
# File 'app/models/design_management/design.rb', line 229 def resource_parent project end |
#status ⇒ Object
124 125 126 127 128 129 130 131 132 |
# File 'app/models/design_management/design.rb', line 124 def status if new_design? :new elsif deleted? :deleted else :current end end |
#to_reference(from = nil, full: false) ⇒ Object
A reference for a design is the issue reference, indexed by the filename with an optional infix when full.
e.g.
#123[homescreen.png]
other-project#72[sidebar.jpg]
#38/designs[transition.gif]
#12["filename with [] in it.jpg"]
163 164 165 166 167 168 |
# File 'app/models/design_management/design.rb', line 163 def to_reference(from = nil, full: false) infix = full ? '/designs' : '' safe_name = Sanitize.fragment(filename) "#{issue.to_reference(from, full: full)}#{infix}[#{safe_name}]" end |
#user_notes_count ⇒ Object
218 219 220 |
# File 'app/models/design_management/design.rb', line 218 def user_notes_count user_notes_count_service.count end |
#visible_in?(version) ⇒ Boolean
A design is visible_in? a version if:
* it was created before that version
* the most recent action before the version was not a deletion
141 142 143 144 145 146 147 148 149 |
# File 'app/models/design_management/design.rb', line 141 def visible_in?(version) map = strong_memoize(:visible_in) do Hash.new do |h, k| h[k] = self.class.visible_at_version(k).where(id: id).exists? end end map[version] end |