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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
|
# frozen_string_literal: true
module FormHelper
def form_errors(model, type: 'form', truncate: [])
errors = model.errors
return unless errors.any?
headline = n_(
'The %{type} contains the following error:',
'The %{type} contains the following errors:',
errors.count
) % { type: type }
truncate = Array.wrap(truncate)
messages = errors.map do |error|
attribute = error.attribute
message = error.message
message = html_escape_once(errors.full_message(attribute, message)).html_safe
message = tag.span(message, class: 'str-truncated-100') if truncate.include?(attribute)
message = append_help_page_link(message, error.options) if error.options[:help_page_url].present?
tag.li(message)
end.join.html_safe
render Pajamas::AlertComponent.new(
variant: :danger,
title: headline,
dismissible: false,
alert_options: { id: 'error_explanation', class: 'gl-mb-5' }
) do |c|
c.body do
tag.ul(class: 'gl-pl-5 gl-mb-0') do
messages
end
end
end
end
def dropdown_max_select(data, feature_flag)
return data[:'max-select'] unless Feature.enabled?(feature_flag)
if data[:'max-select'] && data[:'max-select'] < ::Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
data[:'max-select']
else
::Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
end
end
def assignees_dropdown_options(issuable_type)
dropdown_data = {
toggle_class: 'js-user-search js-assignee-search js-multiselect js-save-user-data',
title: _('Select assignee'),
filter: true,
dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee',
placeholder: _('Search users'),
data: {
first_user: current_user&.username,
null_user: true,
current_user: true,
project_id: (@target_project || @project)&.id,
field_name: "#{issuable_type}[assignee_ids][]",
default_label: _('Unassigned'),
'max-select': 1,
'dropdown-header': s_('SearchToken|Assignee'),
multi_select: true,
'input-meta': 'name',
'always-show-selectbox': true,
current_user_info: UserSerializer.new.represent(current_user)
}
}
type = issuable_type.to_s
if type == 'issue' && issue_supports_multiple_assignees? ||
type == 'merge_request' && merge_request_supports_multiple_assignees?
dropdown_data = multiple_assignees_dropdown_options(dropdown_data)
end
dropdown_data
end
def reviewers_dropdown_options(issuable_type, iid = nil, target_branch = nil)
dropdown_data = {
toggle_class: 'js-reviewer-search js-multiselect js-save-user-data',
title: 'Request review from',
filter: true,
dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-reviewer',
placeholder: _('Search users'),
data: {
first_user: current_user&.username,
null_user: true,
current_user: true,
project_id: (@target_project || @project)&.id,
field_name: "#{issuable_type}[reviewer_ids][]",
default_label: 'Unassigned',
'max-select': 1,
'dropdown-header': 'Reviewer',
multi_select: true,
'input-meta': 'name',
'always-show-selectbox': true,
current_user_info: UserSerializer.new.represent(current_user)
}
}
if iid
dropdown_data[:data][:iid] = iid
end
if target_branch
dropdown_data[:data][:target_branch] = target_branch
end
if merge_request_supports_multiple_reviewers?
dropdown_data = multiple_reviewers_dropdown_options(dropdown_data)
end
dropdown_data[:data].merge!(reviewers_dropdown_options_for_suggested_reviewers)
dropdown_data
end
# Overwritten
def reviewers_dropdown_options_for_suggested_reviewers
{}
end
# Overwritten
def issue_supports_multiple_assignees?
false
end
# Overwritten
def merge_request_supports_multiple_assignees?
false
end
# Overwritten
def merge_request_supports_multiple_reviewers?
false
end
private
def append_help_page_link(message, options)
help_page_url = options[:help_page_url]
help_link_text = options[:help_link_text] || _('Learn more.')
help_link = link_to(
help_link_text,
help_page_url,
target: '_blank',
rel: 'noopener noreferrer'
)
message + " #{help_link}".html_safe
end
def multiple_assignees_dropdown_options(options)
new_options = options.dup
new_options[:title] = _('Select assignee(s)')
new_options[:data][:'dropdown-header'] = 'Assignee(s)'
if Feature.enabled?(:limit_assignees_per_issuable)
new_options[:data][:'max-select'] = ::Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
else
new_options[:data].delete(:'max-select')
end
new_options
end
def multiple_reviewers_dropdown_options(options)
new_options = options.dup
new_options[:title] = _('Select reviewer(s)')
new_options[:data][:'dropdown-header'] = _('Reviewer(s)')
if Feature.enabled?(:limit_reviewer_and_assignee_size)
new_options[:data][:'max-select'] = ::Issuable::MAX_NUMBER_OF_ASSIGNEES_OR_REVIEWERS
else
new_options[:data].delete(:'max-select')
end
new_options
end
end
FormHelper.prepend_mod_with('FormHelper')
|