Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
dfc2d7d8
Commit
dfc2d7d8
authored
May 27, 2021
by
Doug Stull
Committed by
Phil Hughes
May 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add invite option to reviewer dropdown [RUN AS-IF-FOSS]
parent
64f5f4c3
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
146 additions
and
57 deletions
+146
-57
app/assets/javascripts/invite_members/init_invite_members_trigger.js
...javascripts/invite_members/init_invite_members_trigger.js
+12
-10
app/assets/javascripts/pages/projects/issues/show.js
app/assets/javascripts/pages/projects/issues/show.js
+0
-4
app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
.../pages/projects/merge_requests/init_merge_request_show.js
+0
-4
app/assets/javascripts/sidebar/mount_sidebar.js
app/assets/javascripts/sidebar/mount_sidebar.js
+18
-0
app/assets/javascripts/sidebar/track_invite_members.js
app/assets/javascripts/sidebar/track_invite_members.js
+12
-0
app/views/shared/issuable/_sidebar_assignees.html.haml
app/views/shared/issuable/_sidebar_assignees.html.haml
+4
-19
app/views/shared/issuable/_sidebar_reviewers.html.haml
app/views/shared/issuable/_sidebar_reviewers.html.haml
+4
-1
app/views/shared/issuable/_sidebar_user_dropdown.html.haml
app/views/shared/issuable/_sidebar_user_dropdown.html.haml
+20
-0
ee/app/assets/javascripts/pages/projects/issues/show/index.js
...pp/assets/javascripts/pages/projects/issues/show/index.js
+0
-5
ee/app/assets/javascripts/pages/projects/merge_requests/show/index.js
...s/javascripts/pages/projects/merge_requests/show/index.js
+0
-5
spec/features/issues/issue_sidebar_spec.rb
spec/features/issues/issue_sidebar_spec.rb
+1
-1
spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
...atures/merge_request/user_edits_assignees_sidebar_spec.rb
+2
-2
spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
...atures/merge_request/user_edits_reviewers_sidebar_spec.rb
+61
-0
spec/frontend/sidebar/track_invite_members_spec.js
spec/frontend/sidebar/track_invite_members_spec.js
+3
-3
spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb
...mples/features/issuable_invite_members_shared_examples.rb
+9
-3
No files found.
app/assets/javascripts/invite_members/init_invite_members_trigger.js
View file @
dfc2d7d8
...
...
@@ -2,19 +2,21 @@ import Vue from 'vue';
import
InviteMembersTrigger
from
'
~/invite_members/components/invite_members_trigger.vue
'
;
export
default
function
initInviteMembersTrigger
()
{
const
el
=
document
.
querySelector
(
'
.js-invite-members-trigger
'
);
const
triggers
=
document
.
querySelectorAll
(
'
.js-invite-members-trigger
'
);
if
(
!
el
)
{
if
(
!
triggers
)
{
return
false
;
}
return
new
Vue
({
el
,
render
:
(
createElement
)
=>
createElement
(
InviteMembersTrigger
,
{
props
:
{
...
el
.
dataset
,
},
}),
return
triggers
.
forEach
((
el
)
=>
{
return
new
Vue
({
el
,
render
:
(
createElement
)
=>
createElement
(
InviteMembersTrigger
,
{
props
:
{
...
el
.
dataset
,
},
}),
});
});
}
app/assets/javascripts/pages/projects/issues/show.js
View file @
dfc2d7d8
import
loadAwardsHandler
from
'
~/awards_handler
'
;
import
ShortcutsIssuable
from
'
~/behaviors/shortcuts/shortcuts_issuable
'
;
import
initIssuableSidebar
from
'
~/init_issuable_sidebar
'
;
import
initInviteMembersModal
from
'
~/invite_members/init_invite_members_modal
'
;
import
initInviteMembersTrigger
from
'
~/invite_members/init_invite_members_trigger
'
;
import
{
IssuableType
}
from
'
~/issuable_show/constants
'
;
import
Issue
from
'
~/issue
'
;
import
'
~/notes/index
'
;
...
...
@@ -34,8 +32,6 @@ export default function initShowIssue() {
initIssueHeaderActions
(
store
);
initSentryErrorStackTraceApp
();
initRelatedMergeRequestsApp
();
initInviteMembersModal
();
initInviteMembersTrigger
();
import
(
/* webpackChunkName: 'design_management' */
'
~/design_management
'
)
.
then
((
module
)
=>
module
.
default
())
...
...
app/assets/javascripts/pages/projects/merge_requests/init_merge_request_show.js
View file @
dfc2d7d8
...
...
@@ -4,8 +4,6 @@ import loadAwardsHandler from '~/awards_handler';
import
ShortcutsIssuable
from
'
~/behaviors/shortcuts/shortcuts_issuable
'
;
import
initPipelines
from
'
~/commit/pipelines/pipelines_bundle
'
;
import
initIssuableSidebar
from
'
~/init_issuable_sidebar
'
;
import
initInviteMembersModal
from
'
~/invite_members/init_invite_members_modal
'
;
import
initInviteMembersTrigger
from
'
~/invite_members/init_invite_members_trigger
'
;
import
StatusBox
from
'
~/issuable/components/status_box.vue
'
;
import
createDefaultClient
from
'
~/lib/graphql
'
;
import
{
handleLocationHash
}
from
'
~/lib/utils/common_utils
'
;
...
...
@@ -29,8 +27,6 @@ export default function initMergeRequestShow() {
}
else
{
loadAwardsHandler
();
}
initInviteMembersModal
();
initInviteMembersTrigger
();
const
el
=
document
.
querySelector
(
'
.js-mr-status-box
'
);
const
apolloProvider
=
new
VueApollo
({
defaultClient
:
createDefaultClient
()
});
...
...
app/assets/javascripts/sidebar/mount_sidebar.js
View file @
dfc2d7d8
...
...
@@ -2,6 +2,8 @@ import $ from 'jquery';
import
Vue
from
'
vue
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
createFlash
from
'
~/flash
'
;
import
initInviteMembersModal
from
'
~/invite_members/init_invite_members_modal
'
;
import
initInviteMembersTrigger
from
'
~/invite_members/init_invite_members_trigger
'
;
import
{
IssuableType
}
from
'
~/issue_show/constants
'
;
import
{
isInIssuePage
,
...
...
@@ -17,6 +19,7 @@ import SidebarDueDateWidget from '~/sidebar/components/date/sidebar_date_widget.
import
SidebarParticipantsWidget
from
'
~/sidebar/components/participants/sidebar_participants_widget.vue
'
;
import
SidebarReferenceWidget
from
'
~/sidebar/components/reference/sidebar_reference_widget.vue
'
;
import
{
apolloProvider
}
from
'
~/sidebar/graphql
'
;
import
trackShowInviteMemberLink
from
'
~/sidebar/track_invite_members
'
;
import
Translate
from
'
../vue_shared/translate
'
;
import
SidebarAssignees
from
'
./components/assignees/sidebar_assignees.vue
'
;
import
CopyEmailToClipboard
from
'
./components/copy_email_to_clipboard.vue
'
;
...
...
@@ -123,6 +126,12 @@ function mountAssigneesComponent() {
},
}),
});
const
assigneeDropdown
=
document
.
querySelector
(
'
.js-sidebar-assignee-dropdown
'
);
if
(
assigneeDropdown
)
{
trackShowInviteMemberLink
(
assigneeDropdown
);
}
}
function
mountReviewersComponent
(
mediator
)
{
...
...
@@ -149,6 +158,12 @@ function mountReviewersComponent(mediator) {
},
}),
});
const
reviewerDropdown
=
document
.
querySelector
(
'
.js-sidebar-reviewer-dropdown
'
);
if
(
reviewerDropdown
)
{
trackShowInviteMemberLink
(
reviewerDropdown
);
}
}
export
function
mountSidebarLabels
()
{
...
...
@@ -438,6 +453,9 @@ const isAssigneesWidgetShown =
(
isInIssuePage
()
||
isInDesignPage
())
&&
gon
.
features
.
issueAssigneesWidget
;
export
function
mountSidebar
(
mediator
)
{
initInviteMembersModal
();
initInviteMembersTrigger
();
if
(
isAssigneesWidgetShown
)
{
mountAssigneesComponent
();
}
else
{
...
...
ee/app/assets/javascripts/projects
/track_invite_members.js
→
app/assets/javascripts/sidebar
/track_invite_members.js
View file @
dfc2d7d8
import
$
from
'
jquery
'
;
import
Tracking
from
'
~/tracking
'
;
export
default
function
initTrackInviteMembers
(
assigneeDropdown
)
{
const
trackLabel
=
'
edit_assignee
'
;
const
{
trackEvent
}
=
assigneeDropdown
.
querySelector
(
'
.js-invite-members-track
'
).
dataset
;
export
default
function
initTrackInviteMembers
(
userDropdown
)
{
const
{
trackEvent
,
trackLabel
}
=
userDropdown
.
querySelector
(
'
.js-invite-members-track
'
).
dataset
;
$
(
assignee
Dropdown
).
on
(
'
shown.bs.dropdown
'
,
()
=>
{
$
(
user
Dropdown
).
on
(
'
shown.bs.dropdown
'
,
()
=>
{
Tracking
.
event
(
undefined
,
trackEvent
,
{
label
:
trackLabel
,
});
...
...
app/views/shared/issuable/_sidebar_assignees.html.haml
View file @
dfc2d7d8
...
...
@@ -42,22 +42,7 @@
-
data
[
'max-select'
]
=
dropdown_options
[
:data
][
:'max-select'
]
if
dropdown_options
[
:data
][
:'max-select'
]
-
options
[
:data
].
merge!
(
data
)
-
if
directly_invite_members?
-
options
[
:dropdown_class
]
+=
' dropdown-extended-height'
-
options
[
:footer_content
]
=
true
-
options
[
:wrapper_class
]
=
'js-sidebar-assignee-dropdown'
-
options
[
:toggle_class
]
+=
' js-invite-members-track'
-
data
[
'track-event'
]
=
'show_invite_members'
-
options
[
:data
].
merge!
(
data
)
-
invite_text
=
_
(
'Invite Members'
)
-
track_label
=
'edit_assignee'
=
dropdown_tag
(
title
,
options:
options
)
do
%ul
.dropdown-footer-list
%li
.js-invite-members-trigger
{
data:
{
trigger_element:
'anchor'
,
display_text:
invite_text
,
event:
'click_invite_members'
,
label:
track_label
}
}
-
else
=
dropdown_tag
(
title
,
options:
options
)
=
render
'shared/issuable/sidebar_user_dropdown'
,
options:
options
,
wrapper_class:
'js-sidebar-assignee-dropdown'
,
track_label:
'edit_assignee'
app/views/shared/issuable/_sidebar_reviewers.html.haml
View file @
dfc2d7d8
...
...
@@ -39,4 +39,7 @@
-
data
[
'max-select'
]
=
dropdown_options
[
:data
][
:'max-select'
]
if
dropdown_options
[
:data
][
:'max-select'
]
-
options
[
:data
].
merge!
(
data
)
=
dropdown_tag
(
title
,
options:
options
)
=
render
'shared/issuable/sidebar_user_dropdown'
,
options:
options
,
wrapper_class:
'js-sidebar-reviewer-dropdown'
,
track_label:
'edit_reviewer'
app/views/shared/issuable/_sidebar_user_dropdown.html.haml
0 → 100644
View file @
dfc2d7d8
-
options
=
local_assigns
.
fetch
(
:options
)
-
data
=
options
[
:data
]
-
if
directly_invite_members?
-
options
[
:dropdown_class
]
+=
' dropdown-extended-height'
-
options
[
:footer_content
]
=
true
-
options
[
:wrapper_class
]
=
local_assigns
.
fetch
(
:wrapper_class
)
-
options
[
:toggle_class
]
+=
' js-invite-members-track'
-
data
[
'track-event'
]
=
'show_invite_members'
-
data
[
'track-label'
]
=
local_assigns
.
fetch
(
:track_label
)
=
dropdown_tag
(
data
[
'dropdown-title'
],
options:
options
)
do
%ul
.dropdown-footer-list
%li
.js-invite-members-trigger
{
data:
{
trigger_element:
'anchor'
,
display_text:
_
(
'Invite Members'
),
event:
'click_invite_members'
,
label:
data
[
'track-label'
]
}
}
-
else
=
dropdown_tag
(
data
[
'dropdown-title'
],
options:
options
)
ee/app/assets/javascripts/pages/projects/issues/show/index.js
View file @
dfc2d7d8
import
trackShowInviteMemberLink
from
'
ee/projects/track_invite_members
'
;
import
initSidebarBundle
from
'
ee/sidebar/sidebar_bundle
'
;
import
initShow
from
'
~/pages/projects/issues/show
'
;
...
...
@@ -13,7 +12,3 @@ initRelatedIssues();
new
UserCallout
({
className
:
'
js-epics-sidebar-callout
'
});
// eslint-disable-next-line no-new
new
UserCallout
({
className
:
'
js-weight-sidebar-callout
'
});
const
assigneeDropdown
=
document
.
querySelector
(
'
.js-sidebar-assignee-dropdown
'
);
if
(
assigneeDropdown
)
trackShowInviteMemberLink
(
assigneeDropdown
);
ee/app/assets/javascripts/pages/projects/merge_requests/show/index.js
View file @
dfc2d7d8
import
trackShowInviteMemberLink
from
'
ee/projects/track_invite_members
'
;
import
initSidebarBundle
from
'
ee/sidebar/sidebar_bundle
'
;
import
{
initReviewBar
}
from
'
~/batch_comments
'
;
import
initMrNotes
from
'
~/mr_notes
'
;
...
...
@@ -11,7 +10,3 @@ initSidebarBundle();
initMrNotes
();
initReviewBar
();
initIssuableHeaderWarning
(
store
);
const
assigneeDropdown
=
document
.
querySelector
(
'
.js-sidebar-assignee-dropdown
'
);
if
(
assigneeDropdown
)
trackShowInviteMemberLink
(
assigneeDropdown
);
spec/features/issues/issue_sidebar_spec.rb
View file @
dfc2d7d8
...
...
@@ -32,7 +32,7 @@ RSpec.describe 'Issue Sidebar' do
stub_feature_flags
(
issue_assignees_widget:
false
)
end
include_examples
'issuable invite members
experiments
'
do
include_examples
'issuable invite members'
do
let
(
:issuable_path
)
{
project_issue_path
(
project
,
issue2
)
}
end
...
...
spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
View file @
dfc2d7d8
...
...
@@ -68,14 +68,14 @@ RSpec.describe 'Merge request > User edits assignees sidebar', :js do
end
end
context
'with invite members
experiment
considerations'
do
context
'with invite members considerations'
do
let_it_be
(
:user
)
{
create
(
:user
)
}
before
do
sign_in
(
user
)
end
include_examples
'issuable invite members
experiments
'
do
include_examples
'issuable invite members'
do
let
(
:issuable_path
)
{
project_merge_request_path
(
project
,
merge_request
)
}
end
end
...
...
spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
0 → 100644
View file @
dfc2d7d8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'Merge request > User edits reviewers sidebar'
,
:js
do
context
'with invite members considerations'
do
let_it_be
(
:merge_request
)
{
create
(
:merge_request
)
}
let_it_be
(
:project
)
{
merge_request
.
project
}
let_it_be
(
:user
)
{
create
(
:user
)
}
before
do
sign_in
(
user
)
end
context
'when a privileged user can invite in reviewer dropdown'
do
before
do
project
.
add_maintainer
(
user
)
end
it
'shows a link for inviting members and launches invite modal'
do
visit
project_merge_request_path
(
project
,
merge_request
)
reviewer_edit_link
.
click
wait_for_requests
page
.
within
'.dropdown-menu-user'
do
expect
(
page
).
to
have_link
(
'Invite Members'
)
expect
(
page
).
to
have_selector
(
'[data-track-event="click_invite_members"]'
)
expect
(
page
).
to
have_selector
(
'[data-track-label="edit_reviewer"]'
)
end
click_link
'Invite Members'
expect
(
page
).
to
have_content
(
"You're inviting members to the"
)
end
end
context
'when user cannot invite members in reviewer dropdown'
do
before
do
project
.
add_developer
(
user
)
end
it
'shows author in assignee dropdown and no invite link'
do
visit
project_merge_request_path
(
project
,
merge_request
)
reviewer_edit_link
.
click
wait_for_requests
page
.
within
'.dropdown-menu-user'
do
expect
(
page
).
not_to
have_link
(
'Invite Members'
)
end
end
end
def
reviewer_edit_link
find
(
'.block.reviewer .edit-link'
)
end
end
end
ee/spec/frontend/projects
/track_invite_members_spec.js
→
spec/frontend/sidebar
/track_invite_members_spec.js
View file @
dfc2d7d8
import
$
from
'
jquery
'
;
import
trackShowInviteMemberLink
from
'
ee/projects/track_invite_members
'
;
import
{
mockTracking
,
unmockTracking
}
from
'
helpers/tracking_helper
'
;
import
trackShowInviteMemberLink
from
'
~/sidebar/track_invite_members
'
;
describe
(
'
Track user dropdown open
'
,
()
=>
{
let
trackingSpy
;
...
...
@@ -10,7 +10,7 @@ describe('Track user dropdown open', () => {
document
.
body
.
innerHTML
=
`
<div id="dummy-wrapper-element">
<div class="js-sidebar-assignee-dropdown">
<div class="js-invite-members-track" data-track-event="_track_event_">
<div class="js-invite-members-track" data-track-event="_track_event_"
data-track-label="_track_label_"
>
</div>
</div>
</div>
...
...
@@ -31,7 +31,7 @@ describe('Track user dropdown open', () => {
$
(
dropdownElement
).
trigger
(
'
shown.bs.dropdown
'
);
expect
(
trackingSpy
).
toHaveBeenCalledWith
(
undefined
,
'
_track_event_
'
,
{
label
:
'
edit_assignee
'
,
label
:
'
_track_label_
'
,
});
});
});
spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb
View file @
dfc2d7d8
# frozen_string_literal: true
RSpec
.
shared_examples
'issuable invite members
experiments
'
do
RSpec
.
shared_examples
'issuable invite members'
do
context
'when a privileged user can invite'
do
it
'shows a link for inviting members and launches invite modal'
do
before
do
project
.
add_maintainer
(
user
)
end
it
'shows a link for inviting members and launches invite modal'
do
visit
issuable_path
find
(
'.block.assignee .edit-link'
).
click
...
...
@@ -23,8 +26,11 @@ RSpec.shared_examples 'issuable invite members experiments' do
end
context
'when user cannot invite members in assignee dropdown'
do
it
'shows author in assignee dropdown and no invite link'
do
before
do
project
.
add_developer
(
user
)
end
it
'shows author in assignee dropdown and no invite link'
do
visit
issuable_path
find
(
'.block.assignee .edit-link'
).
click
...
...
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