diff options
author | Sean McGivern <sean@mcgivern.me.uk> | 2018-04-06 09:20:01 +0000 |
---|---|---|
committer | Sean McGivern <sean@mcgivern.me.uk> | 2018-04-06 09:20:01 +0000 |
commit | ca330f7ea30b368b928f5468a1f53264d74aa8aa (patch) | |
tree | a36320f6e8c4d7e1863e7b9f9c33c45ab5c4e99b /app | |
parent | 20e9b32c96a5b08e3f61c8974b43977f98d8666e (diff) | |
parent | 696daa7ef1d784dfd1521bd5b5cc2cc18d89e96e (diff) | |
download | gitlab-ce-ca330f7ea30b368b928f5468a1f53264d74aa8aa.tar.gz |
Merge branch 'issue_44270' into 'master'
Show issues of subgroups in group-level issue board
Closes #44270
See merge request gitlab-org/gitlab-ce!18187
Diffstat (limited to 'app')
17 files changed, 36 insertions, 41 deletions
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js index a44969272a1..c4ee4f6c855 100644 --- a/app/assets/javascripts/boards/components/board_sidebar.js +++ b/app/assets/javascripts/boards/components/board_sidebar.js @@ -60,10 +60,6 @@ gl.issueBoards.BoardSidebar = Vue.extend({ this.issue = this.detail.issue; this.list = this.detail.list; - - this.$nextTick(() => { - this.endpoint = this.$refs.assigneeDropdown.dataset.issueUpdate; - }); }, deep: true }, @@ -91,7 +87,7 @@ gl.issueBoards.BoardSidebar = Vue.extend({ saveAssignees () { this.loadingAssignees = true; - gl.issueBoards.BoardsStore.detail.issue.update(this.endpoint) + gl.issueBoards.BoardsStore.detail.issue.update() .then(() => { this.loadingAssignees = false; }) diff --git a/app/assets/javascripts/boards/components/issue_card_inner.js b/app/assets/javascripts/boards/components/issue_card_inner.js index 8aee5b23c76..84fe9b1288a 100644 --- a/app/assets/javascripts/boards/components/issue_card_inner.js +++ b/app/assets/javascripts/boards/components/issue_card_inner.js @@ -68,15 +68,6 @@ gl.issueBoards.IssueCardInner = Vue.extend({ return this.issue.assignees.length > this.numberOverLimit; }, - cardUrl() { - let baseUrl = this.issueLinkBase; - - if (this.groupId && this.issue.project) { - baseUrl = this.issueLinkBase.replace(':project_path', this.issue.project.path); - } - - return `${baseUrl}/${this.issue.iid}`; - }, issueId() { if (this.issue.iid) { return `#${this.issue.iid}`; @@ -153,13 +144,13 @@ gl.issueBoards.IssueCardInner = Vue.extend({ /> <a class="js-no-trigger" - :href="cardUrl" + :href="issue.path" :title="issue.title">{{ issue.title }}</a> <span class="card-number" v-if="issueId" > - <template v-if="groupId && issue.project">{{issue.project.path}}</template>{{ issueId }} + {{ issue.referencePath }} </span> </h4> <div class="card-assignee"> diff --git a/app/assets/javascripts/boards/components/sidebar/remove_issue.js b/app/assets/javascripts/boards/components/sidebar/remove_issue.js index 09c683ff621..0a0820ec5fd 100644 --- a/app/assets/javascripts/boards/components/sidebar/remove_issue.js +++ b/app/assets/javascripts/boards/components/sidebar/remove_issue.js @@ -17,14 +17,10 @@ gl.issueBoards.RemoveIssueBtn = Vue.extend({ type: Object, required: true, }, - issueUpdate: { - type: String, - required: true, - }, }, computed: { updateUrl() { - return this.issueUpdate.replace(':project_path', this.issue.project.path); + return this.issue.path; }, }, methods: { diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js index fb40b9f5565..70367c4f711 100644 --- a/app/assets/javascripts/boards/filtered_search_boards.js +++ b/app/assets/javascripts/boards/filtered_search_boards.js @@ -6,6 +6,7 @@ export default class FilteredSearchBoards extends FilteredSearchManager { constructor(store, updateUrl = false, cantEdit = []) { super({ page: 'boards', + isGroupDecendent: true, stateFiltersSelector: '.issues-state-filters', }); diff --git a/app/assets/javascripts/boards/models/issue.js b/app/assets/javascripts/boards/models/issue.js index 4c5079efc8b..b381d48d625 100644 --- a/app/assets/javascripts/boards/models/issue.js +++ b/app/assets/javascripts/boards/models/issue.js @@ -23,6 +23,8 @@ class ListIssue { }; this.isLoading = {}; this.sidebarInfoEndpoint = obj.issue_sidebar_endpoint; + this.referencePath = obj.reference_path; + this.path = obj.real_path; this.toggleSubscriptionEndpoint = obj.toggle_subscription_endpoint; this.milestone_id = obj.milestone_id; this.project_id = obj.project_id; @@ -98,7 +100,7 @@ class ListIssue { this.isLoading[key] = value; } - update (url) { + update () { const data = { issue: { milestone_id: this.milestone ? this.milestone.id : null, @@ -113,7 +115,7 @@ class ListIssue { } const projectPath = this.project ? this.project.path : ''; - return Vue.http.patch(url.replace(':project_path', projectPath), data); + return Vue.http.patch(`${this.path}.json`, data); } } diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 19dbee84c11..7d7ff217e5d 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -96,7 +96,8 @@ module Boards resource.as_json( only: [:id, :iid, :project_id, :title, :confidential, :due_date, :relative_position], labels: true, - sidebar_endpoints: true, + issue_endpoints: true, + include_full_project_path: board.group_board?, include: { project: { only: [:id, :path] }, assignees: { only: [:id, :name, :username], methods: [:avatar_url] }, diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index acf6aaf57f4..5903689dc62 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -12,7 +12,7 @@ class Groups::MilestonesController < Groups::ApplicationController @milestones = Kaminari.paginate_array(milestones).page(params[:page]) end format.json do - render json: milestones.map { |m| m.for_display.slice(:title, :name) } + render json: milestones.map { |m| m.for_display.slice(:id, :title, :name) } end end end diff --git a/app/models/issue.rb b/app/models/issue.rb index 13abc6c1a0d..13d9e42bcc8 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -272,11 +272,17 @@ class Issue < ActiveRecord::Base def as_json(options = {}) super(options).tap do |json| - if options.key?(:sidebar_endpoints) && project + if options.key?(:issue_endpoints) && project url_helper = Gitlab::Routing.url_helpers - json.merge!(issue_sidebar_endpoint: url_helper.project_issue_path(project, self, format: :json, serializer: 'sidebar'), - toggle_subscription_endpoint: url_helper.toggle_subscription_project_issue_path(project, self)) + issue_reference = options[:include_full_project_path] ? to_reference(full: true) : to_reference + + json.merge!( + reference_path: issue_reference, + real_path: url_helper.project_issue_path(project, self), + issue_sidebar_endpoint: url_helper.project_issue_path(project, self, format: :json, serializer: 'sidebar'), + toggle_subscription_endpoint: url_helper.toggle_subscription_project_issue_path(project, self) + ) end if options.key?(:labels) diff --git a/app/models/milestone.rb b/app/models/milestone.rb index dafae58d121..a66a0015827 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -34,8 +34,8 @@ class Milestone < ActiveRecord::Base scope :for_projects_and_groups, -> (project_ids, group_ids) do conditions = [] - conditions << arel_table[:project_id].in(project_ids) if project_ids.compact.any? - conditions << arel_table[:group_id].in(group_ids) if group_ids.compact.any? + conditions << arel_table[:project_id].in(project_ids) if project_ids&.compact&.any? + conditions << arel_table[:group_id].in(group_ids) if group_ids&.compact&.any? where(conditions.reduce(:or)) end diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index ecd74b74f8a..ac70a99c2c5 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -35,6 +35,7 @@ module Boards def filter_params set_parent set_state + set_scope params end @@ -51,6 +52,10 @@ module Boards params[:state] = list && list.closed? ? 'closed' : 'opened' end + def set_scope + params[:include_subgroups] = board.group_board? + end + def board_label_ids @board_label_ids ||= board.lists.movable.pluck(:label_id) end diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index 91ec702fbc6..1f67e3ecf9d 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -51,9 +51,10 @@ class IssuableBaseService < BaseService return unless milestone_id params[:milestone_id] = '' if milestone_id == IssuableFinder::NONE + group_ids = project.group&.self_and_ancestors&.pluck(:id) milestone = - Milestone.for_projects_and_groups([project.id], [project.group&.id]).find_by_id(milestone_id) + Milestone.for_projects_and_groups([project.id], group_ids).find_by_id(milestone_id) params[:milestone_id] = '' unless milestone end diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index 4161932ad2a..1374f10c586 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -90,7 +90,7 @@ module Issues issue = if board_group_id - IssuesFinder.new(current_user, group_id: board_group_id).find_by(id: id) + IssuesFinder.new(current_user, group_id: board_group_id, include_subgroups: true).find_by(id: id) else project.issues.find(id) end diff --git a/app/views/shared/boards/components/_sidebar.html.haml b/app/views/shared/boards/components/_sidebar.html.haml index 8e5e32e9f16..b385cc3f962 100644 --- a/app/views/shared/boards/components/_sidebar.html.haml +++ b/app/views/shared/boards/components/_sidebar.html.haml @@ -22,6 +22,6 @@ = render "shared/boards/components/sidebar/labels" = render "shared/boards/components/sidebar/notifications" %remove-btn{ ":issue" => "issue", - ":issue-update" => "'#{build_issue_link_base}/' + issue.iid + '.json'", + ":issue-update" => "issue.sidebarInfoEndpoint", ":list" => "list", "v-if" => "canRemove" } diff --git a/app/views/shared/boards/components/sidebar/_assignee.html.haml b/app/views/shared/boards/components/sidebar/_assignee.html.haml index 3d2e8471a60..1374da9d82c 100644 --- a/app/views/shared/boards/components/sidebar/_assignee.html.haml +++ b/app/views/shared/boards/components/sidebar/_assignee.html.haml @@ -21,8 +21,7 @@ .dropdown - dropdown_options = issue_assignees_dropdown_options %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: board_sidebar_user_data, - ":data-issuable-id" => "issue.iid", - ":data-issue-update" => "'#{build_issue_link_base}/' + issue.iid + '.json'" } + ":data-issuable-id" => "issue.iid" } = dropdown_options[:title] = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-user.dropdown-menu-selectable.dropdown-menu-author diff --git a/app/views/shared/boards/components/sidebar/_due_date.html.haml b/app/views/shared/boards/components/sidebar/_due_date.html.haml index db794d6f855..d13b998e6f4 100644 --- a/app/views/shared/boards/components/sidebar/_due_date.html.haml +++ b/app/views/shared/boards/components/sidebar/_due_date.html.haml @@ -22,8 +22,7 @@ ":value" => "issue.dueDate" } .dropdown %button.dropdown-menu-toggle.js-due-date-select.js-issue-boards-due-date{ type: 'button', - data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue" }, - ":data-issue-update" => "'#{build_issue_link_base}/' + issue.iid + '.json'" } + data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue" } } %span.dropdown-toggle-text Due date = icon('chevron-down') .dropdown-menu.dropdown-menu-due-date diff --git a/app/views/shared/boards/components/sidebar/_labels.html.haml b/app/views/shared/boards/components/sidebar/_labels.html.haml index dfc0f9be321..87e6b52f46e 100644 --- a/app/views/shared/boards/components/sidebar/_labels.html.haml +++ b/app/views/shared/boards/components/sidebar/_labels.html.haml @@ -26,8 +26,7 @@ project_id: @project&.try(:id), labels: labels_filter_path(false), namespace_path: @namespace_path, - project_path: @project.try(:path) }, - ":data-issue-update" => "'#{build_issue_link_base}/' + issue.iid + '.json'" } + project_path: @project.try(:path) } } %span.dropdown-toggle-text Label = icon('chevron-down') diff --git a/app/views/shared/boards/components/sidebar/_milestone.html.haml b/app/views/shared/boards/components/sidebar/_milestone.html.haml index d09c7c218e0..f51c4a97f2b 100644 --- a/app/views/shared/boards/components/sidebar/_milestone.html.haml +++ b/app/views/shared/boards/components/sidebar/_milestone.html.haml @@ -18,8 +18,7 @@ .dropdown %button.dropdown-menu-toggle.js-milestone-select.js-issue-board-sidebar{ type: "button", data: { toggle: "dropdown", show_no: "true", field_name: "issue[milestone_id]", milestones: milestones_filter_path(format: :json), ability_name: "issue", use_id: "true", default_no: "true" }, ":data-selected" => "milestoneTitle", - ":data-issuable-id" => "issue.iid", - ":data-issue-update" => "'#{build_issue_link_base}/' + issue.iid + '.json'" } + ":data-issuable-id" => "issue.iid" } Milestone = icon("chevron-down") .dropdown-menu.dropdown-select.dropdown-menu-selectable |