diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-06 00:09:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-06 00:09:42 +0300 |
commit | 53288eeb6300a5c162f146b13d1710c71f0ee197 (patch) | |
tree | 790faa45cf2a56bb0022ef02f989ddbd8ab0c0d9 /app/models/concerns/timebox.rb | |
parent | 38ceebb9b3a541f8530b379d5b5ab5e13ffc58ed (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models/concerns/timebox.rb')
-rw-r--r-- | app/models/concerns/timebox.rb | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/app/models/concerns/timebox.rb b/app/models/concerns/timebox.rb index 7b518d3dda3..b460baff8bc 100644 --- a/app/models/concerns/timebox.rb +++ b/app/models/concerns/timebox.rb @@ -5,10 +5,31 @@ module Timebox include AtomicInternalId include CacheMarkdownField + include Gitlab::SQL::Pattern include IidRoutes include StripAttribute + TimeboxStruct = Struct.new(:title, :name, :id) do + # Ensure these models match the interface required for exporting + def serializable_hash(_opts = {}) + { title: title, name: name, id: id } + end + end + + # Represents a "No Timebox" state used for filtering Issues and Merge + # Requests that have no timeboxes assigned. + None = TimeboxStruct.new('No Timebox', 'No Timebox', 0) + Any = TimeboxStruct.new('Any Timebox', '', -1) + Upcoming = TimeboxStruct.new('Upcoming', '#upcoming', -2) + Started = TimeboxStruct.new('Started', '#started', -3) + included do + # Defines the same constants above, but inside the including class. + const_set :None, TimeboxStruct.new("No #{self.name}", "No #{self.name}", 0) + const_set :Any, TimeboxStruct.new("Any #{self.name}", '', -1) + const_set :Upcoming, TimeboxStruct.new('Upcoming', '#upcoming', -2) + const_set :Started, TimeboxStruct.new('Started', '#started', -3) + alias_method :timebox_id, :id validates :group, presence: true, unless: :project @@ -35,6 +56,7 @@ module Timebox scope :active, -> { with_state(:active) } scope :closed, -> { with_state(:closed) } scope :for_projects, -> { where(group: nil).includes(:project) } + scope :with_title, -> (title) { where(title: title) } scope :for_projects_and_groups, -> (projects, groups) do projects = projects.compact if projects.is_a? Array @@ -57,6 +79,50 @@ module Timebox alias_attribute :name, :title end + class_methods do + # Searches for timeboxes with a matching title or description. + # + # This method uses ILIKE on PostgreSQL + # + # query - The search query as a String + # + # Returns an ActiveRecord::Relation. + def search(query) + fuzzy_search(query, [:title, :description]) + end + + # Searches for timeboxes with a matching title. + # + # This method uses ILIKE on PostgreSQL + # + # query - The search query as a String + # + # Returns an ActiveRecord::Relation. + def search_title(query) + fuzzy_search(query, [:title]) + end + + def filter_by_state(timeboxes, state) + case state + when 'closed' then timeboxes.closed + when 'all' then timeboxes + else timeboxes.active + end + end + + def count_by_state + reorder(nil).group(:state).count + end + + def predefined_id?(id) + [Any.id, None.id, Upcoming.id, Started.id].include?(id) + end + + def predefined?(timebox) + predefined_id?(timebox&.id) + end + end + def title=(value) write_attribute(:title, sanitize_title(value)) if value.present? end |