File: base_label.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (86 lines) | stat: -rw-r--r-- 2,181 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# frozen_string_literal: true

module BaseLabel # rubocop:disable Gitlab/BoundedContexts -- existing Label modules/classes are not bounded
  extend ActiveSupport::Concern

  DEFAULT_COLOR = ::Gitlab::Color.of('#6699cc')

  included do
    include CacheMarkdownField
    include Gitlab::SQL::Pattern

    cache_markdown_field :description, pipeline: :single_line

    attribute :color, ::Gitlab::Database::Type::Color.new, default: DEFAULT_COLOR

    before_validation :strip_whitespace_from_title

    validates :color, color: true, presence: true

    # Don't allow ',' for label titles
    validates :title, presence: true, format: { with: /\A[^,]+\z/ }
    validates :title, length: { maximum: 255 }

    # Searches for labels with a matching title or description.
    #
    # This method uses ILIKE on PostgreSQL.
    #
    # query - The search query as a String.
    #
    # Returns an ActiveRecord::Relation.
    def self.search(query, **options)
      # make sure we prevent passing in disallowed columns
      search_in = case options[:search_in]
                  when [:title]
                    [:title]
                  when [:description]
                    [:description]
                  else
                    [:title, :description]
                  end

      fuzzy_search(query, search_in)
    end

    # Override Gitlab::SQL::Pattern.min_chars_for_partial_matching as
    # label queries are never global, and so will not use a trigram
    # index. That means we can have just one character in the LIKE.
    def self.min_chars_for_partial_matching
      1
    end

    def color
      super || DEFAULT_COLOR
    end

    def text_color
      color.contrast
    end

    def title=(value)
      if value.blank?
        super
      else
        write_attribute(:title, sanitize_value(value))
      end
    end

    def description=(value)
      if value.blank?
        super
      else
        write_attribute(:description, sanitize_value(value))
      end
    end

    private

    def sanitize_value(value)
      CGI.unescapeHTML(Sanitize.clean(value.to_s))
    end

    def strip_whitespace_from_title
      self[:title] = title&.strip
    end
  end
end