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
6b91dfd0
Commit
6b91dfd0
authored
Oct 22, 2021
by
Florie Guibert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Labels widget support for epic
Use labels widget on epic sidebar
parent
1d154fa0
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
208 additions
and
66 deletions
+208
-66
app/assets/javascripts/boards/components/board_content_sidebar.vue
...s/javascripts/boards/components/board_content_sidebar.vue
+2
-1
app/assets/javascripts/issue_show/constants.js
app/assets/javascripts/issue_show/constants.js
+5
-0
app/assets/javascripts/right_sidebar.js
app/assets/javascripts/right_sidebar.js
+6
-2
app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
.../javascripts/sidebar/components/labels/sidebar_labels.vue
+2
-1
app/assets/javascripts/sidebar/components/sidebar_editable_item.vue
.../javascripts/sidebar/components/sidebar_editable_item.vue
+1
-1
app/assets/javascripts/sidebar/constants.js
app/assets/javascripts/sidebar/constants.js
+14
-9
app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue
...omponents/sidebar/labels_select_vue/dropdown_contents.vue
+1
-0
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/constants.js
...ared/components/sidebar/labels_select_widget/constants.js
+2
-2
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
...onents/sidebar/labels_select_widget/dropdown_contents.vue
+13
-3
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
...ar/labels_select_widget/dropdown_contents_create_view.vue
+16
-9
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
...ar/labels_select_widget/dropdown_contents_labels_view.vue
+6
-2
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/epic_update_labels.mutation.graphql
...select_widget/graphql/epic_update_labels.mutation.graphql
+16
-0
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
...nents/sidebar/labels_select_widget/labels_select_root.vue
+57
-10
ee/app/assets/javascripts/behaviors/shortcuts/shortcuts_epic.js
.../assets/javascripts/behaviors/shortcuts/shortcuts_epic.js
+4
-0
ee/app/assets/javascripts/epic/components/epic_form.vue
ee/app/assets/javascripts/epic/components/epic_form.vue
+2
-1
ee/app/assets/javascripts/epic/components/epic_sidebar.vue
ee/app/assets/javascripts/epic/components/epic_sidebar.vue
+26
-0
ee/app/assets/javascripts/epic/epic_bundle.js
ee/app/assets/javascripts/epic/epic_bundle.js
+4
-0
ee/spec/features/epics/epic_labels_spec.rb
ee/spec/features/epics/epic_labels_spec.rb
+3
-2
ee/spec/features/epics/epic_show_spec.rb
ee/spec/features/epics/epic_show_spec.rb
+11
-11
ee/spec/features/epics/shortcuts_epic_spec.rb
ee/spec/features/epics/shortcuts_epic_spec.rb
+1
-1
spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
...abels_select_widget/dropdown_contents_create_view_spec.js
+10
-9
spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
...abels_select_widget/dropdown_contents_labels_view_spec.js
+2
-0
spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
...ts/sidebar/labels_select_widget/dropdown_contents_spec.js
+2
-1
spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
...s/sidebar/labels_select_widget/labels_select_root_spec.js
+2
-1
No files found.
app/assets/javascripts/boards/components/board_content_sidebar.vue
View file @
6b91dfd0
...
...
@@ -214,8 +214,9 @@ export default {
:labels-create-title=
"createLabelTitle"
:labels-filter-base-path=
"projectPathForActiveIssue"
:attr-workspace-path=
"attrWorkspacePath"
workspace-type=
"project"
:issuable-type=
"issuableType"
:label-type=
"labelType"
:label-
create-
type=
"labelType"
@
onLabelRemove=
"handleLabelRemove"
@
updateSelectedLabels=
"handleUpdateSelectedLabels"
>
...
...
app/assets/javascripts/issue_show/constants.js
View file @
6b91dfd0
...
...
@@ -39,3 +39,8 @@ export const IncidentType = 'incident';
export
const
issueState
=
{
issueType
:
undefined
,
isDirty
:
false
};
export
const
POLLING_DELAY
=
2000
;
export
const
WorkspaceType
=
{
project
:
'
project
'
,
group
:
'
group
'
,
};
app/assets/javascripts/right_sidebar.js
View file @
6b91dfd0
...
...
@@ -130,8 +130,12 @@ Sidebar.prototype.openDropdown = function (blockOrName) {
// Wait for the sidebar to trigger('click') open
// so it doesn't cause our dropdown to close preemptively
setTimeout
(()
=>
{
$block
.
find
(
'
.js-sidebar-dropdown-toggle
'
).
trigger
(
'
click
'
);
});
if
(
gon
.
features
?.
labelsWidget
)
{
$block
.
find
(
'
.shortcut-sidebar-dropdown-toggle
'
).
trigger
(
'
click
'
);
}
else
{
$block
.
find
(
'
.js-sidebar-dropdown-toggle
'
).
trigger
(
'
click
'
);
}
},
200
);
};
Sidebar
.
prototype
.
setCollapseAfterUpdate
=
function
(
$block
)
{
...
...
app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue
View file @
6b91dfd0
...
...
@@ -158,8 +158,9 @@ export default {
:labels-filter-base-path=
"projectIssuesPath"
:variant=
"$options.variant"
:issuable-type=
"issuableType"
workspace-type=
"project"
:attr-workspace-path=
"fullPath"
:label-type=
"LabelType.project"
:label-
create-
type=
"LabelType.project"
data-qa-selector=
"labels_block"
>
{{
__
(
'
None
'
)
}}
...
...
app/assets/javascripts/sidebar/components/sidebar_editable_item.vue
View file @
6b91dfd0
...
...
@@ -134,7 +134,7 @@ export default {
v-if=
"canUpdate && !initialLoading && canEdit"
category=
"tertiary"
size=
"small"
class=
"gl-text-gray-900! gl-ml-auto hide-collapsed gl-mr-n2"
class=
"gl-text-gray-900! gl-ml-auto hide-collapsed gl-mr-n2
shortcut-sidebar-dropdown-toggle
"
data-testid=
"edit-button"
:data-track-action=
"tracking.event"
:data-track-label=
"tracking.label"
...
...
app/assets/javascripts/sidebar/constants.js
View file @
6b91dfd0
import
updateIssueLabelsMutation
from
'
~/boards/graphql/issue_set_labels.mutation.graphql
'
;
import
{
IssuableType
}
from
'
~/issue_show/constants
'
;
import
{
IssuableType
,
WorkspaceType
}
from
'
~/issue_show/constants
'
;
import
{
DEFAULT_DEBOUNCE_AND_THROTTLE_MS
}
from
'
~/lib/utils/constants
'
;
import
epicConfidentialQuery
from
'
~/sidebar/queries/epic_confidential.query.graphql
'
;
import
epicDueDateQuery
from
'
~/sidebar/queries/epic_due_date.query.graphql
'
;
...
...
@@ -34,6 +34,7 @@ import updateMergeRequestLabelsMutation from '~/sidebar/queries/update_merge_req
import
updateMergeRequestSubscriptionMutation
from
'
~/sidebar/queries/update_merge_request_subscription.mutation.graphql
'
;
import
updateAlertAssigneesMutation
from
'
~/vue_shared/alert_details/graphql/mutations/alert_set_assignees.mutation.graphql
'
;
import
epicLabelsQuery
from
'
~/vue_shared/components/sidebar/labels_select_widget/graphql/epic_labels.query.graphql
'
;
import
updateEpicLabelsMutation
from
'
~/vue_shared/components/sidebar/labels_select_widget/graphql/epic_update_labels.mutation.graphql
'
;
import
groupLabelsQuery
from
'
~/vue_shared/components/sidebar/labels_select_widget/graphql/group_labels.query.graphql
'
;
import
issueLabelsQuery
from
'
~/vue_shared/components/sidebar/labels_select_widget/graphql/issue_labels.query.graphql
'
;
import
projectLabelsQuery
from
'
~/vue_shared/components/sidebar/labels_select_widget/graphql/project_labels.query.graphql
'
;
...
...
@@ -111,19 +112,18 @@ export const referenceQueries = {
},
};
export
const
labelsQueries
=
{
[
IssuableType
.
Issue
]:
{
issuableQuery
:
issueLabelsQuery
,
workspaceQuery
:
projectLabelsQuery
,
export
const
workspaceLabelsQueries
=
{
[
WorkspaceType
.
project
]:
{
query
:
projectLabelsQuery
,
},
[
IssuableType
.
Epic
]:
{
issuableQuery
:
epicLabelsQuery
,
workspaceQuery
:
groupLabelsQuery
,
[
WorkspaceType
.
group
]:
{
query
:
groupLabelsQuery
,
},
};
export
const
labelsMutation
s
=
{
export
const
issuableLabelsQuerie
s
=
{
[
IssuableType
.
Issue
]:
{
issuableQuery
:
issueLabelsQuery
,
mutation
:
updateIssueLabelsMutation
,
mutationName
:
'
updateIssue
'
,
},
...
...
@@ -131,6 +131,11 @@ export const labelsMutations = {
mutation
:
updateMergeRequestLabelsMutation
,
mutationName
:
'
mergeRequestSetLabels
'
,
},
[
IssuableType
.
Epic
]:
{
issuableQuery
:
epicLabelsQuery
,
mutation
:
updateEpicLabelsMutation
,
mutationName
:
'
updateEpic
'
,
},
};
export
const
dateTypes
=
{
...
...
app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents.vue
View file @
6b91dfd0
...
...
@@ -36,6 +36,7 @@ export default {
<
template
>
<div
class=
"labels-select-dropdown-contents gl-w-full gl-my-2 gl-py-3 gl-rounded-base gl-absolute"
data-testid=
"labels-select-dropdown-contents"
data-qa-selector=
"labels_dropdown_content"
:style=
"directionStyle"
>
...
...
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/constants.js
View file @
6b91dfd0
...
...
@@ -7,6 +7,6 @@ export const DropdownVariant = {
};
export
const
LabelType
=
{
group
:
'
GroupLabel
'
,
project
:
'
ProjectLabel
'
,
group
:
'
group
'
,
project
:
'
project
'
,
};
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue
View file @
6b91dfd0
...
...
@@ -66,11 +66,15 @@ export default {
type
:
String
,
required
:
true
,
},
workspaceType
:
{
type
:
String
,
required
:
true
,
},
attrWorkspacePath
:
{
type
:
String
,
required
:
true
,
},
labelType
:
{
label
Create
Type
:
{
type
:
String
,
required
:
true
,
},
...
...
@@ -158,6 +162,7 @@ export default {
this
.
$emit
(
'
setLabels
'
,
this
.
localSelectedLabels
);
},
handleDropdownHide
()
{
this
.
$emit
(
'
closeDropdown
'
);
if
(
!
isDropdownVariantSidebar
(
this
.
variant
))
{
this
.
setLabels
();
}
...
...
@@ -168,6 +173,9 @@ export default {
setFocus
()
{
this
.
$refs
.
header
.
focusInput
();
},
showDropdown
()
{
this
.
$refs
.
dropdown
.
show
();
},
},
};
</
script
>
...
...
@@ -177,6 +185,7 @@ export default {
ref=
"dropdown"
:text=
"buttonText"
class=
"gl-w-full gl-mt-2"
data-testid=
"labels-select-dropdown-contents"
data-qa-selector=
"labels_dropdown_content"
@
hide=
"handleDropdownHide"
@
shown=
"setFocus"
...
...
@@ -202,9 +211,10 @@ export default {
:allow-multiselect=
"allowMultiselect"
:issuable-type=
"issuableType"
:full-path=
"fullPath"
:workspace-type=
"workspaceType"
:attr-workspace-path=
"attrWorkspacePath"
:label-
type=
"label
Type"
@
hideCreateView=
"toggleDropdownContent
sCreateView
"
:label-
create-type=
"labelCreate
Type"
@
hideCreateView=
"toggleDropdownContent"
/>
</
template
>
<
template
#footer
>
...
...
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
View file @
6b91dfd0
...
...
@@ -3,7 +3,7 @@ import { GlTooltipDirective, GlButton, GlFormInput, GlLink, GlLoadingIcon } from
import
produce
from
'
immer
'
;
import
createFlash
from
'
~/flash
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
l
abelsQueries
}
from
'
~/sidebar/constants
'
;
import
{
workspaceL
abelsQueries
}
from
'
~/sidebar/constants
'
;
import
createLabelMutation
from
'
./graphql/create_label.mutation.graphql
'
;
import
{
LabelType
}
from
'
./constants
'
;
...
...
@@ -20,19 +20,24 @@ export default {
GlTooltip
:
GlTooltipDirective
,
},
props
:
{
issuableType
:
{
fullPath
:
{
type
:
String
,
required
:
true
,
},
full
Path
:
{
attrWorkspace
Path
:
{
type
:
String
,
required
:
true
,
},
attrWorkspacePath
:
{
labelCreateType
:
{
type
:
String
,
required
:
true
,
},
labelType
:
{
issuableType
:
{
type
:
String
,
required
:
false
,
default
:
undefined
,
},
workspaceType
:
{
type
:
String
,
required
:
true
,
},
...
...
@@ -53,7 +58,7 @@ export default {
return
Object
.
keys
(
colorsMap
).
map
((
color
)
=>
({
[
color
]:
colorsMap
[
color
]
}));
},
mutationVariables
()
{
const
attributePath
=
this
.
labelType
===
LabelType
.
group
?
'
groupPath
'
:
'
projectPath
'
;
const
attributePath
=
this
.
label
Create
Type
===
LabelType
.
group
?
'
groupPath
'
:
'
projectPath
'
;
return
{
title
:
this
.
labelTitle
,
...
...
@@ -73,8 +78,10 @@ export default {
this
.
selectedColor
=
this
.
getColorCode
(
color
);
},
updateLabelsInCache
(
store
,
label
)
{
const
{
query
}
=
workspaceLabelsQueries
[
this
.
workspaceType
];
const
sourceData
=
store
.
readQuery
({
query
:
labelsQueries
[
this
.
issuableType
].
workspaceQuery
,
query
,
variables
:
{
fullPath
:
this
.
fullPath
,
searchTerm
:
''
},
});
...
...
@@ -86,7 +93,7 @@ export default {
});
store
.
writeQuery
({
query
:
labelsQueries
[
this
.
issuableType
].
workspaceQuery
,
query
,
variables
:
{
fullPath
:
this
.
fullPath
,
searchTerm
:
''
},
data
,
});
...
...
@@ -171,7 +178,7 @@ export default {
<gl-button
class=
"js-btn-cancel-create"
data-testid=
"cancel-button"
@
click=
"$emit('hideCreateView')"
@
click
.stop
=
"$emit('hideCreateView')"
>
{{
__
(
'
Cancel
'
)
}}
</gl-button>
...
...
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue
View file @
6b91dfd0
...
...
@@ -4,7 +4,7 @@ import fuzzaldrinPlus from 'fuzzaldrin-plus';
import
createFlash
from
'
~/flash
'
;
import
{
getIdFromGraphQLId
}
from
'
~/graphql_shared/utils
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
l
abelsQueries
}
from
'
~/sidebar/constants
'
;
import
{
workspaceL
abelsQueries
}
from
'
~/sidebar/constants
'
;
import
LabelItem
from
'
./label_item.vue
'
;
export
default
{
...
...
@@ -39,6 +39,10 @@ export default {
type
:
String
,
required
:
true
,
},
workspaceType
:
{
type
:
String
,
required
:
true
,
},
},
data
()
{
return
{
...
...
@@ -49,7 +53,7 @@ export default {
apollo
:
{
labels
:
{
query
()
{
return
labelsQueries
[
this
.
issuableType
].
workspaceQ
uery
;
return
workspaceLabelsQueries
[
this
.
workspaceType
].
q
uery
;
},
variables
()
{
return
{
...
...
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/graphql/epic_update_labels.mutation.graphql
0 → 100644
View file @
6b91dfd0
mutation
updateEpic
(
$input
:
UpdateEpicInput
!)
{
updateEpic
(
input
:
$input
)
{
epic
{
id
labels
{
nodes
{
id
title
color
description
}
}
}
errors
}
}
app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
View file @
6b91dfd0
<
script
>
import
{
MutationOperationMode
}
from
'
~/graphql_shared/utils
'
;
import
{
debounce
}
from
'
lodash
'
;
import
{
MutationOperationMode
,
getIdFromGraphQLId
}
from
'
~/graphql_shared/utils
'
;
import
createFlash
from
'
~/flash
'
;
import
{
IssuableType
}
from
'
~/issue_show/constants
'
;
import
{
__
}
from
'
~/locale
'
;
import
SidebarEditableItem
from
'
~/sidebar/components/sidebar_editable_item.vue
'
;
import
{
labelsQueries
,
labelsMutation
s
}
from
'
~/sidebar/constants
'
;
import
{
issuableLabelsQuerie
s
}
from
'
~/sidebar/constants
'
;
import
{
DropdownVariant
}
from
'
./constants
'
;
import
DropdownContents
from
'
./dropdown_contents.vue
'
;
import
DropdownValue
from
'
./dropdown_value.vue
'
;
...
...
@@ -91,11 +92,15 @@ export default {
type
:
String
,
required
:
true
,
},
workspaceType
:
{
type
:
String
,
required
:
true
,
},
attrWorkspacePath
:
{
type
:
String
,
required
:
true
,
},
labelType
:
{
label
Create
Type
:
{
type
:
String
,
required
:
true
,
},
...
...
@@ -106,17 +111,21 @@ export default {
issuableLabels
:
[],
labelsSelectInProgress
:
false
,
oldIid
:
null
,
sidebarExpandedOnClick
:
false
,
};
},
computed
:
{
isLoading
()
{
return
this
.
labelsSelectInProgress
||
this
.
$apollo
.
queries
.
issuableLabels
.
loading
;
},
issuableLabelIds
()
{
return
this
.
issuableLabels
.
map
((
label
)
=>
label
.
id
);
},
},
apollo
:
{
issuableLabels
:
{
query
()
{
return
l
abelsQueries
[
this
.
issuableType
].
issuableQuery
;
return
issuableL
abelsQueries
[
this
.
issuableType
].
issuableQuery
;
},
skip
()
{
return
!
isDropdownVariantSidebar
(
this
.
variant
);
...
...
@@ -140,6 +149,15 @@ export default {
this
.
oldIid
=
oldVal
;
},
},
mounted
()
{
document
.
addEventListener
(
'
toggleSidebarRevealLabelsDropdown
'
,
this
.
handleCollapsedValueClick
);
},
beforeDestroy
()
{
document
.
removeEventListener
(
'
toggleSidebarRevealLabelsDropdown
'
,
this
.
handleCollapsedValueClick
,
);
},
methods
:
{
handleDropdownClose
(
labels
)
{
if
(
this
.
iid
!==
''
)
{
...
...
@@ -152,9 +170,18 @@ export default {
},
collapseEditableItem
()
{
this
.
$refs
.
editable
?.
collapse
();
if
(
this
.
sidebarExpandedOnClick
)
{
this
.
sidebarExpandedOnClick
=
false
;
this
.
$emit
(
'
toggleCollapse
'
);
}
},
handleCollapsedValueClick
()
{
this
.
sidebarExpandedOnClick
=
true
;
this
.
$emit
(
'
toggleCollapse
'
);
debounce
(()
=>
{
this
.
$refs
.
editable
.
toggle
();
this
.
$refs
.
dropdownContents
.
showDropdown
();
},
200
)();
},
getUpdateVariables
(
labels
)
{
let
labelIds
=
[];
...
...
@@ -172,8 +199,19 @@ export default {
case
IssuableType
.
Issue
:
return
updateVariables
;
case
IssuableType
.
MergeRequest
:
updateVariables
.
operationMode
=
MutationOperationMode
.
Replace
;
return
updateVariables
;
return
{
...
updateVariables
,
operationMode
:
MutationOperationMode
.
Replace
,
};
case
IssuableType
.
Epic
:
return
{
iid
:
currentIid
,
groupPath
:
this
.
fullPath
,
addLabelIds
:
labelIds
,
removeLabelIds
:
this
.
issuableLabelIds
.
filter
((
id
)
=>
!
labelIds
.
includes
(
id
))
.
map
((
id
)
=>
getIdFromGraphQLId
(
id
)),
};
default
:
return
{};
}
...
...
@@ -183,11 +221,11 @@ export default {
this
.
$apollo
.
mutate
({
mutation
:
labelsMutation
s
[
this
.
issuableType
].
mutation
,
mutation
:
issuableLabelsQuerie
s
[
this
.
issuableType
].
mutation
,
variables
:
{
input
:
inputVariables
},
})
.
then
(({
data
})
=>
{
const
{
mutationName
}
=
labelsMutation
s
[
this
.
issuableType
];
const
{
mutationName
}
=
issuableLabelsQuerie
s
[
this
.
issuableType
];
if
(
data
[
mutationName
]?.
errors
?.
length
)
{
throw
new
Error
();
...
...
@@ -227,6 +265,12 @@ export default {
labelIds
:
[
labelId
],
operationMode
:
MutationOperationMode
.
Remove
,
};
case
IssuableType
.
Epic
:
return
{
iid
:
this
.
iid
,
removeLabelIds
:
[
labelId
],
groupPath
:
this
.
fullPath
,
};
default
:
return
{};
}
...
...
@@ -288,6 +332,7 @@ export default {
<slot></slot>
</dropdown-value>
<dropdown-contents
ref=
"dropdownContents"
:dropdown-button-text=
"dropdownButtonText"
:allow-multiselect=
"allowMultiselect"
:labels-list-title=
"labelsListTitle"
...
...
@@ -299,8 +344,9 @@ export default {
:issuable-type=
"issuableType"
:is-visible=
"edit"
:full-path=
"fullPath"
:workspace-type=
"workspaceType"
:attr-workspace-path=
"attrWorkspacePath"
:label-
type=
"label
Type"
:label-
create-type=
"labelCreate
Type"
@
setLabels=
"handleDropdownClose"
@
closeDropdown=
"collapseEditableItem"
/>
...
...
@@ -320,8 +366,9 @@ export default {
:variant=
"variant"
:issuable-type=
"issuableType"
:full-path=
"fullPath"
:workspace-type=
"workspaceType"
:attr-workspace-path=
"attrWorkspacePath"
:label-
type=
"label
Type"
:label-
create-type=
"labelCreate
Type"
@
setLabels=
"handleDropdownClose"
/>
</div>
...
...
ee/app/assets/javascripts/behaviors/shortcuts/shortcuts_epic.js
View file @
6b91dfd0
...
...
@@ -24,6 +24,10 @@ export default class ShortcutsEpic extends ShortcutsIssuable {
}
static
openSidebarDropdown
(
$block
)
{
if
(
gon
.
features
?.
labelsWidget
)
{
document
.
dispatchEvent
(
new
Event
(
'
toggleSidebarRevealLabelsDropdown
'
));
return
;
}
if
(
parseBoolean
(
Cookies
.
get
(
'
collapsed_gutter
'
)))
{
document
.
dispatchEvent
(
new
Event
(
'
toggleSidebarRevealLabelsDropdown
'
));
}
else
{
...
...
ee/app/assets/javascripts/epic/components/epic_form.vue
View file @
6b91dfd0
...
...
@@ -197,7 +197,8 @@ export default {
:allow-scoped-labels=
"false"
:labels-filter-base-path=
"groupEpicsPath"
:attr-workspace-path=
"groupPath"
:label-type=
"LabelType.group"
workspace-type=
"group"
:label-create-type=
"LabelType.group"
issuable-type=
"epic"
variant=
"embedded"
data-qa-selector=
"labels_block"
...
...
ee/app/assets/javascripts/epic/components/epic_sidebar.vue
View file @
6b91dfd0
...
...
@@ -14,6 +14,9 @@ import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sideb
import
SidebarTodoWidget
from
'
~/sidebar/components/todo_toggle/sidebar_todo_widget.vue
'
;
import
sidebarEventHub
from
'
~/sidebar/event_hub
'
;
import
SidebarDatePickerCollapsed
from
'
~/vue_shared/components/sidebar/collapsed_grouped_date_picker.vue
'
;
import
LabelsSelectWidget
from
'
~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue
'
;
import
{
LabelType
}
from
'
~/vue_shared/components/sidebar/labels_select_widget/constants
'
;
import
glFeatureFlagMixin
from
'
~/vue_shared/mixins/gl_feature_flags_mixin
'
;
import
{
dateTypes
}
from
'
../constants
'
;
import
epicUtils
from
'
../utils/epic_utils
'
;
...
...
@@ -34,11 +37,14 @@ export default {
SidebarSubscriptionsWidget
,
SidebarReferenceWidget
,
SidebarTodoWidget
,
LabelsSelectWidget
,
},
mixins
:
[
glFeatureFlagMixin
()],
inject
:
[
'
iid
'
],
data
()
{
return
{
sidebarExpandedOnClick
:
false
,
LabelType
,
};
},
computed
:
{
...
...
@@ -60,6 +66,7 @@ export default {
'
epicDueDateSaveInProgress
'
,
'
fullPath
'
,
'
epicId
'
,
'
epicsWebUrl
'
,
]),
...
mapGetters
([
'
isUserSignedIn
'
,
...
...
@@ -231,7 +238,26 @@ export default {
:max-date=
"dueDateForCollapsedSidebar"
@
toggleCollapse=
"toggleSidebar(
{ sidebarCollapsed })"
/>
<labels-select-widget
v-if=
"glFeatures.labelsWidget"
class=
"block labels js-labels-block"
:iid=
"String(iid)"
:full-path=
"fullPath"
:allow-label-remove=
"canUpdate"
:allow-multiselect=
"true"
:labels-filter-base-path=
"epicsWebUrl"
variant=
"sidebar"
issuable-type=
"epic"
workspace-type=
"group"
:attr-workspace-path=
"fullPath"
:label-create-type=
"LabelType.group"
data-testid=
"labels-select"
@
toggleCollapse=
"handleSidebarToggle"
>
{{
__
(
'
None
'
)
}}
</labels-select-widget>
<sidebar-labels
v-else
:can-update=
"canUpdate"
:sidebar-collapsed=
"sidebarCollapsed"
data-testid=
"labels-select"
...
...
ee/app/assets/javascripts/epic/epic_bundle.js
View file @
6b91dfd0
...
...
@@ -43,9 +43,13 @@ export default () => {
components
:
{
EpicApp
},
provide
:
{
canUpdate
:
epicData
.
canUpdate
,
allowLabelCreate
:
parseBoolean
(
epicData
.
canUpdate
),
allowLabelEdit
:
parseBoolean
(
epicData
.
canUpdate
),
fullPath
:
epicData
.
fullPath
,
iid
:
epicMeta
.
epicIid
,
isClassicSidebar
:
true
,
allowScopedLabels
:
epicMeta
.
scopedLabels
,
labelsManagePath
:
epicMeta
.
labelsWebUrl
,
},
created
()
{
this
.
setEpicMeta
({
...
...
ee/spec/features/epics/epic_labels_spec.rb
View file @
6b91dfd0
...
...
@@ -51,13 +51,14 @@ RSpec.describe 'Assign labels to an epic', :js do
it
'opens labels dropdown'
do
page
.
within
(
'aside.right-sidebar'
)
do
expect
(
page
).
to
have_css
(
'.js-labels-block
.labels-select-dropdown-contents
'
)
expect
(
page
).
to
have_css
(
'.js-labels-block
[data-testid="labels-select-dropdown-contents"]
'
)
end
end
it
'collapses sidebar when clicked outside'
do
wait_for_requests
page
.
within
(
'.content-wrapper'
)
do
find
(
'.
content
'
).
click
find
(
'.
epic-page-container
'
).
click
expect
(
page
).
to
have_css
(
'.right-sidebar-collapsed'
)
end
...
...
ee/spec/features/epics/epic_show_spec.rb
View file @
6b91dfd0
...
...
@@ -228,8 +228,8 @@ RSpec.describe 'Epic show', :js do
describe
'Labels select'
do
it
'opens dropdown when `Edit` is clicked'
do
page
.
within
(
'aside.right-sidebar'
)
do
find
(
'.js-sidebar-dropdown-toggle'
).
click
page
.
within
(
'aside.right-sidebar
[data-testid="labels-select"]
'
)
do
click_button
'Edit'
end
wait_for_requests
...
...
@@ -239,20 +239,20 @@ RSpec.describe 'Epic show', :js do
context
'when dropdown is open'
do
before
do
page
.
within
(
'aside.right-sidebar'
)
do
find
(
'.js-sidebar-dropdown-toggle'
).
click
page
.
within
(
'aside.right-sidebar
[data-testid="labels-select"]
'
)
do
click_button
'Edit'
end
wait_for_requests
end
it
'shows labels within the label dropdown'
do
page
.
within
(
'.js-labels-list
.dropdown-content
'
)
do
page
.
within
(
'.js-labels-list
[data-testid="dropdown-content"]
'
)
do
expect
(
page
).
to
have_selector
(
'li'
,
count:
3
)
end
end
it
'shows checkmark next to label when label is clicked'
do
page
.
within
(
'.js-labels-list
.dropdown-content
'
)
do
page
.
within
(
'.js-labels-list
[data-testid="dropdown-content"]
'
)
do
find
(
'li'
,
text:
label1
.
title
).
click
expect
(
find
(
'li'
,
text:
label1
.
title
)).
to
have_selector
(
'.gl-icon'
,
visible:
true
)
...
...
@@ -261,7 +261,7 @@ RSpec.describe 'Epic show', :js do
it
'shows label create view when `Create group label` is clicked'
do
page
.
within
(
'.js-labels-block'
)
do
find
(
'a'
,
text:
'Create group label'
).
click
click_on
'Create group label'
expect
(
page
).
to
have_selector
(
'.js-labels-create'
)
end
...
...
@@ -269,7 +269,7 @@ RSpec.describe 'Epic show', :js do
it
'creates new label using create view'
do
page
.
within
(
'.js-labels-block'
)
do
find
(
'a'
,
text:
'Create group label'
).
click
click_on
'Create group label'
find
(
'.dropdown-input .gl-form-input'
).
set
(
'Test label'
)
find
(
'.suggest-colors-dropdown a'
,
match: :first
).
click
...
...
@@ -278,7 +278,7 @@ RSpec.describe 'Epic show', :js do
wait_for_requests
end
page
.
within
(
'.js-labels-list
.dropdown-content
'
)
do
page
.
within
(
'.js-labels-list
[data-testid="dropdown-content"]
'
)
do
expect
(
page
).
to
have_selector
(
'li'
,
count:
4
)
expect
(
page
).
to
have_content
(
'Test label'
)
end
...
...
@@ -286,7 +286,7 @@ RSpec.describe 'Epic show', :js do
it
'shows labels list view when `Cancel` button is clicked from create view'
do
page
.
within
(
'.js-labels-block'
)
do
find
(
'a'
,
text:
'Create group label'
).
click
click_on
'Create group label'
find
(
'.js-btn-cancel-create'
).
click
wait_for_requests
...
...
@@ -297,7 +297,7 @@ RSpec.describe 'Epic show', :js do
it
'shows labels list view when back button is clicked from create view'
do
page
.
within
(
'.js-labels-block'
)
do
find
(
'a'
,
text:
'Create group label'
).
click
click_on
'Create group label'
find
(
'.js-btn-back'
).
click
wait_for_requests
...
...
ee/spec/features/epics/shortcuts_epic_spec.rb
View file @
6b91dfd0
...
...
@@ -30,7 +30,7 @@ RSpec.describe 'Epic shortcuts', :js do
it
"opens labels dropdown for editing"
do
find
(
'body'
).
native
.
send_key
(
'l'
)
expect
(
find
(
'.js-labels-block'
)).
to
have_selector
(
'
.labels-select-dropdown-contents
'
)
expect
(
find
(
'.js-labels-block'
)).
to
have_selector
(
'
[data-testid="labels-select-dropdown-contents"]
'
)
end
end
...
...
spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js
View file @
6b91dfd0
...
...
@@ -5,8 +5,7 @@ import VueApollo from 'vue-apollo';
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
createFlash
from
'
~/flash
'
;
import
{
IssuableType
}
from
'
~/issue_show/constants
'
;
import
{
labelsQueries
}
from
'
~/sidebar/constants
'
;
import
{
workspaceLabelsQueries
}
from
'
~/sidebar/constants
'
;
import
DropdownContentsCreateView
from
'
~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue
'
;
import
createLabelMutation
from
'
~/vue_shared/components/sidebar/labels_select_widget/graphql/create_label.mutation.graphql
'
;
import
{
...
...
@@ -50,12 +49,12 @@ describe('DropdownContentsCreateView', () => {
const
createComponent
=
({
mutationHandler
=
createLabelSuccessHandler
,
issuableType
=
IssuableType
.
Issue
,
labelType
=
'
ProjectLabel
'
,
labelCreateType
=
'
project
'
,
workspaceType
=
'
project
'
,
}
=
{})
=>
{
const
mockApollo
=
createMockApollo
([[
createLabelMutation
,
mutationHandler
]]);
mockApollo
.
clients
.
defaultClient
.
cache
.
writeQuery
({
query
:
labelsQueries
[
issuableType
].
workspaceQ
uery
,
query
:
workspaceLabelsQueries
[
workspaceType
].
q
uery
,
data
:
workspaceLabelsQueryResponse
.
data
,
variables
:
{
fullPath
:
''
,
...
...
@@ -67,10 +66,10 @@ describe('DropdownContentsCreateView', () => {
localVue
,
apolloProvider
:
mockApollo
,
propsData
:
{
issuableType
,
fullPath
:
''
,
attrWorkspacePath
:
''
,
labelType
,
labelCreateType
,
workspaceType
,
},
});
};
...
...
@@ -131,9 +130,11 @@ describe('DropdownContentsCreateView', () => {
it
(
'
emits a `hideCreateView` event on Cancel button click
'
,
()
=>
{
createComponent
();
findCancelButton
().
vm
.
$emit
(
'
click
'
);
const
event
=
{
stopPropagation
:
jest
.
fn
()
};
findCancelButton
().
vm
.
$emit
(
'
click
'
,
event
);
expect
(
wrapper
.
emitted
(
'
hideCreateView
'
)).
toHaveLength
(
1
);
expect
(
event
.
stopPropagation
).
toHaveBeenCalled
();
});
describe
(
'
when label title and selected color are set
'
,
()
=>
{
...
...
@@ -177,7 +178,7 @@ describe('DropdownContentsCreateView', () => {
});
it
(
'
calls a mutation with `groupPath` variable on the epic
'
,
()
=>
{
createComponent
({
issuableType
:
IssuableType
.
Epic
,
labelType
:
'
GroupLabel
'
});
createComponent
({
labelCreateType
:
'
group
'
,
workspaceType
:
'
group
'
});
fillLabelAttributes
();
findCreateButton
().
vm
.
$emit
(
'
click
'
);
...
...
spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view_spec.js
View file @
6b91dfd0
...
...
@@ -59,6 +59,8 @@ describe('DropdownContentsLabelsView', () => {
localSelectedLabels
,
issuableType
:
IssuableType
.
Issue
,
searchKey
,
labelCreateType
:
'
project
'
,
workspaceType
:
'
project
'
,
},
stubs
:
{
GlSearchBoxByType
,
...
...
spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js
View file @
6b91dfd0
...
...
@@ -41,7 +41,8 @@ describe('DropdownContent', () => {
variant
:
'
sidebar
'
,
issuableType
:
'
issue
'
,
fullPath
:
'
test
'
,
labelType
:
'
ProjectLabel
'
,
workspaceType
:
'
project
'
,
labelCreateType
:
'
project
'
,
attrWorkspacePath
:
'
path
'
,
...
props
,
},
...
...
spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
View file @
6b91dfd0
...
...
@@ -41,7 +41,8 @@ describe('LabelsSelectRoot', () => {
propsData
:
{
...
config
,
issuableType
:
IssuableType
.
Issue
,
labelType
:
'
ProjectLabel
'
,
labelCreateType
:
'
project
'
,
workspaceType
:
'
project
'
,
},
stubs
:
{
SidebarEditableItem
,
...
...
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