From ca884980ee8e6fe1269f5abdb803519d51aa09c0 Mon Sep 17 00:00:00 2001 From: Oswaldo Ferreira Date: Sun, 7 Apr 2019 15:35:16 -0300 Subject: [CE] Support multiple assignees for merge requests Backports https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/10161 (code out of ee/ folder). --- .../javascripts/issuable_bulk_update_actions.js | 3 - .../sidebar/components/assignees/assignees.vue | 33 ++++- app/assets/stylesheets/pages/merge_requests.scss | 10 ++ app/assets/stylesheets/pages/projects.scss | 2 + app/controllers/concerns/issuable_actions.rb | 7 +- app/controllers/concerns/issuable_collections.rb | 10 +- .../merge_requests/application_controller.rb | 2 +- app/finders/issuable_finder.rb | 30 ++-- app/finders/issues_finder.rb | 14 -- app/helpers/boards_helper.rb | 2 +- app/helpers/form_helper.rb | 39 ++++- app/helpers/issuables_helper.rb | 11 +- app/mailers/emails/merge_requests.rb | 6 +- app/mailers/notify.rb | 2 + app/models/concerns/deprecated_assignee.rb | 86 +++++++++++ app/models/concerns/issuable.rb | 41 ++++-- app/models/issue.rb | 22 --- app/models/merge_request.rb | 51 +------ app/models/project.rb | 4 + app/serializers/issuable_sidebar_extras_entity.rb | 2 + app/serializers/issue_sidebar_extras_entity.rb | 1 - app/serializers/merge_request_assignee_entity.rb | 7 + app/serializers/merge_request_basic_entity.rb | 3 +- app/serializers/merge_request_serializer.rb | 4 +- .../merge_request_sidebar_basic_entity.rb | 11 -- .../merge_request_sidebar_extras_entity.rb | 7 + app/services/issuable_base_service.rb | 18 ++- app/services/issues/base_service.rb | 22 +-- app/services/issues/update_service.rb | 2 +- app/services/merge_requests/base_service.rb | 6 +- app/services/merge_requests/update_service.rb | 18 +-- app/services/notification_recipient_service.rb | 24 +--- app/services/notification_service.rb | 20 +-- app/services/system_note_service.rb | 10 +- app/services/todo_service.rb | 16 +-- .../notify/_reassigned_issuable_email.html.haml | 10 ++ .../notify/closed_merge_request_email.text.haml | 2 +- app/views/notify/issue_due_email.html.haml | 2 +- app/views/notify/issue_due_email.text.erb | 2 +- .../notify/merge_request_status_email.text.haml | 2 +- .../merge_request_unmergeable_email.text.haml | 2 +- .../notify/merged_merge_request_email.text.haml | 2 +- app/views/notify/new_issue_email.html.haml | 2 +- app/views/notify/new_issue_email.text.erb | 2 +- .../notify/new_mention_in_issue_email.text.erb | 2 +- .../new_mention_in_merge_request_email.text.erb | 2 +- app/views/notify/new_merge_request_email.html.haml | 4 +- app/views/notify/new_merge_request_email.text.erb | 2 +- app/views/notify/reassigned_issue_email.html.haml | 11 +- .../reassigned_merge_request_email.html.haml | 11 +- .../notify/reassigned_merge_request_email.text.erb | 4 +- app/views/projects/issues/_issue.html.haml | 2 +- .../merge_requests/_merge_request.html.haml | 4 +- .../boards/components/sidebar/_assignee.html.haml | 2 +- app/views/shared/issuable/_assignees.html.haml | 6 +- .../shared/issuable/_bulk_update_sidebar.html.haml | 5 +- .../shared/issuable/_sidebar_assignees.html.haml | 56 ++------ .../form/_merge_request_assignee.html.haml | 31 ---- app/views/shared/issuable/form/_metadata.html.haml | 7 +- .../form/_metadata_issuable_assignee.html.haml | 11 ++ .../form/_metadata_issue_assignee.html.haml | 11 -- db/fixtures/development/10_merge_requests.rb | 2 +- lib/api/entities.rb | 6 +- lib/api/merge_requests.rb | 4 + .../reference_parser/merge_request_parser.rb | 2 +- lib/gitlab/hook_data/issuable_builder.rb | 6 +- lib/gitlab/hook_data/merge_request_builder.rb | 5 +- locale/gitlab.pot | 18 --- qa/qa/page/merge_request/new.rb | 2 +- .../projects/merge_requests_controller_spec.rb | 6 +- spec/features/dashboard/issuables_counter_spec.rb | 4 +- spec/features/dashboard/merge_requests_spec.rb | 4 +- spec/features/groups/merge_requests_spec.rb | 2 +- spec/features/issues/form_spec.rb | 4 +- .../user_creates_merge_request_spec.rb | 4 +- .../features/merge_request/user_creates_mr_spec.rb | 15 +- spec/features/merge_request/user_edits_mr_spec.rb | 18 ++- .../user_filters_by_assignees_spec.rb | 2 +- .../user_filters_by_multiple_criteria_spec.rb | 2 +- .../user_lists_merge_requests_spec.rb | 4 +- .../merge_requests/user_mass_updates_spec.rb | 3 +- .../search/user_uses_header_search_field_spec.rb | 4 +- spec/finders/issues_finder_spec.rb | 64 +++------ spec/finders/merge_requests_finder_spec.rb | 49 +++++-- .../api/schemas/entities/merge_request_basic.json | 12 +- .../api/schemas/public_api/v4/merge_request.json | 5 + spec/javascripts/sidebar/assignees_spec.js | 85 +++++++++++ spec/lib/gitlab/hook_data/issuable_builder_spec.rb | 6 +- .../gitlab/hook_data/merge_request_builder_spec.rb | 1 + spec/lib/gitlab/import_export/all_models.yml | 4 + .../gitlab/import_export/safe_model_attributes.yml | 4 + spec/lib/gitlab/issuable_metadata_spec.rb | 4 +- spec/mailers/notify_spec.rb | 18 +-- spec/models/ci/pipeline_spec.rb | 8 +- spec/models/concerns/deprecated_assignee_spec.rb | 160 +++++++++++++++++++++ spec/models/concerns/issuable_spec.rb | 7 +- spec/models/event_spec.rb | 2 +- spec/models/merge_request_spec.rb | 60 ++------ spec/models/user_spec.rb | 6 +- spec/requests/api/events_spec.rb | 4 +- spec/requests/api/merge_requests_spec.rb | 124 +++++++++++++--- spec/services/issuable/bulk_update_service_spec.rb | 16 +-- spec/services/issuable/destroy_service_spec.rb | 2 +- spec/services/members/destroy_service_spec.rb | 4 +- spec/services/merge_requests/close_service_spec.rb | 2 +- .../create_from_issue_service_spec.rb | 2 +- .../services/merge_requests/create_service_spec.rb | 30 ++-- .../merge_requests/ff_merge_service_spec.rb | 2 +- spec/services/merge_requests/merge_service_spec.rb | 4 +- .../merge_requests/merge_to_ref_service_spec.rb | 2 +- .../merge_requests/post_merge_service_spec.rb | 2 +- .../services/merge_requests/reopen_service_spec.rb | 2 +- .../services/merge_requests/update_service_spec.rb | 42 +++--- spec/services/notification_service_spec.rb | 55 +++---- .../quick_actions/interpret_service_spec.rb | 4 +- spec/services/system_note_service_spec.rb | 6 +- spec/services/todo_service_spec.rb | 110 +++++++------- spec/services/users/destroy_service_spec.rb | 4 +- .../merge_requests_finder_shared_contexts.rb | 6 +- .../shared_contexts/merge_request_create.rb | 26 ++++ spec/support/shared_contexts/merge_request_edit.rb | 28 ++++ .../creatable_merge_request_shared_examples.rb | 31 +--- .../editable_merge_request_shared_examples.rb | 28 +--- .../multiple_assignees_mr_shared_examples.rb | 47 ++++++ .../finders/assignees_filter_spec.rb | 49 +++++++ .../projects/merge_requests/edit.html.haml_spec.rb | 6 +- .../projects/merge_requests/show.html.haml_spec.rb | 13 -- 127 files changed, 1189 insertions(+), 817 deletions(-) create mode 100644 app/models/concerns/deprecated_assignee.rb create mode 100644 app/serializers/merge_request_assignee_entity.rb delete mode 100644 app/serializers/merge_request_sidebar_basic_entity.rb create mode 100644 app/serializers/merge_request_sidebar_extras_entity.rb create mode 100644 app/views/notify/_reassigned_issuable_email.html.haml delete mode 100644 app/views/shared/issuable/form/_merge_request_assignee.html.haml create mode 100644 app/views/shared/issuable/form/_metadata_issuable_assignee.html.haml delete mode 100644 app/views/shared/issuable/form/_metadata_issue_assignee.html.haml create mode 100644 spec/models/concerns/deprecated_assignee_spec.rb create mode 100644 spec/support/shared_contexts/merge_request_create.rb create mode 100644 spec/support/shared_contexts/merge_request_edit.rb create mode 100644 spec/support/shared_examples/features/multiple_assignees_mr_shared_examples.rb create mode 100644 spec/support/shared_examples/finders/assignees_filter_spec.rb diff --git a/app/assets/javascripts/issuable_bulk_update_actions.js b/app/assets/javascripts/issuable_bulk_update_actions.js index b844e4c5e5b..ccbe591a63e 100644 --- a/app/assets/javascripts/issuable_bulk_update_actions.js +++ b/app/assets/javascripts/issuable_bulk_update_actions.js @@ -81,9 +81,6 @@ export default { const formData = { update: { state_event: this.form.find('input[name="update[state_event]"]').val(), - // For Merge Requests - assignee_id: this.form.find('input[name="update[assignee_id]"]').val(), - // For Issues assignee_ids: [this.form.find('input[name="update[assignee_ids][]"]').val()], milestone_id: this.form.find('input[name="update[milestone_id]"]').val(), issuable_ids: this.form.find('input[name="update[issuable_ids]"]').val(), diff --git a/app/assets/javascripts/sidebar/components/assignees/assignees.vue b/app/assets/javascripts/sidebar/components/assignees/assignees.vue index d1a396182b3..ce378e24289 100644 --- a/app/assets/javascripts/sidebar/components/assignees/assignees.vue +++ b/app/assets/javascripts/sidebar/components/assignees/assignees.vue @@ -74,8 +74,7 @@ export default { } if (!this.users.length) { - const emptyTooltipLabel = - this.issuableType === 'issue' ? __('Assignee(s)') : __('Assignee'); + const emptyTooltipLabel = __('Assignee(s)'); names.push(emptyTooltipLabel); } @@ -90,6 +89,27 @@ export default { return counter; }, + mergeNotAllowedTooltipMessage() { + const assigneesCount = this.users.length; + + if (this.issuableType !== 'merge_request' || assigneesCount === 0) { + return null; + } + + const cannotMergeCount = this.users.filter(u => u.can_merge === false).length; + const canMergeCount = assigneesCount - cannotMergeCount; + + if (canMergeCount === assigneesCount) { + // Everyone can merge + return null; + } else if (cannotMergeCount === assigneesCount && assigneesCount > 1) { + return 'No one can merge'; + } else if (assigneesCount === 1) { + return 'Cannot merge'; + } + + return `${canMergeCount}/${assigneesCount} can merge`; + }, }, methods: { assignSelf() { @@ -154,6 +174,15 @@ export default {
+ + +