Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
gpt
large_projects
gitlabhq1
Commits
6dc9028f
Commit
6dc9028f
authored
7 years ago
by
Eric Eastwood
Committed by
Phil Hughes
7 years ago
Browse files
Options
Download
Email Patches
Plain Diff
Load participants async
parent
74a0e855
Changes
45
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
397 additions
and
50 deletions
+397
-50
app/assets/javascripts/issuable_context.js
app/assets/javascripts/issuable_context.js
+0
-28
app/assets/javascripts/sidebar/components/participants/participants.vue
...ascripts/sidebar/components/participants/participants.vue
+125
-0
app/assets/javascripts/sidebar/components/participants/sidebar_participants.vue
.../sidebar/components/participants/sidebar_participants.vue
+26
-0
app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue
...idebar/components/subscriptions/sidebar_subscriptions.vue
+45
-0
app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
...cripts/sidebar/components/subscriptions/subscriptions.vue
+60
-0
app/assets/javascripts/sidebar/services/sidebar_service.js
app/assets/javascripts/sidebar/services/sidebar_service.js
+5
-0
app/assets/javascripts/sidebar/sidebar_bundle.js
app/assets/javascripts/sidebar/sidebar_bundle.js
+34
-0
app/assets/javascripts/sidebar/sidebar_mediator.js
app/assets/javascripts/sidebar/sidebar_mediator.js
+16
-0
app/assets/javascripts/sidebar/stores/sidebar_store.js
app/assets/javascripts/sidebar/stores/sidebar_store.js
+22
-0
app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
...ts/vue_merge_request_widget/services/mr_widget_service.js
+1
-1
app/assets/stylesheets/pages/issuable.scss
app/assets/stylesheets/pages/issuable.scss
+4
-2
app/controllers/projects/issues_controller.rb
app/controllers/projects/issues_controller.rb
+1
-1
app/controllers/projects/merge_requests_controller.rb
app/controllers/projects/merge_requests_controller.rb
+1
-1
app/helpers/issuables_helper.rb
app/helpers/issuables_helper.rb
+13
-10
app/models/concerns/subscribable.rb
app/models/concerns/subscribable.rb
+2
-0
app/serializers/issuable_sidebar_entity.rb
app/serializers/issuable_sidebar_entity.rb
+16
-0
app/serializers/issue_serializer.rb
app/serializers/issue_serializer.rb
+14
-1
app/serializers/issue_sidebar_entity.rb
app/serializers/issue_sidebar_entity.rb
+3
-0
app/serializers/merge_request_basic_entity.rb
app/serializers/merge_request_basic_entity.rb
+1
-5
app/serializers/merge_request_serializer.rb
app/serializers/merge_request_serializer.rb
+8
-1
No files found.
app/assets/javascripts/issuable_context.js
View file @
6dc9028f
...
...
@@ -2,11 +2,8 @@ import Cookies from 'js-cookie';
import
bp
from
'
./breakpoints
'
;
import
UsersSelect
from
'
./users_select
'
;
const
PARTICIPANTS_ROW_COUNT
=
7
;
export
default
class
IssuableContext
{
constructor
(
currentUser
)
{
this
.
initParticipants
();
this
.
userSelect
=
new
UsersSelect
(
currentUser
);
$
(
'
select.select2
'
).
select2
({
...
...
@@ -51,29 +48,4 @@ export default class IssuableContext {
}
});
}
initParticipants
()
{
$
(
document
).
on
(
'
click
'
,
'
.js-participants-more
'
,
this
.
toggleHiddenParticipants
);
return
$
(
'
.js-participants-author
'
).
each
(
function
forEachAuthor
(
i
)
{
if
(
i
>=
PARTICIPANTS_ROW_COUNT
)
{
$
(
this
).
addClass
(
'
js-participants-hidden
'
).
hide
();
}
});
}
toggleHiddenParticipants
()
{
const
currentText
=
$
(
this
).
text
().
trim
();
const
lessText
=
$
(
this
).
data
(
'
less-text
'
);
const
originalText
=
$
(
this
).
data
(
'
original-text
'
);
if
(
currentText
===
originalText
)
{
$
(
this
).
text
(
lessText
);
if
(
gl
.
lazyLoader
)
gl
.
lazyLoader
.
loadCheck
();
}
else
{
$
(
this
).
text
(
originalText
);
}
$
(
'
.js-participants-hidden
'
).
toggle
();
}
}
This diff is collapsed.
Click to expand it.
app/assets/javascripts/sidebar/components/participants/participants.vue
0 → 100644
View file @
6dc9028f
<
script
>
import
{
__
,
n__
,
sprintf
}
from
'
../../../locale
'
;
import
loadingIcon
from
'
../../../vue_shared/components/loading_icon.vue
'
;
import
userAvatarImage
from
'
../../../vue_shared/components/user_avatar/user_avatar_image.vue
'
;
export
default
{
props
:
{
loading
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
participants
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
numberOfLessParticipants
:
{
type
:
Number
,
required
:
false
,
default
:
7
,
},
},
data
()
{
return
{
isShowingMoreParticipants
:
false
,
};
},
components
:
{
loadingIcon
,
userAvatarImage
,
},
computed
:
{
lessParticipants
()
{
return
this
.
participants
.
slice
(
0
,
this
.
numberOfLessParticipants
);
},
visibleParticipants
()
{
return
this
.
isShowingMoreParticipants
?
this
.
participants
:
this
.
lessParticipants
;
},
hasMoreParticipants
()
{
return
this
.
participants
.
length
>
this
.
numberOfLessParticipants
;
},
toggleLabel
()
{
let
label
=
''
;
if
(
this
.
isShowingMoreParticipants
)
{
label
=
__
(
'
- show less
'
);
}
else
{
label
=
sprintf
(
__
(
'
+ %{moreCount} more
'
),
{
moreCount
:
this
.
participants
.
length
-
this
.
numberOfLessParticipants
,
});
}
return
label
;
},
participantLabel
()
{
return
sprintf
(
n__
(
'
%{count} participant
'
,
'
%{count} participants
'
,
this
.
participants
.
length
),
{
count
:
this
.
loading
?
''
:
this
.
participantCount
},
);
},
participantCount
()
{
return
this
.
participants
.
length
;
},
},
methods
:
{
toggleMoreParticipants
()
{
this
.
isShowingMoreParticipants
=
!
this
.
isShowingMoreParticipants
;
},
},
};
</
script
>
<
template
>
<div>
<div
class=
"sidebar-collapsed-icon"
>
<i
class=
"fa fa-users"
aria-hidden=
"true"
>
</i>
<loading-icon
v-if=
"loading"
class=
"js-participants-collapsed-loading-icon"
/>
<span
v-else
class=
"js-participants-collapsed-count"
>
{{
participantCount
}}
</span>
</div>
<div
class=
"title hide-collapsed"
>
<loading-icon
v-if=
"loading"
:inline=
"true"
class=
"js-participants-expanded-loading-icon"
/>
{{
participantLabel
}}
</div>
<div
class=
"participants-list hide-collapsed"
>
<div
v-for=
"participant in visibleParticipants"
:key=
"participant.id"
class=
"participants-author js-participants-author"
>
<a
class=
"author_link"
:href=
"participant.web_url"
>
<user-avatar-image
:lazy=
"true"
:img-src=
"participant.avatar_url"
css-classes=
"avatar-inline"
:size=
"24"
:tooltip-text=
"participant.name"
tooltip-placement=
"bottom"
/>
</a>
</div>
</div>
<div
v-if=
"hasMoreParticipants"
class=
"participants-more hide-collapsed"
>
<button
type=
"button"
class=
"btn-transparent btn-blank js-toggle-participants-button"
@
click=
"toggleMoreParticipants"
>
{{
toggleLabel
}}
</button>
</div>
</div>
</
template
>
This diff is collapsed.
Click to expand it.
app/assets/javascripts/sidebar/components/participants/sidebar_participants.vue
0 → 100644
View file @
6dc9028f
<
script
>
import
Store
from
'
../../stores/sidebar_store
'
;
import
Mediator
from
'
../../sidebar_mediator
'
;
import
participants
from
'
./participants.vue
'
;
export
default
{
data
()
{
return
{
mediator
:
new
Mediator
(),
store
:
new
Store
(),
};
},
components
:
{
participants
,
},
};
</
script
>
<
template
>
<div
class=
"block participants"
>
<participants
:loading=
"store.isFetching.participants"
:participants=
"store.participants"
:number-of-less-participants=
"7"
/>
</div>
</
template
>
This diff is collapsed.
Click to expand it.
app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions.vue
0 → 100644
View file @
6dc9028f
<
script
>
import
Store
from
'
../../stores/sidebar_store
'
;
import
Mediator
from
'
../../sidebar_mediator
'
;
import
eventHub
from
'
../../event_hub
'
;
import
Flash
from
'
../../../flash
'
;
import
subscriptions
from
'
./subscriptions.vue
'
;
export
default
{
data
()
{
return
{
mediator
:
new
Mediator
(),
store
:
new
Store
(),
};
},
components
:
{
subscriptions
,
},
methods
:
{
onToggleSubscription
()
{
this
.
mediator
.
toggleSubscription
()
.
catch
(()
=>
{
Flash
(
'
Error occurred when toggling the notification subscription
'
);
});
},
},
created
()
{
eventHub
.
$on
(
'
toggleSubscription
'
,
this
.
onToggleSubscription
);
},
beforeDestroy
()
{
eventHub
.
$off
(
'
toggleSubscription
'
,
this
.
onToggleSubscription
);
},
};
</
script
>
<
template
>
<div
class=
"block subscriptions"
>
<subscriptions
:loading=
"store.isFetching.subscriptions"
:subscribed=
"store.subscribed"
/>
</div>
</
template
>
This diff is collapsed.
Click to expand it.
app/assets/javascripts/sidebar/components/subscriptions/subscriptions.vue
0 → 100644
View file @
6dc9028f
<
script
>
import
{
__
}
from
'
../../../locale
'
;
import
eventHub
from
'
../../event_hub
'
;
import
loadingButton
from
'
../../../vue_shared/components/loading_button.vue
'
;
export
default
{
props
:
{
loading
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
subscribed
:
{
type
:
Boolean
,
required
:
false
,
},
},
components
:
{
loadingButton
,
},
computed
:
{
buttonLabel
()
{
let
label
;
if
(
this
.
subscribed
===
false
)
{
label
=
__
(
'
Subscribe
'
);
}
else
if
(
this
.
subscribed
===
true
)
{
label
=
__
(
'
Unsubscribe
'
);
}
return
label
;
},
},
methods
:
{
toggleSubscription
()
{
eventHub
.
$emit
(
'
toggleSubscription
'
);
},
},
};
</
script
>
<
template
>
<div>
<div
class=
"sidebar-collapsed-icon"
>
<i
class=
"fa fa-rss"
aria-hidden=
"true"
>
</i>
</div>
<span
class=
"issuable-header-text hide-collapsed pull-left"
>
{{
__
(
'
Notifications
'
)
}}
</span>
<loading-button
ref=
"loadingButton"
class=
"btn btn-default pull-right hide-collapsed js-issuable-subscribe-button"
:loading=
"loading"
:label=
"buttonLabel"
@
click=
"toggleSubscription"
/>
</div>
</
template
>
This diff is collapsed.
Click to expand it.
app/assets/javascripts/sidebar/services/sidebar_service.js
View file @
6dc9028f
...
...
@@ -7,6 +7,7 @@ export default class SidebarService {
constructor
(
endpointMap
)
{
if
(
!
SidebarService
.
singleton
)
{
this
.
endpoint
=
endpointMap
.
endpoint
;
this
.
toggleSubscriptionEndpoint
=
endpointMap
.
toggleSubscriptionEndpoint
;
this
.
moveIssueEndpoint
=
endpointMap
.
moveIssueEndpoint
;
this
.
projectsAutocompleteEndpoint
=
endpointMap
.
projectsAutocompleteEndpoint
;
...
...
@@ -36,6 +37,10 @@ export default class SidebarService {
});
}
toggleSubscription
()
{
return
Vue
.
http
.
post
(
this
.
toggleSubscriptionEndpoint
);
}
moveIssue
(
moveToProjectId
)
{
return
Vue
.
http
.
post
(
this
.
moveIssueEndpoint
,
{
move_to_project_id
:
moveToProjectId
,
...
...
This diff is collapsed.
Click to expand it.
app/assets/javascripts/sidebar/sidebar_bundle.js
View file @
6dc9028f
...
...
@@ -4,6 +4,8 @@ import SidebarAssignees from './components/assignees/sidebar_assignees';
import
ConfidentialIssueSidebar
from
'
./components/confidential/confidential_issue_sidebar.vue
'
;
import
SidebarMoveIssue
from
'
./lib/sidebar_move_issue
'
;
import
LockIssueSidebar
from
'
./components/lock/lock_issue_sidebar.vue
'
;
import
sidebarParticipants
from
'
./components/participants/sidebar_participants.vue
'
;
import
sidebarSubscriptions
from
'
./components/subscriptions/sidebar_subscriptions.vue
'
;
import
Translate
from
'
../vue_shared/translate
'
;
import
Mediator
from
'
./sidebar_mediator
'
;
...
...
@@ -49,6 +51,36 @@ function mountLockComponent(mediator) {
}).
$mount
(
el
);
}
function
mountParticipantsComponent
()
{
const
el
=
document
.
querySelector
(
'
.js-sidebar-participants-entry-point
'
);
if
(
!
el
)
return
;
// eslint-disable-next-line no-new
new
Vue
({
el
,
components
:
{
sidebarParticipants
,
},
render
:
createElement
=>
createElement
(
'
sidebar-participants
'
,
{}),
});
}
function
mountSubscriptionsComponent
()
{
const
el
=
document
.
querySelector
(
'
.js-sidebar-subscriptions-entry-point
'
);
if
(
!
el
)
return
;
// eslint-disable-next-line no-new
new
Vue
({
el
,
components
:
{
sidebarSubscriptions
,
},
render
:
createElement
=>
createElement
(
'
sidebar-subscriptions
'
,
{}),
});
}
function
domContentLoaded
()
{
const
sidebarOptions
=
JSON
.
parse
(
document
.
querySelector
(
'
.js-sidebar-options
'
).
innerHTML
);
const
mediator
=
new
Mediator
(
sidebarOptions
);
...
...
@@ -63,6 +95,8 @@ function domContentLoaded() {
mountConfidentialComponent
(
mediator
);
mountLockComponent
(
mediator
);
mountParticipantsComponent
();
mountSubscriptionsComponent
();
new
SidebarMoveIssue
(
mediator
,
...
...
This diff is collapsed.
Click to expand it.
app/assets/javascripts/sidebar/sidebar_mediator.js
View file @
6dc9028f
...
...
@@ -8,6 +8,7 @@ export default class SidebarMediator {
this
.
store
=
new
Store
(
options
);
this
.
service
=
new
Service
({
endpoint
:
options
.
endpoint
,
toggleSubscriptionEndpoint
:
options
.
toggleSubscriptionEndpoint
,
moveIssueEndpoint
:
options
.
moveIssueEndpoint
,
projectsAutocompleteEndpoint
:
options
.
projectsAutocompleteEndpoint
,
});
...
...
@@ -39,10 +40,25 @@ export default class SidebarMediator {
.
then
((
data
)
=>
{
this
.
store
.
setAssigneeData
(
data
);
this
.
store
.
setTimeTrackingData
(
data
);
this
.
store
.
setParticipantsData
(
data
);
this
.
store
.
setSubscriptionsData
(
data
);
})
.
catch
(()
=>
new
Flash
(
'
Error occurred when fetching sidebar data
'
));
}
toggleSubscription
()
{
this
.
store
.
setFetchingState
(
'
subscriptions
'
,
true
);
return
this
.
service
.
toggleSubscription
()
.
then
(()
=>
{
this
.
store
.
setSubscribedState
(
!
this
.
store
.
subscribed
);
this
.
store
.
setFetchingState
(
'
subscriptions
'
,
false
);
})
.
catch
((
err
)
=>
{
this
.
store
.
setFetchingState
(
'
subscriptions
'
,
false
);
throw
err
;
});
}
fetchAutocompleteProjects
(
searchTerm
)
{
return
this
.
service
.
getProjectsAutocomplete
(
searchTerm
)
.
then
(
response
=>
response
.
json
())
...
...
This diff is collapsed.
Click to expand it.
app/assets/javascripts/sidebar/stores/sidebar_store.js
View file @
6dc9028f
...
...
@@ -12,10 +12,14 @@ export default class SidebarStore {
this
.
assignees
=
[];
this
.
isFetching
=
{
assignees
:
true
,
participants
:
true
,
subscriptions
:
true
,
};
this
.
autocompleteProjects
=
[];
this
.
moveToProjectId
=
0
;
this
.
isLockDialogOpen
=
false
;
this
.
participants
=
[];
this
.
subscribed
=
null
;
SidebarStore
.
singleton
=
this
;
}
...
...
@@ -37,6 +41,20 @@ export default class SidebarStore {
this
.
humanTotalTimeSpent
=
data
.
human_total_time_spent
;
}
setParticipantsData
(
data
)
{
this
.
isFetching
.
participants
=
false
;
this
.
participants
=
data
.
participants
||
[];
}
setSubscriptionsData
(
data
)
{
this
.
isFetching
.
subscriptions
=
false
;
this
.
subscribed
=
data
.
subscribed
||
false
;
}
setFetchingState
(
key
,
value
)
{
this
.
isFetching
[
key
]
=
value
;
}
addAssignee
(
assignee
)
{
if
(
!
this
.
findAssignee
(
assignee
))
{
this
.
assignees
.
push
(
assignee
);
...
...
@@ -61,6 +79,10 @@ export default class SidebarStore {
this
.
autocompleteProjects
=
projects
;
}
setSubscribedState
(
subscribed
)
{
this
.
subscribed
=
subscribed
;
}
setMoveToProjectId
(
moveToProjectId
)
{
this
.
moveToProjectId
=
moveToProjectId
;
}
...
...
This diff is collapsed.
Click to expand it.
app/assets/javascripts/vue_merge_request_widget/services/mr_widget_service.js
View file @
6dc9028f
...
...
@@ -11,7 +11,7 @@ export default class MRWidgetService {
this
.
removeWIPResource
=
Vue
.
resource
(
endpoints
.
removeWIPPath
);
this
.
removeSourceBranchResource
=
Vue
.
resource
(
endpoints
.
sourceBranchPath
);
this
.
deploymentsResource
=
Vue
.
resource
(
endpoints
.
ciEnvironmentsStatusPath
);
this
.
pollResource
=
Vue
.
resource
(
`
${
endpoints
.
statusPath
}
?basic
=true
`
);
this
.
pollResource
=
Vue
.
resource
(
`
${
endpoints
.
statusPath
}
?
serializer=
basic`
);
this
.
mergeActionsContentResource
=
Vue
.
resource
(
endpoints
.
mergeActionsContentPath
);
}
...
...
This diff is collapsed.
Click to expand it.
app/assets/stylesheets/pages/issuable.scss
View file @
6dc9028f
...
...
@@ -542,7 +542,9 @@
}
.participants-list
{
margin
:
-5px
;
display
:
flex
;
flex-wrap
:
wrap
;
margin
:
-7px
;
}
...
...
@@ -553,7 +555,7 @@
.participants-author
{
display
:
inline-block
;
padding
:
5
px
;
padding
:
7
px
;
&
:nth-of-type
(
7n
)
{
padding-right
:
0
;
...
...
This diff is collapsed.
Click to expand it.
app/controllers/projects/issues_controller.rb
View file @
6dc9028f
...
...
@@ -74,7 +74,7 @@ class Projects::IssuesController < Projects::ApplicationController
respond_to
do
|
format
|
format
.
html
format
.
json
do
render
json:
serializer
.
represent
(
@issue
)
render
json:
serializer
.
represent
(
@issue
,
serializer:
params
[
:serializer
]
)
end
end
end
...
...
This diff is collapsed.
Click to expand it.
app/controllers/projects/merge_requests_controller.rb
View file @
6dc9028f
...
...
@@ -83,7 +83,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
format
.
json
do
Gitlab
::
PollingInterval
.
set_header
(
response
,
interval:
10_000
)
render
json:
serializer
.
represent
(
@merge_request
,
basic:
params
[
:basic
])
render
json:
serializer
.
represent
(
@merge_request
,
serializer:
params
[
:serializer
])
end
format
.
patch
do
...
...
This diff is collapsed.
Click to expand it.
app/helpers/issuables_helper.rb
View file @
6dc9028f
...
...
@@ -33,15 +33,17 @@ module IssuablesHelper
end
def
serialize_issuable
(
issuable
)
case
issuable
when
Issue
IssueSerializer
.
new
(
current_user:
current_user
,
project:
issuable
.
project
).
represent
(
issuable
).
to_json
when
MergeRequest
MergeRequestSerializer
.
new
(
current_user:
current_user
,
project:
issuable
.
project
)
.
represent
(
issuable
)
.
to_json
end
serializer_klass
=
case
issuable
when
Issue
IssueSerializer
when
MergeRequest
MergeRequestSerializer
end
serializer_klass
.
new
(
current_user:
current_user
,
project:
issuable
.
project
)
.
represent
(
issuable
)
.
to_json
end
def
template_dropdown_tag
(
issuable
,
&
block
)
...
...
@@ -357,7 +359,8 @@ module IssuablesHelper
def
issuable_sidebar_options
(
issuable
,
can_edit_issuable
)
{
endpoint:
"
#{
issuable_json_path
(
issuable
)
}
?basic=true"
,
endpoint:
"
#{
issuable_json_path
(
issuable
)
}
?serializer=sidebar"
,
toggleSubscriptionEndpoint:
toggle_subscription_path
(
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
),
editable:
can_edit_issuable
,
...
...
This diff is collapsed.
Click to expand it.
app/models/concerns/subscribable.rb
View file @
6dc9028f
...
...
@@ -13,6 +13,8 @@ module Subscribable
end
def
subscribed?
(
user
,
project
=
nil
)
return
false
unless
user
if
subscription
=
subscriptions
.
find_by
(
user:
user
,
project:
project
)
subscription
.
subscribed
else
...
...
This diff is collapsed.
Click to expand it.
app/serializers/issuable_sidebar_entity.rb
0 → 100644
View file @
6dc9028f
class
IssuableSidebarEntity
<
Grape
::
Entity
include
RequestAwareEntity
expose
:participants
,
using:
::
API
::
Entities
::
UserBasic
do
|
issuable
|
issuable
.
participants
(
request
.
current_user
)
end
expose
:subscribed
do
|
issuable
|
issuable
.
subscribed?
(
request
.
current_user
,
issuable
.
project
)
end
expose
:time_estimate
expose
:total_time_spent
expose
:human_time_estimate
expose
:human_total_time_spent
end
This diff is collapsed.
Click to expand it.
app/serializers/issue_serializer.rb
View file @
6dc9028f
class
IssueSerializer
<
BaseSerializer
entity
IssueEntity
# This overrided method takes care of which entity should be used
# to serialize the `issue` based on `basic` key in `opts` param.
# Hence, `entity` doesn't need to be declared on the class scope.
def
represent
(
merge_request
,
opts
=
{})
entity
=
case
opts
[
:serializer
]
when
'sidebar'
IssueSidebarEntity
else
IssueEntity
end
super
(
merge_request
,
opts
,
entity
)
end
end
This diff is collapsed.
Click to expand it.
app/serializers/issue_sidebar_entity.rb
0 → 100644
View file @
6dc9028f
class
IssueSidebarEntity
<
IssuableSidebarEntity
expose
:assignees
,
using:
API
::
Entities
::
UserBasic
end
This diff is collapsed.
Click to expand it.
app/serializers/merge_request_basic_entity.rb
View file @
6dc9028f
class
MergeRequestBasicEntity
<
Grape
::
Entity
class
MergeRequestBasicEntity
<
IssuableSidebar
Entity
expose
:assignee_id
expose
:merge_status
expose
:merge_error
expose
:state
expose
:source_branch_exists?
,
as: :source_branch_exists
expose
:time_estimate
expose
:total_time_spent
expose
:human_time_estimate
expose
:human_total_time_spent
end
This diff is collapsed.
Click to expand it.
app/serializers/merge_request_serializer.rb
View file @
6dc9028f
...
...
@@ -3,7 +3,14 @@ class MergeRequestSerializer < BaseSerializer
# to serialize the `merge_request` based on `basic` key in `opts` param.
# Hence, `entity` doesn't need to be declared on the class scope.
def
represent
(
merge_request
,
opts
=
{})
entity
=
opts
[
:basic
]
?
MergeRequestBasicEntity
:
MergeRequestEntity
entity
=
case
opts
[
:serializer
]
when
'basic'
,
'sidebar'
MergeRequestBasicEntity
else
MergeRequestEntity
end
super
(
merge_request
,
opts
,
entity
)
end
end
This diff is collapsed.
Click to expand it.
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment