1# frozen_string_literal: true 2 3module FormHelper 4 def form_errors(model, type: 'form', truncate: []) 5 errors = model.errors 6 7 return unless errors.any? 8 9 headline = n_( 10 'The %{type} contains the following error:', 11 'The %{type} contains the following errors:', 12 errors.count 13 ) % { type: type } 14 15 truncate = Array.wrap(truncate) 16 17 tag.div(class: 'alert alert-danger', id: 'error_explanation') do 18 tag.h4(headline) << 19 tag.ul do 20 messages = errors.map do |error| 21 attribute = error.attribute 22 message = error.message 23 24 message = html_escape_once(errors.full_message(attribute, message)).html_safe 25 message = tag.span(message, class: 'str-truncated-100') if truncate.include?(attribute) 26 27 tag.li(message) 28 end 29 30 messages.join.html_safe 31 end 32 end 33 end 34 35 def assignees_dropdown_options(issuable_type) 36 dropdown_data = { 37 toggle_class: 'js-user-search js-assignee-search js-multiselect js-save-user-data', 38 title: _('Select assignee'), 39 filter: true, 40 dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee', 41 placeholder: _('Search users'), 42 data: { 43 first_user: current_user&.username, 44 null_user: true, 45 current_user: true, 46 project_id: (@target_project || @project)&.id, 47 field_name: "#{issuable_type}[assignee_ids][]", 48 default_label: _('Unassigned'), 49 'max-select': 1, 50 'dropdown-header': _('Assignee'), 51 multi_select: true, 52 'input-meta': 'name', 53 'always-show-selectbox': true, 54 current_user_info: UserSerializer.new.represent(current_user) 55 } 56 } 57 58 type = issuable_type.to_s 59 60 if type == 'issue' && issue_supports_multiple_assignees? || 61 type == 'merge_request' && merge_request_supports_multiple_assignees? 62 dropdown_data = multiple_assignees_dropdown_options(dropdown_data) 63 end 64 65 dropdown_data 66 end 67 68 def reviewers_dropdown_options(issuable_type, iid = nil, target_branch = nil) 69 dropdown_data = { 70 toggle_class: 'js-reviewer-search js-multiselect js-save-user-data', 71 title: 'Request review from', 72 filter: true, 73 dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-reviewer', 74 placeholder: _('Search users'), 75 data: { 76 first_user: current_user&.username, 77 null_user: true, 78 current_user: true, 79 project_id: (@target_project || @project)&.id, 80 field_name: "#{issuable_type}[reviewer_ids][]", 81 default_label: 'Unassigned', 82 'max-select': 1, 83 'dropdown-header': 'Reviewer', 84 multi_select: true, 85 'input-meta': 'name', 86 'always-show-selectbox': true, 87 current_user_info: UserSerializer.new.represent(current_user) 88 } 89 } 90 91 if iid 92 dropdown_data[:data][:iid] = iid 93 end 94 95 if target_branch 96 dropdown_data[:data][:target_branch] = target_branch 97 end 98 99 if merge_request_supports_multiple_reviewers? 100 dropdown_data = multiple_reviewers_dropdown_options(dropdown_data) 101 end 102 103 dropdown_data 104 end 105 106 # Overwritten 107 def issue_supports_multiple_assignees? 108 false 109 end 110 111 # Overwritten 112 def merge_request_supports_multiple_assignees? 113 false 114 end 115 116 # Overwritten 117 def merge_request_supports_multiple_reviewers? 118 false 119 end 120 121 private 122 123 def multiple_assignees_dropdown_options(options) 124 new_options = options.dup 125 126 new_options[:title] = _('Select assignee(s)') 127 new_options[:data][:'dropdown-header'] = 'Assignee(s)' 128 new_options[:data].delete(:'max-select') 129 130 new_options 131 end 132 133 def multiple_reviewers_dropdown_options(options) 134 new_options = options.dup 135 136 new_options[:title] = _('Select reviewer(s)') 137 new_options[:data][:'dropdown-header'] = _('Reviewer(s)') 138 new_options[:data].delete(:'max-select') 139 140 new_options 141 end 142end 143 144FormHelper.prepend_mod_with('FormHelper') 145