Commit 6c79e930 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu Committed by Heinrich Lee Yu

Refactor issuable sidebar to have extras option

parent 1f7c072e
...@@ -71,7 +71,7 @@ export default class SidebarStore { ...@@ -71,7 +71,7 @@ export default class SidebarStore {
} }
findAssignee(findAssignee) { findAssignee(findAssignee) {
return this.assignees.filter(assignee => assignee.id === findAssignee.id)[0]; return this.assignees.find(assignee => assignee.id === findAssignee.id);
} }
removeAssignee(removeAssignee) { removeAssignee(removeAssignee) {
......
...@@ -50,13 +50,13 @@ module IssuablesHelper ...@@ -50,13 +50,13 @@ module IssuablesHelper
end end
end end
def issuable_json_path(issuable) def issuable_json_path(issuable, url_params = {})
project = issuable.project project = issuable.project
if issuable.is_a?(MergeRequest) if issuable.is_a?(MergeRequest)
project_merge_request_path(project, issuable.iid, :json) project_merge_request_path(project, issuable.iid, :json, url_params)
else else
project_issue_path(project, issuable.iid, :json) project_issue_path(project, issuable.iid, :json, url_params)
end end
end end
...@@ -420,7 +420,7 @@ module IssuablesHelper ...@@ -420,7 +420,7 @@ module IssuablesHelper
def issuable_sidebar_options(issuable, can_edit_issuable) def issuable_sidebar_options(issuable, can_edit_issuable)
{ {
endpoint: "#{issuable_json_path(issuable)}?serializer=sidebar", endpoint: issuable_json_path(issuable, serializer: 'sidebar_extras'),
toggleSubscriptionEndpoint: toggle_subscription_path(issuable), toggleSubscriptionEndpoint: toggle_subscription_path(issuable),
moveIssueEndpoint: move_namespace_project_issue_path(namespace_id: issuable.project.namespace.to_param, project_id: issuable.project, id: issuable), moveIssueEndpoint: move_namespace_project_issue_path(namespace_id: issuable.project.namespace.to_param, project_id: issuable.project, id: issuable),
projectsAutocompleteEndpoint: autocomplete_projects_path(project_id: @project.id), projectsAutocompleteEndpoint: autocomplete_projects_path(project_id: @project.id),
......
# frozen_string_literal: true # frozen_string_literal: true
class IssuableSidebarEntity < Grape::Entity class IssuableSidebarEntity < Grape::Entity
include TimeTrackableEntity
include RequestAwareEntity include RequestAwareEntity
expose :participants, using: ::API::Entities::UserBasic do |issuable| with_options if: { include_extras: true } do
issuable.participants(request.current_user) include TimeTrackableEntity
end
expose :participants, using: ::API::Entities::UserBasic do |issuable|
issuable.participants(request.current_user)
end
expose :subscribed do |issuable| expose :subscribed do |issuable|
issuable.subscribed?(request.current_user, issuable.project) issuable.subscribed?(request.current_user, issuable.project)
end
end end
end end
...@@ -37,7 +37,7 @@ class IssueBoardEntity < Grape::Entity ...@@ -37,7 +37,7 @@ class IssueBoardEntity < Grape::Entity
end end
expose :issue_sidebar_endpoint, if: -> (issue) { issue.project } do |issue| expose :issue_sidebar_endpoint, if: -> (issue) { issue.project } do |issue|
project_issue_path(issue.project, issue, format: :json, serializer: 'sidebar') project_issue_path(issue.project, issue, format: :json, serializer: 'sidebar_extras')
end end
expose :toggle_subscription_endpoint, if: -> (issue) { issue.project } do |issue| expose :toggle_subscription_endpoint, if: -> (issue) { issue.project } do |issue|
......
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
class IssueSerializer < BaseSerializer class IssueSerializer < BaseSerializer
# This overrided method takes care of which entity should be used # This overrided method takes care of which entity should be used
# to serialize the `issue` based on `basic` key in `opts` param. # to serialize the `issue` based on `serializer` key in `opts` param.
# Hence, `entity` doesn't need to be declared on the class scope. # Hence, `entity` doesn't need to be declared on the class scope.
def represent(issue, opts = {}) def represent(issue, opts = {})
entity = entity =
case opts[:serializer] case opts[:serializer]
when 'sidebar' when 'sidebar_extras'
opts[:include_basic] = false
opts[:include_extras] = true
IssueSidebarEntity IssueSidebarEntity
when 'board' when 'board'
IssueBoardEntity IssueBoardEntity
......
# frozen_string_literal: true # frozen_string_literal: true
class IssueSidebarEntity < IssuableSidebarEntity class IssueSidebarEntity < IssuableSidebarEntity
expose :assignees, using: API::Entities::UserBasic with_options if: { include_extras: true } do
expose :assignees, using: API::Entities::UserBasic
end
end end
# frozen_string_literal: true # frozen_string_literal: true
class MergeRequestBasicEntity < IssuableSidebarEntity class MergeRequestBasicEntity < Grape::Entity
expose :assignee_id expose :assignee_id
expose :merge_status expose :merge_status
expose :merge_error expose :merge_error
......
# frozen_string_literal: true
class MergeRequestBasicSerializer < BaseSerializer
entity MergeRequestBasicEntity
end
...@@ -7,9 +7,14 @@ class MergeRequestSerializer < BaseSerializer ...@@ -7,9 +7,14 @@ class MergeRequestSerializer < BaseSerializer
def represent(merge_request, opts = {}) def represent(merge_request, opts = {})
entity = entity =
case opts[:serializer] case opts[:serializer]
when 'basic', 'sidebar' when 'sidebar_extras'
opts[:include_basic] = false
opts[:include_extras] = true
MergeRequestSidebarEntity
when 'basic'
MergeRequestBasicEntity MergeRequestBasicEntity
else # It's 'widget' else
# fallback to widget for old poll requests without `serializer` set
MergeRequestWidgetEntity MergeRequestWidgetEntity
end end
......
# frozen_string_literal: true
class MergeRequestSidebarEntity < IssuableSidebarEntity
end
- page_title "Merge Conflicts", "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
- content_for :page_specific_javascripts do
= page_specific_javascript_tag('lib/ace.js')
= render "projects/merge_requests/mr_title"
.merge-request-details.issuable-details
= render "projects/merge_requests/mr_box"
= render 'shared/issuable/sidebar', issuable: @merge_request
#conflicts{ "v-cloak" => "true", data: { conflicts_path: conflicts_project_merge_request_path(@merge_request.project, @merge_request, format: :json),
resolve_conflicts_path: resolve_conflicts_project_merge_request_path(@merge_request.project, @merge_request) } }
.loading{ "v-if" => "isLoading" }
%i.fa.fa-spinner.fa-spin
.nothing-here-block{ "v-if" => "hasError" }
{{conflictsData.errorMessage}}
= render partial: "projects/merge_requests/conflicts/commit_stats"
.files-wrapper{ "v-if" => "!isLoading && !hasError" }
.files
.diff-file.file-holder.conflict{ "v-for" => "file in conflictsData.files" }
.js-file-title.file-title
%i.fa.fa-fw{ ":class" => "file.iconClass" }
%strong {{file.filePath}}
= render partial: 'projects/merge_requests/conflicts/file_actions'
.diff-content.diff-wrap-lines
.diff-wrap-lines.code.file-content.js-syntax-highlight{ "v-show" => "!isParallel && file.resolveMode === 'interactive' && file.type === 'text'" }
= render partial: "projects/merge_requests/conflicts/components/inline_conflict_lines"
.diff-wrap-lines.code.file-content.js-syntax-highlight{ "v-show" => "isParallel && file.resolveMode === 'interactive' && file.type === 'text'" }
%parallel-conflict-lines{ ":file" => "file" }
%div{ "v-show" => "file.resolveMode === 'edit' || file.type === 'text-editor'" }
= render partial: "projects/merge_requests/conflicts/components/diff_file_editor"
= render partial: "projects/merge_requests/conflicts/submit_form"
...@@ -4,15 +4,9 @@ ...@@ -4,15 +4,9 @@
"state": { "type": "string" }, "state": { "type": "string" },
"merge_status": { "type": "string" }, "merge_status": { "type": "string" },
"source_branch_exists": { "type": "boolean" }, "source_branch_exists": { "type": "boolean" },
"time_estimate": { "type": "integer" },
"total_time_spent": { "type": "integer" },
"human_time_estimate": { "type": ["string", "null"] },
"human_total_time_spent": { "type": ["string", "null"] },
"merge_error": { "type": ["string", "null"] }, "merge_error": { "type": ["string", "null"] },
"rebase_in_progress": { "type": "boolean" }, "rebase_in_progress": { "type": "boolean" },
"assignee_id": { "type": ["integer", "null"] }, "assignee_id": { "type": ["integer", "null"] },
"subscribed": { "type": ["boolean", "null"] },
"participants": { "type": "array" },
"allow_collaboration": { "type": "boolean"}, "allow_collaboration": { "type": "boolean"},
"allow_maintainer_to_push": { "type": "boolean"}, "allow_maintainer_to_push": { "type": "boolean"},
"assignee": { "assignee": {
......
{
"type": "object",
"properties" : {
"id": { "type": "integer" },
"iid": { "type": "integer" },
"subscribed": { "type": "boolean" },
"time_estimate": { "type": "integer" },
"total_time_spent": { "type": "integer" },
"human_time_estimate": { "type": ["integer", "null"] },
"human_total_time_spent": { "type": ["integer", "null"] },
"participants": {
"type": "array",
"items": { "$ref": "../public_api/v4/user/basic.json" }
},
"assignees": {
"type": "array",
"items": { "$ref": "../public_api/v4/user/basic.json" }
}
},
"additionalProperties": false
}
...@@ -66,7 +66,7 @@ const RESPONSE_MAP = { ...@@ -66,7 +66,7 @@ const RESPONSE_MAP = {
}, },
labels: [], labels: [],
}, },
'/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar': { '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras': {
assignees: [ assignees: [
{ {
name: 'User 0', name: 'User 0',
...@@ -181,7 +181,7 @@ const RESPONSE_MAP = { ...@@ -181,7 +181,7 @@ const RESPONSE_MAP = {
const mockData = { const mockData = {
responseMap: RESPONSE_MAP, responseMap: RESPONSE_MAP,
mediator: { mediator: {
endpoint: '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar', endpoint: '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras',
toggleSubscriptionEndpoint: '/gitlab-org/gitlab-shell/issues/5/toggle_subscription', toggleSubscriptionEndpoint: '/gitlab-org/gitlab-shell/issues/5/toggle_subscription',
moveIssueEndpoint: '/gitlab-org/gitlab-shell/issues/5/move', moveIssueEndpoint: '/gitlab-org/gitlab-shell/issues/5/move',
projectsAutocompleteEndpoint: '/autocomplete/projects?project_id=15', projectsAutocompleteEndpoint: '/autocomplete/projects?project_id=15',
......
...@@ -37,7 +37,7 @@ describe('Sidebar mediator', function() { ...@@ -37,7 +37,7 @@ describe('Sidebar mediator', function() {
it('fetches the data', done => { it('fetches the data', done => {
const mockData = const mockData =
Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar']; Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras'];
spyOn(this.mediator, 'processFetchedData').and.callThrough(); spyOn(this.mediator, 'processFetchedData').and.callThrough();
this.mediator this.mediator
...@@ -51,7 +51,7 @@ describe('Sidebar mediator', function() { ...@@ -51,7 +51,7 @@ describe('Sidebar mediator', function() {
it('processes fetched data', () => { it('processes fetched data', () => {
const mockData = const mockData =
Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar']; Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras'];
this.mediator.processFetchedData(mockData); this.mediator.processFetchedData(mockData);
expect(this.mediator.store.assignees).toEqual(mockData.assignees); expect(this.mediator.store.assignees).toEqual(mockData.assignees);
......
...@@ -18,7 +18,7 @@ describe IssueSerializer do ...@@ -18,7 +18,7 @@ describe IssueSerializer do
end end
context 'sidebar issue serialization' do context 'sidebar issue serialization' do
let(:serializer) { 'sidebar' } let(:serializer) { 'sidebar_extras' }
it 'matches sidebar issue json schema' do it 'matches sidebar issue json schema' do
expect(json_entity).to match_schema('entities/issue_sidebar') expect(json_entity).to match_schema('entities/issue_sidebar')
......
require 'spec_helper'
describe MergeRequestBasicSerializer do
let(:resource) { create(:merge_request) }
let(:user) { create(:user) }
let(:json_entity) do
described_class.new(current_user: user)
.represent(resource, serializer: 'basic')
.with_indifferent_access
end
it 'matches basic merge request json' do
expect(json_entity).to match_schema('entities/merge_request_basic')
end
end
...@@ -18,10 +18,10 @@ describe MergeRequestSerializer do ...@@ -18,10 +18,10 @@ describe MergeRequestSerializer do
end end
context 'sidebar merge request serialization' do context 'sidebar merge request serialization' do
let(:serializer) { 'sidebar' } let(:serializer) { 'sidebar_extras' }
it 'matches basic merge request json schema' do it 'matches basic merge request json schema' do
expect(json_entity).to match_schema('entities/merge_request_basic') expect(json_entity).to match_schema('entities/merge_request_sidebar')
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment