diff options
Diffstat (limited to 'app/views')
19 files changed, 235 insertions, 97 deletions
diff --git a/app/views/issues/_issue.atom.builder b/app/views/issues/_issue.atom.builder index 23a88448055..9ec765c45f9 100644 --- a/app/views/issues/_issue.atom.builder +++ b/app/views/issues/_issue.atom.builder @@ -23,10 +23,12 @@ xml.entry do end end - if issue.assignee - xml.assignee do - xml.name issue.assignee.name - xml.email issue.assignee_public_email + if issue.assignees.any? + xml.assignees do + issue.assignees.each do |assignee| + xml.name assignee.name + xml.email assignee.public_email + end end end end diff --git a/app/views/notify/_reassigned_issuable_email.text.erb b/app/views/notify/_reassigned_issuable_email.text.erb deleted file mode 100644 index daf20a226dd..00000000000 --- a/app/views/notify/_reassigned_issuable_email.text.erb +++ /dev/null @@ -1,6 +0,0 @@ -Reassigned <%= issuable.class.model_name.human.titleize %> <%= issuable.iid %> - -<%= url_for([issuable.project.namespace.becomes(Namespace), issuable.project, issuable, { only_path: false }]) %> - -Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee -%> - to <%= "#{issuable.assignee_id ? issuable.assignee_name : 'Unassigned'}" %> diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml index c762578971a..eb5157ccac9 100644 --- a/app/views/notify/new_issue_email.html.haml +++ b/app/views/notify/new_issue_email.html.haml @@ -2,9 +2,9 @@ %p.details #{link_to @issue.author_name, user_url(@issue.author)} created an issue: -- if @issue.assignee_id.present? +- if @issue.assignees.any? %p - Assignee: #{@issue.assignee_name} + Assignee: #{@issue.assignee_list} - if @issue.description %div diff --git a/app/views/notify/new_issue_email.text.erb b/app/views/notify/new_issue_email.text.erb index ca5c2f2688c..13f1ac08e94 100644 --- a/app/views/notify/new_issue_email.text.erb +++ b/app/views/notify/new_issue_email.text.erb @@ -2,6 +2,6 @@ New Issue was created. Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> Author: <%= @issue.author_name %> -Assignee: <%= @issue.assignee_name %> +Assignee: <%= @issue.assignee_list %> <%= @issue.description %> diff --git a/app/views/notify/new_mention_in_issue_email.text.erb b/app/views/notify/new_mention_in_issue_email.text.erb index 457e94b4800..f19ac3adfc7 100644 --- a/app/views/notify/new_mention_in_issue_email.text.erb +++ b/app/views/notify/new_mention_in_issue_email.text.erb @@ -2,6 +2,6 @@ You have been mentioned in an issue. Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %> Author: <%= @issue.author_name %> -Assignee: <%= @issue.assignee_name %> +Assignee: <%= @issue.assignee_list %> <%= @issue.description %> diff --git a/app/views/notify/reassigned_issue_email.html.haml b/app/views/notify/reassigned_issue_email.html.haml index 498ba8b8365..ee2f40e1683 100644 --- a/app/views/notify/reassigned_issue_email.html.haml +++ b/app/views/notify/reassigned_issue_email.html.haml @@ -1 +1,10 @@ -= render 'reassigned_issuable_email', issuable: @issue +%p + Assignee changed + - if @previous_assignees.any? + from + %strong= @previous_assignees.map(&:name).to_sentence + to + - if @issue.assignees.any? + %strong= @issue.assignee_list + - else + %strong Unassigned diff --git a/app/views/notify/reassigned_issue_email.text.erb b/app/views/notify/reassigned_issue_email.text.erb index 710253be984..6c357f1074a 100644 --- a/app/views/notify/reassigned_issue_email.text.erb +++ b/app/views/notify/reassigned_issue_email.text.erb @@ -1 +1,6 @@ -<%= render 'reassigned_issuable_email', issuable: @issue %> +Reassigned Issue <%= @issue.iid %> + +<%= url_for([@issue.project.namespace.becomes(Namespace), @issue.project, @issue, { only_path: false }]) %> + +Assignee changed <%= "from #{@previous_assignees.map(&:name).to_sentence}" if @previous_assignees.any? -%> + to <%= "#{@issue.assignees.any? ? @issue.assignee_list : 'Unassigned'}" %> diff --git a/app/views/notify/reassigned_merge_request_email.html.haml b/app/views/notify/reassigned_merge_request_email.html.haml index 2a650130f59..841df872857 100644 --- a/app/views/notify/reassigned_merge_request_email.html.haml +++ b/app/views/notify/reassigned_merge_request_email.html.haml @@ -1 +1,9 @@ -= render 'reassigned_issuable_email', issuable: @merge_request +Reassigned Merge Request #{ @merge_request.iid } + += url_for([@merge_request.project.namespace.becomes(Namespace), @merge_request.project, @merge_request, { only_path: false }]) + +Assignee changed +- if @previous_assignee + from #{@previous_assignee.name} +to += @merge_request.assignee_id ? @merge_request.assignee_name : 'Unassigned' diff --git a/app/views/notify/reassigned_merge_request_email.text.erb b/app/views/notify/reassigned_merge_request_email.text.erb index b5b4f1ff99a..998a40fefde 100644 --- a/app/views/notify/reassigned_merge_request_email.text.erb +++ b/app/views/notify/reassigned_merge_request_email.text.erb @@ -1 +1,6 @@ -<%= render 'reassigned_issuable_email', issuable: @merge_request %> +Reassigned Merge Request <%= @merge_request.iid %> + +<%= url_for([@merge_request.project.namespace.becomes(Namespace), @merge_request.project, @merge_request, { only_path: false }]) %> + +Assignee changed <%= "from #{@previous_assignee.name}" if @previous_assignee -%> + to <%= "#{@merge_request.assignee_id ? @merge_request.assignee_name : 'Unassigned'}" %> diff --git a/app/views/projects/boards/components/sidebar/_assignee.html.haml b/app/views/projects/boards/components/sidebar/_assignee.html.haml index 0f424334521..96f7f12b1d7 100644 --- a/app/views/projects/boards/components/sidebar/_assignee.html.haml +++ b/app/views/projects/boards/components/sidebar/_assignee.html.haml @@ -1,40 +1,32 @@ -.block.assignee - .title.hide-collapsed - Assignee - - if can?(current_user, :admin_issue, @project) - = icon("spinner spin", class: "block-loading") - = link_to "Edit", "#", class: "edit-link pull-right" - .value.hide-collapsed - %span.assign-yourself.no-value{ "v-if" => "!issue.assignee" } - No assignee - - if can?(current_user, :admin_issue, @project) - \- - %a.js-assign-yourself{ href: "#" } - assign yourself - %a.author_link.bold{ ":href" => "'#{root_url}' + issue.assignee.username", - "v-if" => "issue.assignee" } - %img.avatar.avatar-inline.s32{ ":src" => "issue.assignee.avatar", - width: "32", alt: "Avatar" } - %span.author - {{ issue.assignee.name }} - %span.username - = precede "@" do - {{ issue.assignee.username }} +.block.assignee{ ref: "assigneeBlock" } + %template{ "v-if" => "issue.assignees" } + %assignee-title{ ":number-of-assignees" => "issue.assignees.length", + ":loading" => "loadingAssignees", + ":editable" => can?(current_user, :admin_issue, @project) } + %assignees.value{ "root-path" => "#{root_url}", + ":users" => "issue.assignees", + ":editable" => can?(current_user, :admin_issue, @project), + "@assign-self" => "assignSelf" } + - if can?(current_user, :admin_issue, @project) .selectbox.hide-collapsed %input{ type: "hidden", - name: "issue[assignee_id]", - id: "issue_assignee_id", - ":value" => "issue.assignee.id", - "v-if" => "issue.assignee" } + name: "issue[assignee_ids][]", + ":value" => "assignee.id", + "v-if" => "issue.assignees", + "v-for" => "assignee in issue.assignees" } .dropdown +<<<<<<< HEAD %button.dropdown-menu-toggle.js-user-search.js-author-search.js-issue-board-sidebar{ type: "button", data: { toggle: "dropdown", field_name: "issue[assignee_id]", first_user: (current_user.username if current_user), current_user: "true", project_id: @project.id, null_user: "true", null_user_default: "true" }, +======= + %button.dropdown-menu-toggle.js-user-search.js-author-search.js-multiselect.js-save-user-data.js-issue-board-sidebar{ type: "button", ref: "assigneeDropdown", data: { toggle: "dropdown", field_name: "issue[assignee_ids][]", first_user: (current_user.username if current_user), current_user: "true", project_id: @project.id, null_user: "true", multi_select: "true", dropdown: { header: 'Assignee(s)'} }, +>>>>>>> b0a2435... Merge branch 'multiple_assignees_review_upstream' into ee_master ":data-issuable-id" => "issue.id", ":data-selected" => "assigneeId", ":data-issue-update" => "'#{namespace_project_issues_path(@project.namespace, @project)}/' + issue.id + '.json'" } - Select assignee + Select assignee(s) = icon("chevron-down") - .dropdown-menu.dropdown-menu-user.dropdown-menu-selectable.dropdown-menu-author + .dropdown-menu.dropdown-select.dropdown-menu-user.dropdown-menu-selectable.dropdown-menu-author = dropdown_title("Assign to") = dropdown_filter("Search users") = dropdown_content diff --git a/app/views/projects/issues/_issue.html.haml b/app/views/projects/issues/_issue.html.haml index 0e3902c066a..c184e0e0022 100644 --- a/app/views/projects/issues/_issue.html.haml +++ b/app/views/projects/issues/_issue.html.haml @@ -13,9 +13,9 @@ %li CLOSED - - if issue.assignee + - if issue.assignees.any? %li - = link_to_member(@project, issue.assignee, name: false, title: "Assigned to :name") + = render 'shared/issuable/assignees', project: @project, issue: issue = render 'shared/issuable_meta_data', issuable: issue diff --git a/app/views/shared/issuable/_assignees.html.haml b/app/views/shared/issuable/_assignees.html.haml new file mode 100644 index 00000000000..36bbb1148d4 --- /dev/null +++ b/app/views/shared/issuable/_assignees.html.haml @@ -0,0 +1,15 @@ +- max_render = 3 +- max = [max_render, issue.assignees.length].min + +- issue.assignees.each_with_index do |assignee, index| + - if index < max + = link_to_member(@project, assignee, name: false, title: "Assigned to :name") + +- if issue.assignees.length > max_render + - counter = issue.assignees.length - max_render + + %span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old', 'original-title' => "+#{counter} more assignees" } } + - if counter < 99 + = "+#{counter}" + - else + 99+ diff --git a/app/views/shared/issuable/_participants.html.haml b/app/views/shared/issuable/_participants.html.haml index 171da899937..db407363a09 100644 --- a/app/views/shared/issuable/_participants.html.haml +++ b/app/views/shared/issuable/_participants.html.haml @@ -12,9 +12,9 @@ - participants.each do |participant| .participants-author.js-participants-author = link_to_member(@project, participant, name: false, size: 24) - - if participants_extra > 0 - .participants-more - %a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } } - + #{participants_extra} more + - if participants_extra > 0 + .hide-collapsed.participants-more + %a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } } + + #{participants_extra} more :javascript IssuableContext.prototype.PARTICIPANTS_ROW_COUNT = #{participants_row}; diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index b6fce5e3cd4..dd727f1abfb 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -124,8 +124,17 @@ %li %a{ href: "#", data: { id: "close" } } Closed .filter-item.inline + - if type == :issues + - field_name = "update[assignee_ids][]" + - else + - field_name = "update[assignee_id]" + = dropdown_tag("Assignee", options: { toggle_class: "js-user-search js-update-assignee js-filter-submit js-filter-bulk-update", title: "Assign to", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable", +<<<<<<< HEAD placeholder: "Search authors", data: { first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: @project.id, field_name: "update[assignee_id]", default_label: "Assignee" } }) +======= + placeholder: "Search authors", data: { first_user: (current_user.username if current_user), null_user: true, current_user: true, project_id: @project.id, field_name: field_name } }) +>>>>>>> b0a2435... Merge branch 'multiple_assignees_review_upstream' into ee_master .filter-item.inline = dropdown_tag("Milestone", options: { title: "Assign milestone", toggle_class: 'js-milestone-select js-extra-options js-filter-submit js-filter-bulk-update', filter: true, dropdown_class: "dropdown-menu-selectable dropdown-menu-milestone", placeholder: "Search milestones", data: { show_no: true, field_name: "update[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), use_id: true, default_label: "Milestone" } }) .filter-item.inline.labels-filter diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index bc638e994f3..9bf73c87c88 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -1,10 +1,10 @@ - todo = issuable_todo(issuable) - content_for :page_specific_javascripts do = page_specific_javascript_bundle_tag('common_vue') - = page_specific_javascript_bundle_tag('issuable') + = page_specific_javascript_bundle_tag('sidebar') %aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => "102", "spy" => "affix" }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' } - .issuable-sidebar + .issuable-sidebar{ data: { endpoint: "#{issuable_json_path(issuable)}" } } - can_edit_issuable = can?(current_user, :"admin_#{issuable.to_ability_name}", @project) .block.issuable-sidebar-header - if current_user @@ -20,36 +20,59 @@ .block.todo.hide-expanded = render "shared/issuable/sidebar_todo", todo: todo, issuable: issuable, is_collapsed: true .block.assignee - .sidebar-collapsed-icon.sidebar-collapsed-user{ data: { toggle: "tooltip", placement: "left", container: "body" }, title: (issuable.assignee.name if issuable.assignee) } - - if issuable.assignee - = link_to_member(@project, issuable.assignee, size: 24) - - else - = icon('user', 'aria-hidden': 'true') - .title.hide-collapsed - Assignee - = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') - - if can_edit_issuable - = link_to 'Edit', '#', class: 'edit-link pull-right' - .value.hide-collapsed - - if issuable.assignee - = link_to_member(@project, issuable.assignee, size: 32, extra_class: 'bold') do - - if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee) - %span.pull-right.cannot-be-merged{ data: { toggle: 'tooltip', placement: 'left' }, title: 'Not allowed to merge' } - = icon('exclamation-triangle', 'aria-hidden': 'true') - %span.username - = issuable.assignee.to_reference - - else - %span.assign-yourself.no-value - No assignee - - if can_edit_issuable - \- - %a.js-assign-yourself{ href: '#' } - assign yourself + - if issuable.instance_of?(Issue) + #js-vue-sidebar-assignees{ data: { field: "#{issuable.to_ability_name}[assignee_ids]" } } + - else + .sidebar-collapsed-icon.sidebar-collapsed-user{ data: { toggle: "tooltip", placement: "left", container: "body" }, title: (issuable.assignee.name if issuable.assignee) } + - if issuable.assignee + = link_to_member(@project, issuable.assignee, size: 24) + - else + = icon('user', 'aria-hidden': 'true') + .title.hide-collapsed + Assignee + = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') + - if can_edit_issuable + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.hide-collapsed + - if issuable.assignee + = link_to_member(@project, issuable.assignee, size: 32, extra_class: 'bold') do + - if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee) + %span.pull-right.cannot-be-merged{ data: { toggle: 'tooltip', placement: 'left' }, title: 'Not allowed to merge' } + = icon('exclamation-triangle', 'aria-hidden': 'true') + %span.username + = issuable.assignee.to_reference + - else + %span.assign-yourself.no-value + No assignee + - if can_edit_issuable + \- + %a.js-assign-yourself{ href: '#' } + assign yourself .selectbox.hide-collapsed +<<<<<<< HEAD = f.hidden_field 'assignee_id', value: issuable.assignee_id, id: 'issue_assignee_id' = dropdown_tag('Select assignee', options: { toggle_class: 'js-user-search js-author-search', title: 'Assign to', filter: true, dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author', placeholder: 'Search users', data: { first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), author_id: issuable.author_id, field_name: "#{issuable.to_ability_name}[assignee_id]", issue_update: issuable_json_path(issuable), ability_name: issuable.to_ability_name, null_user: true, null_user_default: true, selected: issuable.assignee_id } }) +======= + - issuable.assignees.each do |assignee| + = hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", assignee.id, id: nil +>>>>>>> b0a2435... Merge branch 'multiple_assignees_review_upstream' into ee_master + - options = { toggle_class: 'js-user-search js-author-search', title: 'Assign to', filter: true, dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author', placeholder: 'Search users', data: { first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), author_id: issuable.author_id, field_name: "#{issuable.to_ability_name}[assignee_id]", issue_update: issuable_json_path(issuable), ability_name: issuable.to_ability_name, null_user: true } } + + - if issuable.instance_of?(Issue) + - if issuable.assignees.length == 0 + = hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", 0, id: nil + - title = 'Select assignee(s)' + - options[:toggle_class] += ' js-multiselect js-save-user-data' + - options[:data][:field_name] = "#{issuable.to_ability_name}[assignee_ids][]" + - options[:data][:multi_select] = true + - options[:data]['dropdown-title'] = title + - options[:data]['dropdown-header'] = 'Assignee(s)' + - else + - title = 'Select assignee' + + = dropdown_tag(title, options: options) .block.milestone .sidebar-collapsed-icon = icon('clock-o', 'aria-hidden': 'true') @@ -75,11 +98,10 @@ = dropdown_tag('Milestone', options: { title: 'Assign milestone', toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: 'Search milestones', data: { show_no: true, field_name: "#{issuable.to_ability_name}[milestone_id]", project_id: @project.id, issuable_id: issuable.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: issuable.to_ability_name, issue_update: issuable_json_path(issuable), use_id: true }}) - if issuable.has_attribute?(:time_estimate) #issuable-time-tracker.block - %issuable-time-tracker{ ':time_estimate' => 'issuable.time_estimate', ':time_spent' => 'issuable.total_time_spent', ':human_time_estimate' => 'issuable.human_time_estimate', ':human_time_spent' => 'issuable.human_total_time_spent', 'docs-url' => help_page_path('workflow/time_tracking.md') } - // Fallback while content is loading - .title.hide-collapsed - Time tracking - = icon('spinner spin', 'aria-hidden': 'true') + // Fallback while content is loading + .title.hide-collapsed + Time tracking + = icon('spinner spin', 'aria-hidden': 'true') - if issuable.has_attribute?(:due_date) .block.due_date .sidebar-collapsed-icon @@ -169,8 +191,13 @@ = clipboard_button(text: project_ref, title: "Copy reference to clipboard", placement: "left") :javascript - gl.IssuableResource = new gl.SubbableResource('#{issuable_json_path(issuable)}'); - new gl.IssuableTimeTracking("#{escape_javascript(serialize_issuable(issuable))}"); + gl.sidebarOptions = { + endpoint: "#{issuable_json_path(issuable)}", + editable: #{can_edit_issuable ? true : false}, + currentUser: #{current_user.to_json(only: [:username, :id, :name], methods: :avatar_url)}, + rootPath: "#{root_path}" + }; + new MilestoneSelect('{"full_path":"#{@project.full_path}"}'); new LabelsSelect(); new IssuableContext('#{escape_javascript(current_user.to_json(only: [:username, :id, :name]))}'); diff --git a/app/views/shared/issuable/form/_issue_assignee.html.haml b/app/views/shared/issuable/form/_issue_assignee.html.haml new file mode 100644 index 00000000000..c33474ac3b4 --- /dev/null +++ b/app/views/shared/issuable/form/_issue_assignee.html.haml @@ -0,0 +1,30 @@ +- issue = issuable +.block.assignee + .sidebar-collapsed-icon.sidebar-collapsed-user{ data: { toggle: "tooltip", placement: "left", container: "body" }, title: (issuable.assignee_list) } + - if issue.assignees.any? + - issue.assignees.each do |assignee| + = link_to_member(@project, assignee, size: 24) + - else + = icon('user', 'aria-hidden': 'true') + .title.hide-collapsed + Assignee + = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') + - if can_edit_issuable + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.hide-collapsed + - if issue.assignees.any? + - issue.assignees.each do |assignee| + = link_to_member(@project, assignee, size: 32, extra_class: 'bold') do + %span.username + = assignee.to_reference + - else + %span.assign-yourself.no-value + No assignee + - if can_edit_issuable + \- + %a.js-assign-yourself{ href: '#' } + assign yourself + + .selectbox.hide-collapsed + = f.hidden_field 'assignee_ids', value: issuable.assignee_ids, id: 'issue_assignee_ids' + = dropdown_tag('Select assignee', options: { toggle_class: 'js-user-search js-author-search', title: 'Assign to', filter: true, dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author', placeholder: 'Search users', data: { first_user: (current_user.username if current_user), current_user: true, project_id: (@project.id if @project), author_id: issuable.author_id, field_name: "#{issuable.to_ability_name}[assignee_id]", issue_update: issuable_json_path(issuable), ability_name: issuable.to_ability_name, null_user: true } }) diff --git a/app/views/shared/issuable/form/_merge_request_assignee.html.haml b/app/views/shared/issuable/form/_merge_request_assignee.html.haml new file mode 100644 index 00000000000..18011d528a0 --- /dev/null +++ b/app/views/shared/issuable/form/_merge_request_assignee.html.haml @@ -0,0 +1,31 @@ +- merge_request = issuable +.block.assignee + .sidebar-collapsed-icon.sidebar-collapsed-user{ data: { toggle: "tooltip", placement: "left", container: "body" }, title: (merge_request.assignee.name if merge_request.assignee) } + - if merge_request.assignee + = link_to_member(@project, merge_request.assignee, size: 24) + - else + = icon('user', 'aria-hidden': 'true') + .title.hide-collapsed + Assignee + = icon('spinner spin', class: 'hidden block-loading', 'aria-hidden': 'true') + - if can_edit_issuable + = link_to 'Edit', '#', class: 'edit-link pull-right' + .value.hide-collapsed + - if merge_request.assignee + = link_to_member(@project, merge_request.assignee, size: 32, extra_class: 'bold') do + - unless merge_request.can_be_merged_by?(merge_request.assignee) + %span.pull-right.cannot-be-merged{ data: { toggle: 'tooltip', placement: 'left' }, title: 'Not allowed to merge' } + = icon('exclamation-triangle', 'aria-hidden': 'true') + %span.username + = merge_request.assignee.to_reference + - else + %span.assign-yourself.no-value + No assignee + - if can_edit_issuable + \- + %a.js-assign-yourself{ href: '#' } + assign yourself + + .selectbox.hide-collapsed + = f.hidden_field 'assignee_id', value: merge_request.assignee_id, id: 'issue_assignee_id' + = dropdown_tag('Select assignee', options: { toggle_class: 'js-user-search js-author-search', title: 'Assign to', filter: true, dropdown_class: 'dropdown-menu-user dropdown-menu-selectable dropdown-menu-author', placeholder: 'Search users', data: { first_user: (current_user.username if current_user), current_user: true, project_id: @project&.id, author_id: merge_request.author_id, field_name: 'merge_request[assignee_id]', issue_update: issuable_json_path(merge_request), ability_name: 'merge_request', null_user: true } }) diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml index 9dbfedb84f1..411cb717fc7 100644 --- a/app/views/shared/issuable/form/_metadata.html.haml +++ b/app/views/shared/issuable/form/_metadata.html.haml @@ -10,13 +10,24 @@ .row %div{ class: (has_due_date ? "col-lg-6" : "col-sm-12") } .form-group.issue-assignee - = form.label :assignee_id, "Assignee", class: "control-label #{"col-lg-4" if has_due_date}" - .col-sm-10{ class: ("col-lg-8" if has_due_date) } - .issuable-form-select-holder - = form.hidden_field :assignee_id - = dropdown_tag(user_dropdown_label(issuable.assignee_id, "Assignee"), options: { toggle_class: "js-dropdown-keep-input js-user-search js-issuable-form-dropdown js-assignee-search", title: "Select assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee js-filter-submit", - placeholder: "Search assignee", data: { first_user: current_user.try(:username), null_user: true, current_user: true, project_id: issuable.project.try(:id), selected: issuable.assignee_id, field_name: "#{issuable.class.model_name.param_key}[assignee_id]", default_label: "Assignee"} }) - = link_to 'Assign to me', '#', class: "assign-to-me-link #{'hide' if issuable.assignee_id == current_user.id}" + - if issuable.is_a?(Issue) + = form.label :assignee_ids, "Assignee", class: "control-label #{"col-lg-4" if has_due_date}" + .col-sm-10{ class: ("col-lg-8" if has_due_date) } + .issuable-form-select-holder.selectbox + - issuable.assignees.each do |assignee| + = hidden_field_tag "#{issuable.to_ability_name}[assignee_ids][]", assignee.id, id: nil, data: { meta: assignee.name } + + = dropdown_tag(users_dropdown_label(issuable.assignees), options: issue_dropdown_options(issuable, true)) + = link_to 'Assign to me', '#', class: "assign-to-me-link #{'hide' if issuable.assignees.include?(current_user)}" + - else + = form.label :assignee_id, "Assignee", class: "control-label #{"col-lg-4" if has_due_date}" + .col-sm-10{ class: ("col-lg-8" if has_due_date) } + .issuable-form-select-holder + = form.hidden_field :assignee_id + + = dropdown_tag(user_dropdown_label(issuable.assignee_id, "Assignee"), options: { toggle_class: "js-dropdown-keep-input js-user-search js-issuable-form-dropdown js-assignee-search", title: "Select assignee", filter: true, dropdown_class: "dropdown-menu-user dropdown-menu-selectable dropdown-menu-assignee js-filter-submit", + placeholder: "Search assignee", data: { first_user: current_user.try(:username), null_user: true, current_user: true, project_id: issuable.project.try(:id), selected: issuable.assignee_id, field_name: "#{issuable.class.model_name.param_key}[assignee_id]", default_label: "Assignee"} }) + = link_to 'Assign to me', '#', class: "assign-to-me-link #{'hide' if issuable.assignee_id == current_user.id}" .form-group.issue-milestone = form.label :milestone_id, "Milestone", class: "control-label #{"col-lg-4" if has_due_date}" .col-sm-10{ class: ("col-lg-8" if has_due_date) } diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml index 5247d6a51e6..22547a30cdf 100644 --- a/app/views/shared/milestones/_issuable.html.haml +++ b/app/views/shared/milestones/_issuable.html.haml @@ -1,7 +1,7 @@ -# @project is present when viewing Project's milestone - project = @project || issuable.project - namespace = @project_namespace || project.namespace.becomes(Namespace) -- assignee = issuable.assignee +- assignees = issuable.assignees - issuable_type = issuable.class.table_name - base_url_args = [namespace, project] - issuable_type_args = base_url_args + [issuable_type] @@ -26,7 +26,7 @@ - render_colored_label(label) %span.assignee-icon - - if assignee - = link_to polymorphic_path(issuable_type_args, { milestone_title: @milestone.title, assignee_id: issuable.assignee_id, state: 'all' }), + - assignees.each do |assignee| + = link_to polymorphic_path(base_url_args, { milestone_title: @milestone.title, assignee_id: assignee.id, state: 'all' }), class: 'has-tooltip', title: "Assigned to #{assignee.name}", data: { container: 'body' } do - - image_tag(avatar_icon(issuable.assignee, 16), class: "avatar s16", alt: '') + - image_tag(avatar_icon(assignee, 16), class: "avatar s16", alt: '') |