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
43646d64
Commit
43646d64
authored
Feb 13, 2020
by
Kushal Pandya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use Vue Labels Select for Epics sidebar
Use pure Vue Labels Select dropdown for Epics sidebar.
parent
0f758429
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
324 additions
and
33 deletions
+324
-33
app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue
...mponents/sidebar/labels_select_vue/labels_select_root.vue
+24
-2
ee/app/assets/javascripts/behaviors/shortcuts/shortcuts_epic.js
.../assets/javascripts/behaviors/shortcuts/shortcuts_epic.js
+4
-1
ee/app/assets/javascripts/epic/components/sidebar_items/sidebar_labels.vue
...ascripts/epic/components/sidebar_items/sidebar_labels.vue
+21
-17
ee/app/assets/javascripts/epic/epic_bundle.js
ee/app/assets/javascripts/epic/epic_bundle.js
+2
-0
ee/app/assets/javascripts/epic/sidebar_context.js
ee/app/assets/javascripts/epic/sidebar_context.js
+7
-5
ee/app/assets/javascripts/epic/store/actions.js
ee/app/assets/javascripts/epic/store/actions.js
+41
-0
ee/app/assets/javascripts/epic/store/mutation_types.js
ee/app/assets/javascripts/epic/store/mutation_types.js
+4
-0
ee/app/assets/javascripts/epic/store/mutations.js
ee/app/assets/javascripts/epic/store/mutations.js
+16
-0
ee/app/assets/javascripts/epic/store/state.js
ee/app/assets/javascripts/epic/store/state.js
+1
-0
ee/spec/features/epics/epic_labels_spec.rb
ee/spec/features/epics/epic_labels_spec.rb
+1
-1
ee/spec/features/epics/shortcuts_epic_spec.rb
ee/spec/features/epics/shortcuts_epic_spec.rb
+1
-1
ee/spec/frontend/epic/components/sidebar_items/sidebar_labels_spec.js
...tend/epic/components/sidebar_items/sidebar_labels_spec.js
+10
-6
ee/spec/frontend/epic/store/actions_spec.js
ee/spec/frontend/epic/store/actions_spec.js
+124
-0
ee/spec/frontend/epic/store/mutations_spec.js
ee/spec/frontend/epic/store/mutations_spec.js
+65
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
No files found.
app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue
View file @
43646d64
...
@@ -122,9 +122,14 @@ export default {
...
@@ -122,9 +122,14 @@ export default {
this
.
$store
.
subscribeAction
({
this
.
$store
.
subscribeAction
({
after
:
this
.
handleVuexActionDispatch
,
after
:
this
.
handleVuexActionDispatch
,
});
});
document
.
addEventListener
(
'
click
'
,
this
.
handleDocumentClick
);
},
beforeDestroy
()
{
document
.
removeEventListener
(
'
click
'
,
this
.
handleDocumentClick
);
},
},
methods
:
{
methods
:
{
...
mapActions
([
'
setInitialState
'
]),
...
mapActions
([
'
setInitialState
'
,
'
toggleDropdownContents
'
]),
/**
/**
* This method differentiates between
* This method differentiates between
* dispatched actions and calls necessary method.
* dispatched actions and calls necessary method.
...
@@ -138,6 +143,22 @@ export default {
...
@@ -138,6 +143,22 @@ export default {
this
.
handleDropdownClose
(
state
.
labels
.
filter
(
label
=>
label
.
touched
));
this
.
handleDropdownClose
(
state
.
labels
.
filter
(
label
=>
label
.
touched
));
}
}
},
},
/**
* This method listens for document-wide click event
* and toggle dropdown if user clicks anywhere outside
* the dropdown while dropdown is visible.
*/
handleDocumentClick
({
target
})
{
if
(
this
.
showDropdownButton
&&
this
.
showDropdownContents
&&
!
target
?.
classList
.
contains
(
'
js-sidebar-dropdown-toggle
'
)
&&
!
this
.
$refs
.
dropdownButtonCollapsed
?.
$el
.
contains
(
target
)
&&
!
this
.
$refs
.
dropdownContents
?.
$el
.
contains
(
target
)
)
{
this
.
toggleDropdownContents
();
}
},
handleDropdownClose
(
labels
)
{
handleDropdownClose
(
labels
)
{
// Only emit label updates if there are any labels to update
// Only emit label updates if there are any labels to update
// on UI.
// on UI.
...
@@ -156,6 +177,7 @@ export default {
...
@@ -156,6 +177,7 @@ export default {
<div
v-if=
"!dropdownOnly"
>
<div
v-if=
"!dropdownOnly"
>
<dropdown-value-collapsed
<dropdown-value-collapsed
v-if=
"allowLabelCreate"
v-if=
"allowLabelCreate"
ref=
"dropdownButtonCollapsed"
:labels=
"selectedLabels"
:labels=
"selectedLabels"
@
onValueClick=
"handleCollapsedValueClick"
@
onValueClick=
"handleCollapsedValueClick"
/>
/>
...
@@ -167,7 +189,7 @@ export default {
...
@@ -167,7 +189,7 @@ export default {
<slot></slot>
<slot></slot>
</dropdown-value>
</dropdown-value>
<dropdown-button
v-show=
"showDropdownButton"
/>
<dropdown-button
v-show=
"showDropdownButton"
/>
<dropdown-contents
v-if=
"showDropdownButton && showDropdownContents"
/>
<dropdown-contents
v-if=
"showDropdownButton && showDropdownContents"
ref=
"dropdownContents"
/>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
ee/app/assets/javascripts/behaviors/shortcuts/shortcuts_epic.js
View file @
43646d64
...
@@ -21,7 +21,10 @@ export default class ShortcutsEpic extends ShortcutsIssuable {
...
@@ -21,7 +21,10 @@ export default class ShortcutsEpic extends ShortcutsIssuable {
if
(
parseBoolean
(
Cookies
.
get
(
'
collapsed_gutter
'
)))
{
if
(
parseBoolean
(
Cookies
.
get
(
'
collapsed_gutter
'
)))
{
document
.
dispatchEvent
(
new
Event
(
'
toggleSidebarRevealLabelsDropdown
'
));
document
.
dispatchEvent
(
new
Event
(
'
toggleSidebarRevealLabelsDropdown
'
));
}
else
{
}
else
{
$block
.
find
(
'
.js-sidebar-dropdown-toggle
'
).
trigger
(
'
click
'
);
$block
.
find
(
'
.js-sidebar-dropdown-toggle
'
)
.
get
(
0
)
.
dispatchEvent
(
new
Event
(
'
click
'
));
}
}
}
}
}
}
ee/app/assets/javascripts/epic/components/sidebar_items/sidebar_labels.vue
View file @
43646d64
...
@@ -4,11 +4,11 @@ import _ from 'underscore';
...
@@ -4,11 +4,11 @@ import _ from 'underscore';
import
ListLabel
from
'
../../models/label
'
;
import
ListLabel
from
'
../../models/label
'
;
import
LabelsSelect
from
'
~/vue_shared/components/sidebar/labels_select/base
.vue
'
;
import
LabelsSelect
Vue
from
'
~/vue_shared/components/sidebar/labels_select_vue/labels_select_root
.vue
'
;
export
default
{
export
default
{
components
:
{
components
:
{
LabelsSelect
,
LabelsSelect
Vue
,
},
},
props
:
{
props
:
{
canUpdate
:
{
canUpdate
:
{
...
@@ -27,6 +27,7 @@ export default {
...
@@ -27,6 +27,7 @@ export default {
},
},
computed
:
{
computed
:
{
...
mapState
([
...
mapState
([
'
epicId
'
,
'
labels
'
,
'
labels
'
,
'
namespace
'
,
'
namespace
'
,
'
updateEndpoint
'
,
'
updateEndpoint
'
,
...
@@ -35,6 +36,7 @@ export default {
...
@@ -35,6 +36,7 @@ export default {
'
epicsWebUrl
'
,
'
epicsWebUrl
'
,
'
scopedLabels
'
,
'
scopedLabels
'
,
'
scopedLabelsDocumentationLink
'
,
'
scopedLabelsDocumentationLink
'
,
'
epicLabelsSelectInProgress
'
,
]),
]),
epicContext
()
{
epicContext
()
{
return
{
return
{
...
@@ -55,7 +57,7 @@ export default {
...
@@ -55,7 +57,7 @@ export default {
);
);
},
},
methods
:
{
methods
:
{
...
mapActions
([
'
toggleSidebar
'
]),
...
mapActions
([
'
toggleSidebar
'
,
'
updateEpicLabels
'
]),
toggleSidebarRevealLabelsDropdown
()
{
toggleSidebarRevealLabelsDropdown
()
{
const
contentContainer
=
this
.
$el
.
closest
(
'
.page-with-contextual-sidebar
'
);
const
contentContainer
=
this
.
$el
.
closest
(
'
.page-with-contextual-sidebar
'
);
this
.
toggleSidebar
({
sidebarCollapsed
:
this
.
sidebarCollapsed
});
this
.
toggleSidebar
({
sidebarCollapsed
:
this
.
sidebarCollapsed
});
...
@@ -99,26 +101,28 @@ export default {
...
@@ -99,26 +101,28 @@ export default {
}
}
}
}
},
},
handleUpdateSelectedLabels
(
labels
)
{
this
.
updateEpicLabels
(
labels
);
},
},
},
};
};
</
script
>
</
script
>
<
template
>
<
template
>
<labels-select
<labels-select-vue
:can-edit=
"canUpdate"
:allow-label-edit=
"canUpdate"
:context=
"epicContext"
:allow-label-create=
"true"
:namespace=
"namespace"
:allow-scoped-labels=
"scopedLabels"
:update-path=
"updateEndpoint"
:selected-labels=
"labels"
:labels-path=
"labelsPath"
:labels-select-in-progress=
"epicLabelsSelectInProgress"
:labels-web-url=
"labelsWebUrl"
:labels-fetch-path=
"labelsPath"
:label-filter-base-path=
"epicsWebUrl"
:labels-manage-path=
"labelsWebUrl"
:show-create=
"true"
:labels-filter-base-path=
"epicsWebUrl"
:enable-scoped-labels=
"scopedLabels"
:scoped-labels-documentation-path=
"scopedLabelsDocumentationLink"
:scoped-labels-documentation-link=
"scopedLabelsDocumentationLink"
class=
"block labels js-labels-block"
ability-name=
"epic"
@
updateSelectedLabels=
"handleUpdateSelectedLabels"
@
onLabelClick=
"handleLabelClick"
@
onDropdownClose=
"handleDropdownClose"
@
onDropdownClose=
"handleDropdownClose"
@
toggleCollapse=
"toggleSidebarRevealLabelsDropdown"
@
toggleCollapse=
"toggleSidebarRevealLabelsDropdown"
>
{{
__
(
'
None
'
)
}}
</labels-select
>
{{
__
(
'
None
'
)
}}
</labels-select
-vue
>
>
</
template
>
</
template
>
ee/app/assets/javascripts/epic/epic_bundle.js
View file @
43646d64
...
@@ -4,6 +4,7 @@ import { mapActions } from 'vuex';
...
@@ -4,6 +4,7 @@ import { mapActions } from 'vuex';
import
Cookies
from
'
js-cookie
'
;
import
Cookies
from
'
js-cookie
'
;
import
{
GlBreakpointInstance
as
bp
}
from
'
@gitlab/ui/dist/utils
'
;
import
{
GlBreakpointInstance
as
bp
}
from
'
@gitlab/ui/dist/utils
'
;
import
{
convertObjectPropsToCamelCase
,
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
import
{
convertObjectPropsToCamelCase
,
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
import
labelsSelectModule
from
'
~/vue_shared/components/sidebar/labels_select_vue/store
'
;
import
createStore
from
'
./store
'
;
import
createStore
from
'
./store
'
;
import
EpicApp
from
'
./components/epic_app.vue
'
;
import
EpicApp
from
'
./components/epic_app.vue
'
;
...
@@ -17,6 +18,7 @@ export default (epicCreate = false) => {
...
@@ -17,6 +18,7 @@ export default (epicCreate = false) => {
}
}
const
store
=
createStore
();
const
store
=
createStore
();
store
.
registerModule
(
'
labelsSelect
'
,
labelsSelectModule
());
if
(
epicCreate
)
{
if
(
epicCreate
)
{
return
new
Vue
({
return
new
Vue
({
...
...
ee/app/assets/javascripts/epic/sidebar_context.js
View file @
43646d64
...
@@ -20,6 +20,7 @@ export default class SidebarContext {
...
@@ -20,6 +20,7 @@ export default class SidebarContext {
// which requires us to use `display: none;`
// which requires us to use `display: none;`
// in `labels_select/base.vue` as well.
// in `labels_select/base.vue` as well.
// see: https://gitlab.com/gitlab-org/gitlab/merge_requests/4773#note_61844731
// see: https://gitlab.com/gitlab-org/gitlab/merge_requests/4773#note_61844731
if
(
$selectbox
.
length
)
{
const
isVisible
=
Boolean
(
$selectbox
.
get
(
0
).
offsetParent
);
const
isVisible
=
Boolean
(
$selectbox
.
get
(
0
).
offsetParent
);
$selectbox
.
toggle
(
!
isVisible
);
$selectbox
.
toggle
(
!
isVisible
);
$block
.
find
(
'
.js-value
'
).
toggle
(
isVisible
);
$block
.
find
(
'
.js-value
'
).
toggle
(
isVisible
);
...
@@ -27,6 +28,7 @@ export default class SidebarContext {
...
@@ -27,6 +28,7 @@ export default class SidebarContext {
if
(
$selectbox
.
get
(
0
).
offsetParent
)
{
if
(
$selectbox
.
get
(
0
).
offsetParent
)
{
setTimeout
(()
=>
$block
.
find
(
'
.js-label-select
'
).
trigger
(
'
click
'
),
0
);
setTimeout
(()
=>
$block
.
find
(
'
.js-label-select
'
).
trigger
(
'
click
'
),
0
);
}
}
}
});
});
window
.
addEventListener
(
'
beforeunload
'
,
()
=>
{
window
.
addEventListener
(
'
beforeunload
'
,
()
=>
{
...
...
ee/app/assets/javascripts/epic/store/actions.js
View file @
43646d64
...
@@ -194,6 +194,47 @@ export const saveDate = ({ state, dispatch }, { dateType, dateTypeIsFixed, newDa
...
@@ -194,6 +194,47 @@ export const saveDate = ({ state, dispatch }, { dateType, dateTypeIsFixed, newDa
});
});
};
};
/**
* Methods to handle Epic labels selection from sidebar
*/
export
const
requestEpicLabelsSelect
=
({
commit
})
=>
commit
(
types
.
REQUEST_EPIC_LABELS_SELECT
);
export
const
receiveEpicLabelsSelectSuccess
=
({
commit
},
labels
)
=>
commit
(
types
.
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
,
labels
);
export
const
receiveEpicLabelsSelectFailure
=
({
commit
})
=>
{
commit
(
types
.
RECEIVE_EPIC_LABELS_SELECT_FAILURE
);
flash
(
s__
(
'
Epics|An error occurred while updating labels.
'
));
};
export
const
updateEpicLabels
=
({
dispatch
,
state
},
labels
)
=>
{
const
addLabelIds
=
labels
.
filter
(
label
=>
label
.
set
).
map
(
label
=>
label
.
id
);
const
removeLabelIds
=
labels
.
filter
(
label
=>
!
label
.
set
).
map
(
label
=>
label
.
id
);
const
updateEpicInput
=
{
iid
:
`
${
state
.
epicIid
}
`
,
groupPath
:
state
.
fullPath
,
addLabelIds
,
removeLabelIds
,
};
dispatch
(
'
requestEpicLabelsSelect
'
);
epicUtils
.
gqClient
.
mutate
({
mutation
:
updateEpic
,
variables
:
{
updateEpicInput
,
},
})
.
then
(({
data
})
=>
{
if
(
!
data
?.
updateEpic
?.
errors
.
length
)
{
dispatch
(
'
receiveEpicLabelsSelectSuccess
'
,
labels
);
}
else
{
// eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings
throw
new
Error
(
'
An error occurred while updating labels
'
);
}
})
.
catch
(()
=>
{
dispatch
(
'
receiveEpicLabelsSelectFailure
'
);
});
};
/**
/**
* Methods to handle Epic subscription (AKA Notifications) toggle from sidebar
* Methods to handle Epic subscription (AKA Notifications) toggle from sidebar
*/
*/
...
...
ee/app/assets/javascripts/epic/store/mutation_types.js
View file @
43646d64
...
@@ -25,3 +25,7 @@ export const REQUEST_EPIC_SUBSCRIPTION_TOGGLE_FAILURE = 'REQUEST_EPIC_SUBSCRIPTI
...
@@ -25,3 +25,7 @@ export const REQUEST_EPIC_SUBSCRIPTION_TOGGLE_FAILURE = 'REQUEST_EPIC_SUBSCRIPTI
export
const
SET_EPIC_CREATE_TITLE
=
'
SET_EPIC_CREATE_TITLE
'
;
export
const
SET_EPIC_CREATE_TITLE
=
'
SET_EPIC_CREATE_TITLE
'
;
export
const
REQUEST_EPIC_CREATE
=
'
REQUEST_EPIC_CREATE
'
;
export
const
REQUEST_EPIC_CREATE
=
'
REQUEST_EPIC_CREATE
'
;
export
const
REQUEST_EPIC_CREATE_FAILURE
=
'
REQUEST_EPIC_CREATE_FAILURE
'
;
export
const
REQUEST_EPIC_CREATE_FAILURE
=
'
REQUEST_EPIC_CREATE_FAILURE
'
;
export
const
REQUEST_EPIC_LABELS_SELECT
=
'
REQUEST_EPIC_LABELS_SELECT
'
;
export
const
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
=
'
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
'
;
export
const
RECEIVE_EPIC_LABELS_SELECT_FAILURE
=
'
RECEIVE_EPIC_LABELS_SELECT_FAILURE
'
;
ee/app/assets/javascripts/epic/store/mutations.js
View file @
43646d64
...
@@ -102,4 +102,20 @@ export default {
...
@@ -102,4 +102,20 @@ export default {
[
types
.
REQUEST_EPIC_CREATE_FAILURE
](
state
)
{
[
types
.
REQUEST_EPIC_CREATE_FAILURE
](
state
)
{
state
.
epicCreateInProgress
=
false
;
state
.
epicCreateInProgress
=
false
;
},
},
[
types
.
REQUEST_EPIC_LABELS_SELECT
](
state
)
{
state
.
epicLabelsSelectInProgress
=
true
;
},
[
types
.
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
](
state
,
labels
)
{
const
addedLabels
=
labels
.
filter
(
label
=>
label
.
set
);
const
removeLabelIds
=
labels
.
filter
(
label
=>
!
label
.
set
).
map
(
label
=>
label
.
id
);
const
updatedLabels
=
state
.
labels
.
filter
(
label
=>
!
removeLabelIds
.
includes
(
label
.
id
));
updatedLabels
.
push
(...
addedLabels
);
state
.
epicLabelsSelectInProgress
=
false
;
state
.
labels
=
updatedLabels
;
},
[
types
.
RECEIVE_EPIC_LABELS_SELECT_FAILURE
](
state
)
{
state
.
epicLabelsSelectInProgress
=
false
;
},
};
};
ee/app/assets/javascripts/epic/store/state.js
View file @
43646d64
...
@@ -66,6 +66,7 @@ export default () => ({
...
@@ -66,6 +66,7 @@ export default () => ({
epicTodoToggleInProgress
:
false
,
epicTodoToggleInProgress
:
false
,
epicStartDateSaveInProgress
:
false
,
epicStartDateSaveInProgress
:
false
,
epicDueDateSaveInProgress
:
false
,
epicDueDateSaveInProgress
:
false
,
epicLabelsSelectInProgress
:
false
,
epicSubscriptionToggleInProgress
:
false
,
epicSubscriptionToggleInProgress
:
false
,
epicCreateInProgress
:
false
,
epicCreateInProgress
:
false
,
sidebarCollapsed
:
false
,
sidebarCollapsed
:
false
,
...
...
ee/spec/features/epics/epic_labels_spec.rb
View file @
43646d64
...
@@ -51,7 +51,7 @@ describe 'Assign labels to an epic', :js do
...
@@ -51,7 +51,7 @@ describe 'Assign labels to an epic', :js do
it
'opens labels dropdown'
do
it
'opens labels dropdown'
do
page
.
within
(
'aside.right-sidebar'
)
do
page
.
within
(
'aside.right-sidebar'
)
do
expect
(
page
).
to
have_css
(
'.js-
selectbox .dropdown.show
'
)
expect
(
page
).
to
have_css
(
'.js-
labels-block .labels-select-dropdown-contents
'
)
end
end
end
end
...
...
ee/spec/features/epics/shortcuts_epic_spec.rb
View file @
43646d64
...
@@ -30,7 +30,7 @@ describe 'Epic shortcuts', :js do
...
@@ -30,7 +30,7 @@ describe 'Epic shortcuts', :js do
it
"opens labels dropdown for editing"
do
it
"opens labels dropdown for editing"
do
find
(
'body'
).
native
.
send_key
(
'l'
)
find
(
'body'
).
native
.
send_key
(
'l'
)
expect
(
find
(
'.js-labels-block'
)).
to
have_selector
(
'.
dropdown-menu-labels.show
'
)
expect
(
find
(
'.js-labels-block'
)).
to
have_selector
(
'.
labels-select-dropdown-contents
'
)
end
end
end
end
...
...
ee/spec/frontend/epic/components/sidebar_items/sidebar_labels_spec.js
View file @
43646d64
import
Vue
from
'
vue
'
;
import
Vue
x
from
'
vuex
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
SidebarLabels
from
'
ee/epic/components/sidebar_items/sidebar_labels.vue
'
;
import
SidebarLabels
from
'
ee/epic/components/sidebar_items/sidebar_labels.vue
'
;
import
createStore
from
'
ee/epic/store
'
;
import
createStore
from
'
ee/epic/store
'
;
import
{
mockEpicMeta
,
mockEpicData
,
mockLabels
}
from
'
../../mock_data
'
;
import
{
mockEpicMeta
,
mockEpicData
,
mockLabels
}
from
'
../../mock_data
'
;
const
localVue
=
createLocalVue
();
localVue
.
use
(
Vuex
);
describe
(
'
SidebarLabelsComponent
'
,
()
=>
{
describe
(
'
SidebarLabelsComponent
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
let
store
;
let
store
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
const
Component
=
Vue
.
extend
(
SidebarLabels
);
store
=
createStore
();
store
=
createStore
();
store
.
dispatch
(
'
setEpicMeta
'
,
mockEpicMeta
);
store
.
dispatch
(
'
setEpicMeta
'
,
mockEpicMeta
);
store
.
dispatch
(
'
setEpicData
'
,
mockEpicData
);
store
.
dispatch
(
'
setEpicData
'
,
mockEpicData
);
wrapper
=
mount
(
Component
,
{
wrapper
=
mount
(
SidebarLabels
,
{
propsData
:
{
canUpdate
:
false
,
sidebarCollapsed
:
false
},
propsData
:
{
canUpdate
:
false
,
sidebarCollapsed
:
false
},
store
,
store
,
stubs
:
{
stubs
:
{
...
@@ -63,7 +65,9 @@ describe('SidebarLabelsComponent', () => {
...
@@ -63,7 +65,9 @@ describe('SidebarLabelsComponent', () => {
it
(
'
calls `toggleSidebar` action only when `sidebarExpandedOnClick` prop is true
'
,
()
=>
{
it
(
'
calls `toggleSidebar` action only when `sidebarExpandedOnClick` prop is true
'
,
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
,
'
toggleSidebar
'
);
jest
.
spyOn
(
wrapper
.
vm
,
'
toggleSidebar
'
);
wrapper
.
vm
.
sidebarExpandedOnClick
=
true
;
wrapper
.
setData
({
sidebarExpandedOnClick
:
true
,
});
wrapper
.
vm
.
handleDropdownClose
();
wrapper
.
vm
.
handleDropdownClose
();
...
@@ -117,7 +121,7 @@ describe('SidebarLabelsComponent', () => {
...
@@ -117,7 +121,7 @@ describe('SidebarLabelsComponent', () => {
describe
(
'
template
'
,
()
=>
{
describe
(
'
template
'
,
()
=>
{
it
(
'
renders labels select element container
'
,
()
=>
{
it
(
'
renders labels select element container
'
,
()
=>
{
expect
(
wrapper
.
vm
.
$el
.
classList
.
contain
s
(
'
js-labels-block
'
)).
toBe
(
true
);
expect
(
wrapper
.
classe
s
(
'
js-labels-block
'
)).
toBe
(
true
);
});
});
});
});
});
});
ee/spec/frontend/epic/store/actions_spec.js
View file @
43646d64
...
@@ -801,6 +801,130 @@ describe('Epic Store Actions', () => {
...
@@ -801,6 +801,130 @@ describe('Epic Store Actions', () => {
});
});
});
});
describe
(
'
requestEpicLabelsSelect
'
,
()
=>
{
it
(
'
should set `state.epicLabelsSelectInProgress` flag to `true`
'
,
done
=>
{
testAction
(
actions
.
requestEpicLabelsSelect
,
{},
state
,
[{
type
:
'
REQUEST_EPIC_LABELS_SELECT
'
}],
[],
done
,
);
});
});
describe
(
'
receiveEpicLabelsSelectSuccess
'
,
()
=>
{
it
(
'
should set provided labels param to `state.labels`
'
,
done
=>
{
const
labels
=
[{
id
:
1
,
set
:
false
},
{
id
:
2
,
set
:
true
}];
testAction
(
actions
.
receiveEpicLabelsSelectSuccess
,
labels
,
state
,
[
{
type
:
'
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
'
,
payload
:
labels
,
},
],
[],
done
,
);
});
});
describe
(
'
receiveEpicLabelsSelectFailure
'
,
()
=>
{
beforeEach
(()
=>
{
setFixtures
(
'
<div class="flash-container"></div>
'
);
});
it
(
'
should set `state.epicLabelsSelectInProgress` flag to `false`
'
,
done
=>
{
testAction
(
actions
.
receiveEpicLabelsSelectFailure
,
{},
state
,
[{
type
:
'
RECEIVE_EPIC_LABELS_SELECT_FAILURE
'
}],
[],
done
,
);
});
it
(
'
should show flash error with message "An error occurred while updating labels."
'
,
()
=>
{
actions
.
receiveEpicLabelsSelectFailure
(
{
commit
:
()
=>
{},
},
{},
);
expect
(
document
.
querySelector
(
'
.flash-container .flash-text
'
).
innerText
.
trim
()).
toBe
(
'
An error occurred while updating labels.
'
,
);
});
});
describe
(
'
updateEpicLabels
'
,
()
=>
{
const
labels
=
[{
id
:
1
,
set
:
false
},
{
id
:
2
,
set
:
true
}];
it
(
'
dispatches `requestEpicLabelsSelect` and `receiveEpicLabelsSelectSuccess` actions when request succeeds
'
,
done
=>
{
jest
.
spyOn
(
epicUtils
.
gqClient
,
'
mutate
'
).
mockReturnValue
(
Promise
.
resolve
({
data
:
{
updateEpic
:
{
errors
:
[],
},
},
}),
);
testAction
(
actions
.
updateEpicLabels
,
labels
,
state
,
[],
[
{
type
:
'
requestEpicLabelsSelect
'
,
},
{
type
:
'
receiveEpicLabelsSelectSuccess
'
,
payload
:
labels
,
},
],
done
,
);
});
it
(
'
dispatches `requestEpicLabelsSelect` and `receiveEpicLabelsSelectFailure` actions when request fails
'
,
done
=>
{
jest
.
spyOn
(
epicUtils
.
gqClient
,
'
mutate
'
).
mockReturnValue
(
Promise
.
resolve
({
data
:
{
updateEpic
:
{
errors
:
[{
foo
:
1
}],
},
},
}),
);
testAction
(
actions
.
updateEpicLabels
,
labels
,
state
,
[],
[
{
type
:
'
requestEpicLabelsSelect
'
,
},
{
type
:
'
receiveEpicLabelsSelectFailure
'
,
},
],
done
,
);
});
});
describe
(
'
requestEpicSubscriptionToggle
'
,
()
=>
{
describe
(
'
requestEpicSubscriptionToggle
'
,
()
=>
{
it
(
'
should set `state.epicSubscriptionToggleInProgress` flag to `true`
'
,
done
=>
{
it
(
'
should set `state.epicSubscriptionToggleInProgress` flag to `true`
'
,
done
=>
{
testAction
(
testAction
(
...
...
ee/spec/frontend/epic/store/mutations_spec.js
View file @
43646d64
...
@@ -343,4 +343,69 @@ describe('Epic Store Mutations', () => {
...
@@ -343,4 +343,69 @@ describe('Epic Store Mutations', () => {
expect
(
state
.
epicCreateInProgress
).
toBe
(
false
);
expect
(
state
.
epicCreateInProgress
).
toBe
(
false
);
});
});
});
});
describe
(
'
REQUEST_EPIC_LABELS_SELECT
'
,
()
=>
{
it
(
'
Should set `epicLabelsSelectInProgress` flag on state to `true`
'
,
()
=>
{
const
state
=
{
epicLabelsSelectInProgress
:
false
,
};
mutations
[
types
.
REQUEST_EPIC_LABELS_SELECT
](
state
);
expect
(
state
.
epicLabelsSelectInProgress
).
toBe
(
true
);
});
});
describe
(
'
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
'
,
()
=>
{
it
(
'
Should update `labels` array on state when new labels are added
'
,
()
=>
{
const
addedLabels
=
[{
id
:
1
,
set
:
true
},
{
id
:
2
,
set
:
true
}];
const
state
=
{
labels
:
[],
};
mutations
[
types
.
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
](
state
,
addedLabels
);
expect
(
state
.
labels
).
toEqual
(
expect
.
arrayContaining
(
addedLabels
));
});
it
(
'
Should update `labels` array on state when existing labels are removed
'
,
()
=>
{
const
removedLabels
=
[{
id
:
1
,
set
:
false
}];
const
state
=
{
labels
:
[{
id
:
1
,
set
:
true
},
{
id
:
2
,
set
:
true
}],
};
mutations
[
types
.
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
](
state
,
removedLabels
);
expect
(
state
.
labels
).
toEqual
(
expect
.
arrayContaining
([{
id
:
2
,
set
:
true
}]));
});
it
(
'
Should update `labels` array on state when some labels are added and some are removed
'
,
()
=>
{
const
removedLabels
=
[{
id
:
1
,
set
:
false
}];
const
addedLabels
=
[{
id
:
3
,
set
:
true
}];
const
state
=
{
labels
:
[{
id
:
1
,
set
:
true
},
{
id
:
2
,
set
:
true
}],
};
mutations
[
types
.
RECEIVE_EPIC_LABELS_SELECT_SUCCESS
](
state
,
[
...
addedLabels
,
...
removedLabels
,
]);
expect
(
state
.
labels
).
toEqual
(
expect
.
arrayContaining
([{
id
:
2
,
set
:
true
},
{
id
:
3
,
set
:
true
}]),
);
});
});
describe
(
'
RECEIVE_EPIC_LABELS_SELECT_FAILURE
'
,
()
=>
{
it
(
'
Should set `epicLabelsSelectInProgress` flag on state to `false`
'
,
()
=>
{
const
state
=
{
epicLabelsSelectInProgress
:
true
,
};
mutations
[
types
.
RECEIVE_EPIC_LABELS_SELECT_FAILURE
](
state
);
expect
(
state
.
epicLabelsSelectInProgress
).
toBe
(
false
);
});
});
});
});
locale/gitlab.pot
View file @
43646d64
...
@@ -7795,6 +7795,9 @@ msgstr ""
...
@@ -7795,6 +7795,9 @@ msgstr ""
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgid "Epics|An error occurred while saving the %{epicDateType} date"
msgstr ""
msgstr ""
msgid "Epics|An error occurred while updating labels."
msgstr ""
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgid "Epics|Are you sure you want to remove %{bStart}%{targetIssueTitle}%{bEnd} from %{bStart}%{parentEpicTitle}%{bEnd}?"
msgstr ""
msgstr ""
...
...
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