summaryrefslogtreecommitdiff
path: root/app/models/concerns/analytics/cycle_analytics
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/concerns/analytics/cycle_analytics')
-rw-r--r--app/models/concerns/analytics/cycle_analytics/parentable.rb22
-rw-r--r--app/models/concerns/analytics/cycle_analytics/stageable.rb (renamed from app/models/concerns/analytics/cycle_analytics/stage.rb)68
2 files changed, 53 insertions, 37 deletions
diff --git a/app/models/concerns/analytics/cycle_analytics/parentable.rb b/app/models/concerns/analytics/cycle_analytics/parentable.rb
new file mode 100644
index 00000000000..785f6eea6bf
--- /dev/null
+++ b/app/models/concerns/analytics/cycle_analytics/parentable.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Analytics
+ module CycleAnalytics
+ module Parentable
+ extend ActiveSupport::Concern
+
+ included do
+ belongs_to :namespace, class_name: 'Namespace', foreign_key: :group_id, optional: false # rubocop: disable Rails/InverseOf
+
+ validate :ensure_namespace_type
+
+ def ensure_namespace_type
+ return if namespace.nil?
+ return if namespace.is_a?(::Namespaces::ProjectNamespace) || namespace.is_a?(::Group)
+
+ errors.add(:namespace, s_('CycleAnalytics|the assigned object is not supported'))
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/concerns/analytics/cycle_analytics/stage.rb b/app/models/concerns/analytics/cycle_analytics/stageable.rb
index d9e6756ab86..d1f948d1366 100644
--- a/app/models/concerns/analytics/cycle_analytics/stage.rb
+++ b/app/models/concerns/analytics/cycle_analytics/stageable.rb
@@ -2,7 +2,7 @@
module Analytics
module CycleAnalytics
- module Stage
+ module Stageable
extend ActiveSupport::Concern
include RelativePositioning
include Gitlab::Utils::StrongMemoize
@@ -10,7 +10,7 @@ module Analytics
included do
belongs_to :start_event_label, class_name: 'GroupLabel', optional: true
belongs_to :end_event_label, class_name: 'GroupLabel', optional: true
- belongs_to :stage_event_hash, class_name: 'Analytics::CycleAnalytics::StageEventHash', foreign_key: :stage_event_hash_id, optional: true
+ belongs_to :stage_event_hash, class_name: 'Analytics::CycleAnalytics::StageEventHash', optional: true
validates :name, presence: true
validates :name, exclusion: { in: Gitlab::Analytics::CycleAnalytics::DefaultStages.names }, if: :custom?
@@ -21,39 +21,31 @@ module Analytics
validate :validate_stage_event_pairs
validate :validate_labels
- enum start_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, _prefix: :start_event_identifier
- enum end_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum, _prefix: :end_event_identifier
+ enum start_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum,
+ _prefix: :start_event_identifier
+ enum end_event_identifier: Gitlab::Analytics::CycleAnalytics::StageEvents.to_enum,
+ _prefix: :end_event_identifier
alias_attribute :custom_stage?, :custom
scope :default_stages, -> { where(custom: false) }
scope :ordered, -> { order(:relative_position, :id) }
scope :with_preloaded_labels, -> { includes(:start_event_label, :end_event_label) }
scope :for_list, -> { with_preloaded_labels.ordered }
- scope :by_value_stream, -> (value_stream) { where(value_stream_id: value_stream.id) }
+ scope :by_value_stream, ->(value_stream) { where(value_stream_id: value_stream.id) }
before_save :ensure_stage_event_hash_id
after_commit :cleanup_old_stage_event_hash
end
- def parent=(_)
- raise NotImplementedError
- end
-
- def parent
- raise NotImplementedError
- end
-
def start_event
- strong_memoize(:start_event) do
- Gitlab::Analytics::CycleAnalytics::StageEvents[start_event_identifier].new(params_for_start_event)
- end
+ Gitlab::Analytics::CycleAnalytics::StageEvents[start_event_identifier].new(params_for_start_event)
end
+ strong_memoize_attr :start_event
def end_event
- strong_memoize(:end_event) do
- Gitlab::Analytics::CycleAnalytics::StageEvents[end_event_identifier].new(params_for_end_event)
- end
+ Gitlab::Analytics::CycleAnalytics::StageEvents[end_event_identifier].new(params_for_end_event)
end
+ strong_memoize_attr :end_event
def events_hash_code
Digest::SHA256.hexdigest("#{start_event.hash_code}-#{end_event.hash_code}")
@@ -109,9 +101,9 @@ module Analytics
def validate_stage_event_pairs
return if start_event_identifier.nil? || end_event_identifier.nil?
- unless pairing_rules.fetch(start_event.class, []).include?(end_event.class)
- errors.add(:end_event, s_('CycleAnalytics|not allowed for the given start event'))
- end
+ return if pairing_rules.fetch(start_event.class, []).include?(end_event.class)
+
+ errors.add(:end_event, s_('CycleAnalytics|not allowed for the given start event'))
end
def pairing_rules
@@ -119,21 +111,23 @@ module Analytics
end
def validate_labels
- validate_label_within_group(:start_event_label_id, start_event_label_id) if start_event_label_id_changed?
- validate_label_within_group(:end_event_label_id, end_event_label_id) if end_event_label_id_changed?
+ validate_label_within_namespace(:start_event_label_id, start_event_label_id) if start_event_label_id_changed?
+ validate_label_within_namespace(:end_event_label_id, end_event_label_id) if end_event_label_id_changed?
end
- def validate_label_within_group(association_name, label_id)
+ def validate_label_within_namespace(association_name, label_id)
return unless label_id
- return unless group
- unless label_available_for_group?(label_id)
- errors.add(association_name, s_('CycleAnalyticsStage|is not available for the selected group'))
- end
+ return if label_available_for_namespace?(label_id)
+
+ errors.add(association_name, s_('CycleAnalyticsStage|is not available for the selected group'))
end
- def label_available_for_group?(label_id)
- LabelsFinder.new(nil, { group_id: group.id, include_ancestor_groups: true, only_group_labels: true })
+ def label_available_for_namespace?(label_id)
+ subject = is_a?(::Analytics::CycleAnalytics::Stage) ? namespace : project.group
+ return unless subject
+
+ LabelsFinder.new(nil, { group_id: subject.id, include_ancestor_groups: true, only_group_labels: true })
.execute(skip_authorization: true)
.id_in(label_id)
.exists?
@@ -142,15 +136,15 @@ module Analytics
def ensure_stage_event_hash_id
previous_stage_event_hash = stage_event_hash&.hash_sha256
- if previous_stage_event_hash.blank? || events_hash_code != previous_stage_event_hash
- self.stage_event_hash_id = Analytics::CycleAnalytics::StageEventHash.record_id_by_hash_sha256(events_hash_code)
- end
+ return unless previous_stage_event_hash.blank? || events_hash_code != previous_stage_event_hash
+
+ self.stage_event_hash_id = Analytics::CycleAnalytics::StageEventHash.record_id_by_hash_sha256(events_hash_code)
end
def cleanup_old_stage_event_hash
- if stage_event_hash_id_previously_changed? && stage_event_hash_id_previously_was
- Analytics::CycleAnalytics::StageEventHash.cleanup_if_unused(stage_event_hash_id_previously_was)
- end
+ return unless stage_event_hash_id_previously_changed? && stage_event_hash_id_previously_was
+
+ Analytics::CycleAnalytics::StageEventHash.cleanup_if_unused(stage_event_hash_id_previously_was)
end
end
end