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
5f1f6c53
Commit
5f1f6c53
authored
Sep 11, 2020
by
Florie Guibert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Swimlanes - Pagination Iteration 1
- Fetch issues per epic - Watch filters - Fetch unassigned issues per list
parent
dbb4abc3
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
458 additions
and
188 deletions
+458
-188
app/assets/javascripts/boards/ee_functions.js
app/assets/javascripts/boards/ee_functions.js
+1
-1
app/assets/javascripts/boards/index.js
app/assets/javascripts/boards/index.js
+6
-11
app/assets/javascripts/boards/stores/actions.js
app/assets/javascripts/boards/stores/actions.js
+2
-25
app/assets/javascripts/boards/stores/mutation_types.js
app/assets/javascripts/boards/stores/mutation_types.js
+1
-3
app/assets/javascripts/boards/stores/mutations.js
app/assets/javascripts/boards/stores/mutations.js
+12
-19
app/assets/javascripts/boards/stores/state.js
app/assets/javascripts/boards/stores/state.js
+0
-1
ee/app/assets/javascripts/boards/components/epic_lane.vue
ee/app/assets/javascripts/boards/components/epic_lane.vue
+23
-8
ee/app/assets/javascripts/boards/components/epics_swimlanes.vue
.../assets/javascripts/boards/components/epics_swimlanes.vue
+2
-7
ee/app/assets/javascripts/boards/components/issues_lane_list.vue
...assets/javascripts/boards/components/issues_lane_list.vue
+13
-8
ee/app/assets/javascripts/boards/ee_functions.js
ee/app/assets/javascripts/boards/ee_functions.js
+1
-1
ee/app/assets/javascripts/boards/stores/actions.js
ee/app/assets/javascripts/boards/stores/actions.js
+63
-1
ee/app/assets/javascripts/boards/stores/mutation_types.js
ee/app/assets/javascripts/boards/stores/mutation_types.js
+5
-0
ee/app/assets/javascripts/boards/stores/mutations.js
ee/app/assets/javascripts/boards/stores/mutations.js
+23
-3
ee/app/assets/javascripts/boards/stores/state.js
ee/app/assets/javascripts/boards/stores/state.js
+1
-1
ee/spec/frontend/boards/components/epic_lane_spec.js
ee/spec/frontend/boards/components/epic_lane_spec.js
+25
-7
ee/spec/frontend/boards/components/epics_swimlanes_spec.js
ee/spec/frontend/boards/components/epics_swimlanes_spec.js
+0
-4
ee/spec/frontend/boards/stores/actions_spec.js
ee/spec/frontend/boards/stores/actions_spec.js
+88
-4
ee/spec/frontend/boards/stores/mutations_spec.js
ee/spec/frontend/boards/stores/mutations_spec.js
+81
-9
locale/gitlab.pot
locale/gitlab.pot
+21
-18
spec/frontend/boards/components/board_content_spec.js
spec/frontend/boards/components/board_content_spec.js
+0
-3
spec/frontend/boards/stores/actions_spec.js
spec/frontend/boards/stores/actions_spec.js
+73
-1
spec/frontend/boards/stores/mutations_spec.js
spec/frontend/boards/stores/mutations_spec.js
+17
-53
No files found.
app/assets/javascripts/boards/ee_functions.js
View file @
5f1f6c53
export
const
setPromotionState
=
()
=>
{};
export
const
setWeig
th
FetchingState
=
()
=>
{};
export
const
setWeig
ht
FetchingState
=
()
=>
{};
export
const
setEpicFetchingState
=
()
=>
{};
export
const
getMilestoneTitle
=
()
=>
({});
...
...
app/assets/javascripts/boards/index.js
View file @
5f1f6c53
...
...
@@ -11,7 +11,7 @@ import toggleLabels from 'ee_else_ce/boards/toggle_labels';
import
toggleEpicsSwimlanes
from
'
ee_else_ce/boards/toggle_epics_swimlanes
'
;
import
{
setPromotionState
,
setWeig
th
FetchingState
,
setWeig
ht
FetchingState
,
setEpicFetchingState
,
getMilestoneTitle
,
getBoardsModalData
,
...
...
@@ -163,12 +163,7 @@ export default () => {
}
},
methods
:
{
...
mapActions
([
'
setInitialBoardData
'
,
'
setFilters
'
,
'
fetchEpicsSwimlanes
'
,
'
fetchIssuesForAllLists
'
,
]),
...
mapActions
([
'
setInitialBoardData
'
,
'
setFilters
'
,
'
fetchEpicsSwimlanes
'
,
'
resetIssues
'
]),
updateTokens
()
{
this
.
filterManager
.
updateTokens
();
},
...
...
@@ -176,14 +171,14 @@ export default () => {
this
.
setFilters
(
convertObjectPropsToCamelCase
(
urlParamsToObject
(
window
.
location
.
search
)));
if
(
gon
.
features
.
boardsWithSwimlanes
&&
this
.
isShowingEpicsSwimlanes
)
{
this
.
fetchEpicsSwimlanes
(
false
);
this
.
fetchIssuesForAllList
s
();
this
.
resetIssue
s
();
}
},
updateDetailIssue
(
newIssue
,
multiSelect
=
false
)
{
const
{
sidebarInfoEndpoint
}
=
newIssue
;
if
(
sidebarInfoEndpoint
&&
newIssue
.
subscribed
===
undefined
)
{
newIssue
.
setFetchingState
(
'
subscriptions
'
,
true
);
setWeig
th
FetchingState
(
newIssue
,
true
);
setWeig
ht
FetchingState
(
newIssue
,
true
);
setEpicFetchingState
(
newIssue
,
true
);
boardsStore
.
getIssueInfo
(
sidebarInfoEndpoint
)
...
...
@@ -201,7 +196,7 @@ export default () => {
}
=
convertObjectPropsToCamelCase
(
data
);
newIssue
.
setFetchingState
(
'
subscriptions
'
,
false
);
setWeig
th
FetchingState
(
newIssue
,
false
);
setWeig
ht
FetchingState
(
newIssue
,
false
);
setEpicFetchingState
(
newIssue
,
false
);
newIssue
.
updateData
({
humanTimeSpent
:
humanTotalTimeSpent
,
...
...
@@ -216,7 +211,7 @@ export default () => {
})
.
catch
(()
=>
{
newIssue
.
setFetchingState
(
'
subscriptions
'
,
false
);
setWeig
th
FetchingState
(
newIssue
,
false
);
setWeig
ht
FetchingState
(
newIssue
,
false
);
Flash
(
__
(
'
An error occurred while fetching sidebar data
'
));
});
}
...
...
app/assets/javascripts/boards/stores/actions.js
View file @
5f1f6c53
...
...
@@ -226,31 +226,8 @@ export default {
.
catch
(()
=>
commit
(
types
.
RECEIVE_ISSUES_FOR_LIST_FAILURE
,
listId
));
},
fetchIssuesForAllLists
:
({
state
,
commit
})
=>
{
commit
(
types
.
REQUEST_ISSUES_FOR_ALL_LISTS
);
const
{
endpoints
,
boardType
,
filterParams
}
=
state
;
const
{
fullPath
,
boardId
}
=
endpoints
;
const
variables
=
{
fullPath
,
boardId
:
fullBoardId
(
boardId
),
filters
:
filterParams
,
isGroup
:
boardType
===
BoardType
.
group
,
isProject
:
boardType
===
BoardType
.
project
,
};
return
gqlClient
.
query
({
query
:
listsIssuesQuery
,
variables
,
})
.
then
(({
data
})
=>
{
const
{
lists
}
=
data
[
boardType
]?.
board
;
const
listIssues
=
formatListIssues
(
lists
);
commit
(
types
.
RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS
,
listIssues
);
})
.
catch
(()
=>
commit
(
types
.
RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE
));
resetIssues
:
({
commit
})
=>
{
commit
(
types
.
RESET_ISSUES
);
},
moveIssue
:
(
...
...
app/assets/javascripts/boards/stores/mutation_types.js
View file @
5f1f6c53
...
...
@@ -12,11 +12,8 @@ export const UPDATE_LIST_FAILURE = 'UPDATE_LIST_FAILURE';
export
const
REQUEST_REMOVE_LIST
=
'
REQUEST_REMOVE_LIST
'
;
export
const
RECEIVE_REMOVE_LIST_SUCCESS
=
'
RECEIVE_REMOVE_LIST_SUCCESS
'
;
export
const
RECEIVE_REMOVE_LIST_ERROR
=
'
RECEIVE_REMOVE_LIST_ERROR
'
;
export
const
REQUEST_ISSUES_FOR_ALL_LISTS
=
'
REQUEST_ISSUES_FOR_ALL_LISTS
'
;
export
const
RECEIVE_ISSUES_FOR_LIST_FAILURE
=
'
RECEIVE_ISSUES_FOR_LIST_FAILURE
'
;
export
const
RECEIVE_ISSUES_FOR_LIST_SUCCESS
=
'
RECEIVE_ISSUES_FOR_LIST_SUCCESS
'
;
export
const
RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS
=
'
RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS
'
;
export
const
RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE
=
'
RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE
'
;
export
const
REQUEST_ADD_ISSUE
=
'
REQUEST_ADD_ISSUE
'
;
export
const
RECEIVE_ADD_ISSUE_SUCCESS
=
'
RECEIVE_ADD_ISSUE_SUCCESS
'
;
export
const
RECEIVE_ADD_ISSUE_ERROR
=
'
RECEIVE_ADD_ISSUE_ERROR
'
;
...
...
@@ -32,3 +29,4 @@ export const SET_CURRENT_PAGE = 'SET_CURRENT_PAGE';
export
const
TOGGLE_EMPTY_STATE
=
'
TOGGLE_EMPTY_STATE
'
;
export
const
SET_ACTIVE_ID
=
'
SET_ACTIVE_ID
'
;
export
const
UPDATE_ISSUE_BY_ID
=
'
UPDATE_ISSUE_BY_ID
'
;
export
const
RESET_ISSUES
=
'
RESET_ISSUES
'
;
app/assets/javascripts/boards/stores/mutations.js
View file @
5f1f6c53
...
...
@@ -2,7 +2,7 @@ import Vue from 'vue';
import
{
sortBy
,
pull
}
from
'
lodash
'
;
import
{
formatIssue
,
moveIssueListHelper
}
from
'
../boards_util
'
;
import
*
as
mutationTypes
from
'
./mutation_types
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
s
__
}
from
'
~/locale
'
;
import
{
getIdFromGraphQLId
}
from
'
~/graphql_shared/utils
'
;
const
notImplemented
=
()
=>
{
...
...
@@ -49,7 +49,7 @@ export default {
},
[
mutationTypes
.
CREATE_LIST_FAILURE
]:
state
=>
{
state
.
error
=
__
(
'
An error occurred while creating the list. Please try again.
'
);
state
.
error
=
s__
(
'
Boards|
An error occurred while creating the list. Please try again.
'
);
},
[
mutationTypes
.
REQUEST_ADD_LIST
]:
()
=>
{
...
...
@@ -73,7 +73,7 @@ export default {
},
[
mutationTypes
.
UPDATE_LIST_FAILURE
]:
(
state
,
backupList
)
=>
{
state
.
error
=
__
(
'
An error occurred while updating the list. Please try again.
'
);
state
.
error
=
s__
(
'
Boards|
An error occurred while updating the list. Please try again.
'
);
Vue
.
set
(
state
,
'
boardLists
'
,
backupList
);
},
...
...
@@ -98,19 +98,17 @@ export default {
},
[
mutationTypes
.
RECEIVE_ISSUES_FOR_LIST_FAILURE
]:
(
state
,
listId
)
=>
{
state
.
error
=
__
(
'
An error occurred while fetching the board issues. Please reload the page.
'
);
state
.
error
=
s__
(
'
Boards|An error occurred while fetching the board issues. Please reload the page.
'
,
);
const
listIndex
=
state
.
boardLists
.
findIndex
(
l
=>
l
.
id
===
listId
);
Vue
.
set
(
state
.
boardLists
[
listIndex
],
'
loading
'
,
false
);
},
[
mutationTypes
.
REQUEST_ISSUES_FOR_ALL_LISTS
]:
state
=>
{
state
.
isLoadingIssues
=
true
;
},
[
mutationTypes
.
RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS
]:
(
state
,
{
listData
,
issues
})
=>
{
state
.
issuesByListId
=
listData
;
state
.
issues
=
issues
;
state
.
isLoadingIssues
=
false
;
[
mutationTypes
.
RESET_ISSUES
]:
state
=>
{
Object
.
keys
(
state
.
issuesByListId
).
forEach
(
listId
=>
{
Vue
.
set
(
state
.
issuesByListId
,
listId
,
[]);
});
},
[
mutationTypes
.
UPDATE_ISSUE_BY_ID
]:
(
state
,
{
issueId
,
prop
,
value
})
=>
{
...
...
@@ -122,11 +120,6 @@ export default {
Vue
.
set
(
state
.
issues
[
issueId
],
prop
,
value
);
},
[
mutationTypes
.
RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE
]:
state
=>
{
state
.
error
=
__
(
'
An error occurred while fetching the board issues. Please reload the page.
'
);
state
.
isLoadingIssues
=
false
;
},
[
mutationTypes
.
REQUEST_ADD_ISSUE
]:
()
=>
{
notImplemented
();
},
...
...
@@ -162,7 +155,7 @@ export default {
state
,
{
originalIssue
,
fromListId
,
toListId
,
originalIndex
},
)
=>
{
state
.
error
=
__
(
'
An error occurred while moving the issue. Please try again.
'
);
state
.
error
=
s__
(
'
Boards|
An error occurred while moving the issue. Please try again.
'
);
Vue
.
set
(
state
.
issues
,
originalIssue
.
id
,
originalIssue
);
removeIssueFromList
(
state
,
toListId
,
originalIssue
.
id
);
addIssueToList
({
...
...
@@ -193,7 +186,7 @@ export default {
},
[
mutationTypes
.
ADD_ISSUE_TO_LIST_FAILURE
]:
(
state
,
{
list
,
issue
})
=>
{
state
.
error
=
__
(
'
An error occurred while creating the issue. Please try again.
'
);
state
.
error
=
s__
(
'
Boards|
An error occurred while creating the issue. Please try again.
'
);
removeIssueFromList
(
state
,
list
.
id
,
issue
.
id
);
},
...
...
app/assets/javascripts/boards/stores/state.js
View file @
5f1f6c53
...
...
@@ -11,7 +11,6 @@ export default () => ({
boardLists
:
[],
issuesByListId
:
{},
issues
:
{},
isLoadingIssues
:
false
,
filterParams
:
{},
error
:
undefined
,
// TODO: remove after ce/ee split of board_content.vue
...
...
ee/app/assets/javascripts/boards/components/epic_lane.vue
View file @
5f1f6c53
<
script
>
import
{
GlButton
,
GlIcon
,
GlLink
,
GlPopover
,
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
map
Getters
}
from
'
vuex
'
;
import
{
GlButton
,
GlIcon
,
GlLink
,
Gl
LoadingIcon
,
Gl
Popover
,
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
map
Actions
,
mapGetters
,
mapState
}
from
'
vuex
'
;
import
{
__
,
n__
,
sprintf
}
from
'
~/locale
'
;
import
timeagoMixin
from
'
~/vue_shared/mixins/timeago
'
;
import
{
formatDate
}
from
'
~/lib/utils/datetime_utility
'
;
...
...
@@ -12,6 +12,7 @@ export default {
GlButton
,
GlIcon
,
GlLink
,
GlLoadingIcon
,
GlPopover
,
IssuesLaneList
,
},
...
...
@@ -28,11 +29,6 @@ export default {
type
:
Array
,
required
:
true
,
},
isLoadingIssues
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
disabled
:
{
type
:
Boolean
,
required
:
true
,
...
...
@@ -49,6 +45,7 @@ export default {
};
},
computed
:
{
...
mapState
([
'
epicsFlags
'
,
'
filterParams
'
]),
...
mapGetters
([
'
getIssuesByEpic
'
]),
isOpen
()
{
return
this
.
epic
.
state
===
statusType
.
open
;
...
...
@@ -89,8 +86,25 @@ export default {
epicDateString
()
{
return
formatDate
(
this
.
epic
.
createdAt
);
},
isLoading
()
{
return
Boolean
(
this
.
epicsFlags
[
this
.
epic
.
id
]?.
isLoading
);
},
},
watch
:
{
filterParams
:
{
handler
()
{
if
(
!
this
.
filterParams
.
epicId
||
this
.
filterParams
.
epicId
===
this
.
epic
.
id
)
{
this
.
fetchIssuesForEpic
(
this
.
epic
.
id
);
}
},
deep
:
true
,
},
},
mounted
()
{
this
.
fetchIssuesForEpic
(
this
.
epic
.
id
);
},
methods
:
{
...
mapActions
([
'
fetchIssuesForEpic
'
]),
toggleExpanded
()
{
this
.
isExpanded
=
!
this
.
isExpanded
;
},
...
...
@@ -133,6 +147,7 @@ export default {
<gl-link
:href=
"epic.webUrl"
class=
"gl-font-sm"
>
{{ __('Go to epic') }}
</gl-link>
</gl-popover>
<span
v-if=
"!isLoading"
v-gl-tooltip
.
hover
:title=
"issuesCountTooltipText"
class=
"gl-display-flex gl-align-items-center gl-text-gray-500"
...
...
@@ -143,6 +158,7 @@ export default {
<gl-icon
class=
"gl-mr-2 gl-flex-shrink-0"
name=
"issues"
aria-hidden=
"true"
/>
<span
aria-hidden=
"true"
>
{{ issuesCount }}
</span>
</span>
<gl-loading-icon
v-if=
"isLoading"
class=
"gl-p-2"
/>
</div>
</div>
<div
v-if=
"isExpanded"
class=
"gl-display-flex"
>
...
...
@@ -151,7 +167,6 @@ export default {
:key=
"`${list.id}-issues`"
:list=
"list"
:issues=
"getIssuesByEpic(list.id, epic.id)"
:is-loading=
"isLoadingIssues"
:disabled=
"disabled"
:epic-id=
"epic.id"
:epic-is-confidential=
"epic.confidential"
...
...
ee/app/assets/javascripts/boards/components/epics_swimlanes.vue
View file @
5f1f6c53
...
...
@@ -35,7 +35,7 @@ export default {
},
},
computed
:
{
...
mapState
([
'
epics
'
,
'
isLoadingIssues
'
]),
...
mapState
([
'
epics
'
]),
...
mapGetters
([
'
getUnassignedIssues
'
]),
unassignedIssues
()
{
return
listId
=>
this
.
getUnassignedIssues
(
listId
);
...
...
@@ -66,11 +66,8 @@ export default {
return
this
.
canAdminList
?
options
:
{};
},
},
mounted
()
{
this
.
fetchIssuesForAllLists
();
},
methods
:
{
...
mapActions
([
'
fetchIssuesForAllLists
'
,
'
moveList
'
]),
...
mapActions
([
'
moveList
'
]),
handleDragOnEnd
(
params
)
{
const
{
newIndex
,
oldIndex
,
item
}
=
params
;
const
{
listId
}
=
item
.
dataset
;
...
...
@@ -122,7 +119,6 @@ export default {
:key=
"epic.id"
:epic=
"epic"
:lists=
"lists"
:is-loading-issues=
"isLoadingIssues"
:disabled=
"disabled"
:can-admin-list=
"canAdminList"
/>
...
...
@@ -153,7 +149,6 @@ export default {
:list="list"
:issues="unassignedIssues(list.id)"
:is-unassigned-issues-lane="true"
:is-loading="isLoadingIssues"
:disabled="disabled"
:can-admin-list="canAdminList"
/>
...
...
ee/app/assets/javascripts/boards/components/issues_lane_list.vue
View file @
5f1f6c53
...
...
@@ -33,11 +33,6 @@ export default {
required
:
false
,
default
:
false
,
},
isLoading
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
canAdminList
:
{
type
:
Boolean
,
required
:
false
,
...
...
@@ -50,7 +45,7 @@ export default {
};
},
computed
:
{
...
mapState
([
'
activeId
'
]),
...
mapState
([
'
activeId
'
,
'
filterParams
'
]),
treeRootWrapper
()
{
return
this
.
canAdminList
?
Draggable
:
'
ul
'
;
},
...
...
@@ -68,6 +63,17 @@ export default {
return
this
.
canAdminList
?
options
:
{};
},
},
watch
:
{
filterParams
:
{
handler
()
{
if
(
this
.
isUnassignedIssuesLane
)
{
this
.
fetchIssuesForList
(
this
.
list
.
id
);
}
},
deep
:
true
,
immediate
:
true
,
},
},
created
()
{
eventHub
.
$on
(
`toggle-issue-form-
${
this
.
list
.
id
}
`
,
this
.
toggleForm
);
},
...
...
@@ -75,7 +81,7 @@ export default {
eventHub
.
$off
(
`toggle-issue-form-
${
this
.
list
.
id
}
`
,
this
.
toggleForm
);
},
methods
:
{
...
mapActions
([
'
setActiveId
'
,
'
moveIssue
'
]),
...
mapActions
([
'
setActiveId
'
,
'
moveIssue
'
,
'
fetchIssuesForList
'
]),
toggleForm
()
{
this
.
showIssueForm
=
!
this
.
showIssueForm
;
if
(
this
.
showIssueForm
&&
this
.
isUnassignedIssuesLane
)
{
...
...
@@ -138,7 +144,6 @@ export default {
:class=
"
{ 'is-collapsed': !list.isExpanded }"
>
<div
class=
"board-inner gl-rounded-base gl-relative gl-w-full"
>
<gl-loading-icon
v-if=
"isLoading"
class=
"gl-p-2"
/>
<board-new-issue
v-if=
"list.type !== 'closed' && showIssueForm && isUnassignedIssuesLane"
:list=
"list"
...
...
ee/app/assets/javascripts/boards/ee_functions.js
View file @
5f1f6c53
...
...
@@ -2,7 +2,7 @@ export const setPromotionState = store => {
store
.
addPromotionState
();
};
export
const
setWeig
th
FetchingState
=
(
issue
,
value
)
=>
{
export
const
setWeig
ht
FetchingState
=
(
issue
,
value
)
=>
{
issue
.
setFetchingState
(
'
weight
'
,
value
);
};
export
const
setEpicFetchingState
=
(
issue
,
value
)
=>
{
...
...
ee/app/assets/javascripts/boards/stores/actions.js
View file @
5f1f6c53
...
...
@@ -10,16 +10,45 @@ import { EpicFilterType } from '../constants';
import
boardsStoreEE
from
'
./boards_store_ee
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
{
fullEpicId
}
from
'
../boards_util
'
;
import
{
formatListIssues
,
fullBoardId
}
from
'
~/boards/boards_util
'
;
import
createDefaultClient
from
'
~/lib/graphql
'
;
import
epicsSwimlanesQuery
from
'
../queries/epics_swimlanes.query.graphql
'
;
import
listsIssuesQuery
from
'
~/boards/queries/lists_issues.query.graphql
'
;
const
notImplemented
=
()
=>
{
/* eslint-disable-next-line @gitlab/require-i18n-strings */
throw
new
Error
(
'
Not implemented!
'
);
};
const
gqlClient
=
createDefaultClient
();
export
const
gqlClient
=
createDefaultClient
();
const
fetchAndFormatListIssues
=
(
state
,
extraVariables
)
=>
{
const
{
endpoints
,
boardType
,
filterParams
}
=
state
;
const
{
fullPath
,
boardId
}
=
endpoints
;
const
variables
=
{
...
extraVariables
,
fullPath
,
boardId
:
fullBoardId
(
boardId
),
filters
:
{
...
filterParams
},
isGroup
:
boardType
===
BoardType
.
group
,
isProject
:
boardType
===
BoardType
.
project
,
};
return
gqlClient
.
query
({
query
:
listsIssuesQuery
,
context
:
{
isSingleRequest
:
true
,
},
variables
,
})
.
then
(({
data
})
=>
{
const
{
lists
}
=
data
[
boardType
]?.
board
;
return
formatListIssues
(
lists
);
});
};
export
default
{
...
actionsCE
,
...
...
@@ -139,6 +168,39 @@ export default {
notImplemented
();
},
fetchIssuesForList
:
({
state
,
commit
},
listId
,
noEpicIssues
=
false
)
=>
{
const
{
filterParams
}
=
state
;
const
variables
=
{
id
:
listId
,
filters
:
noEpicIssues
?
{
...
filterParams
,
epicWildcardId
:
EpicFilterType
.
none
}
:
filterParams
,
};
return
fetchAndFormatListIssues
(
state
,
variables
)
.
then
(
listIssues
=>
{
commit
(
types
.
RECEIVE_ISSUES_FOR_LIST_SUCCESS
,
{
listIssues
,
listId
});
})
.
catch
(()
=>
commit
(
types
.
RECEIVE_ISSUES_FOR_LIST_FAILURE
,
listId
));
},
fetchIssuesForEpic
:
({
state
,
commit
},
epicId
)
=>
{
commit
(
types
.
REQUEST_ISSUES_FOR_EPIC
,
epicId
);
const
{
filterParams
}
=
state
;
const
variables
=
{
filters
:
{
...
filterParams
,
epicId
},
};
return
fetchAndFormatListIssues
(
state
,
variables
)
.
then
(
listIssues
=>
{
commit
(
types
.
RECEIVE_ISSUES_FOR_EPIC_SUCCESS
,
{
...
listIssues
,
epicId
});
})
.
catch
(()
=>
commit
(
types
.
RECEIVE_ISSUES_FOR_EPIC_FAILURE
,
epicId
));
},
toggleEpicSwimlanes
:
({
state
,
commit
,
dispatch
})
=>
{
commit
(
types
.
TOGGLE_EPICS_SWIMLANES
);
...
...
ee/app/assets/javascripts/boards/stores/mutation_types.js
View file @
5f1f6c53
...
...
@@ -11,6 +11,11 @@ export const REQUEST_REMOVE_BOARD = 'REQUEST_REMOVE_BOARD';
export
const
RECEIVE_REMOVE_BOARD_SUCCESS
=
'
RECEIVE_REMOVE_BOARD_SUCCESS
'
;
export
const
RECEIVE_REMOVE_BOARD_ERROR
=
'
RECEIVE_REMOVE_BOARD_ERROR
'
;
export
const
TOGGLE_PROMOTION_STATE
=
'
TOGGLE_PROMOTION_STATE
'
;
export
const
RECEIVE_ISSUES_FOR_LIST_FAILURE
=
'
RECEIVE_ISSUES_FOR_LIST_FAILURE
'
;
export
const
RECEIVE_ISSUES_FOR_LIST_SUCCESS
=
'
RECEIVE_ISSUES_FOR_LIST_SUCCESS
'
;
export
const
REQUEST_ISSUES_FOR_EPIC
=
'
REQUEST_ISSUES_FOR_EPIC
'
;
export
const
RECEIVE_ISSUES_FOR_EPIC_SUCCESS
=
'
RECEIVE_ISSUES_FOR_EPIC_SUCCESS
'
;
export
const
RECEIVE_ISSUES_FOR_EPIC_FAILURE
=
'
RECEIVE_ISSUES_FOR_EPIC_FAILURE
'
;
export
const
TOGGLE_EPICS_SWIMLANES
=
'
TOGGLE_EPICS_SWIMLANES
'
;
export
const
RECEIVE_BOARD_LISTS_SUCCESS
=
'
RECEIVE_BOARD_LISTS_SUCCESS
'
;
export
const
RECEIVE_SWIMLANES_FAILURE
=
'
RECEIVE_SWIMLANES_FAILURE
'
;
...
...
ee/app/assets/javascripts/boards/stores/mutations.js
View file @
5f1f6c53
import
Vue
from
'
vue
'
;
import
{
union
}
from
'
lodash
'
;
import
mutationsCE
from
'
~/boards/stores/mutations
'
;
import
{
__
}
from
'
~/locale
'
;
import
{
s
__
}
from
'
~/locale
'
;
import
*
as
mutationTypes
from
'
./mutation_types
'
;
const
notImplemented
=
()
=>
{
...
...
@@ -65,6 +67,24 @@ export default {
notImplemented
();
},
[
mutationTypes
.
REQUEST_ISSUES_FOR_EPIC
]:
(
state
,
epicId
)
=>
{
Vue
.
set
(
state
.
epicsFlags
,
epicId
,
{
isLoading
:
true
});
},
[
mutationTypes
.
RECEIVE_ISSUES_FOR_EPIC_SUCCESS
]:
(
state
,
{
listData
,
issues
,
epicId
})
=>
{
Object
.
entries
(
listData
).
forEach
(([
listId
,
list
])
=>
{
Vue
.
set
(
state
.
issuesByListId
,
listId
,
union
(
state
.
issuesByListId
[
listId
]
||
[],
list
));
});
Vue
.
set
(
state
,
'
issues
'
,
{
...
state
.
issues
,
...
issues
});
Vue
.
set
(
state
.
epicsFlags
,
epicId
,
{
isLoading
:
false
});
},
[
mutationTypes
.
RECEIVE_ISSUES_FOR_EPIC_FAILURE
]:
(
state
,
epicId
)
=>
{
state
.
error
=
s__
(
'
Boards|An error occurred while fetching issues. Please reload the page.
'
);
Vue
.
set
(
state
.
epicsFlags
,
epicId
,
{
isLoading
:
false
});
},
[
mutationTypes
.
TOGGLE_EPICS_SWIMLANES
]:
state
=>
{
state
.
isShowingEpicsSwimlanes
=
!
state
.
isShowingEpicsSwimlanes
;
state
.
epicsSwimlanesFetchInProgress
=
true
;
...
...
@@ -76,8 +96,8 @@ export default {
},
[
mutationTypes
.
RECEIVE_SWIMLANES_FAILURE
]:
state
=>
{
state
.
error
=
__
(
'
An error occurred while fetching the board swimlanes. Please reload the page.
'
,
state
.
error
=
s
__
(
'
Boards|
An error occurred while fetching the board swimlanes. Please reload the page.
'
,
);
state
.
epicsSwimlanesFetchInProgress
=
false
;
},
...
...
ee/app/assets/javascripts/boards/stores/state.js
View file @
5f1f6c53
...
...
@@ -6,5 +6,5 @@ export default () => ({
isShowingEpicsSwimlanes
:
false
,
epicsSwimlanesFetchInProgress
:
false
,
epics
:
{},
issuesByEpicId
:
{},
epicsFlags
:
{},
});
ee/spec/frontend/boards/components/epic_lane_spec.js
View file @
5f1f6c53
...
...
@@ -2,7 +2,7 @@ import Vuex from 'vuex';
import
{
createLocalVue
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
EpicLane
from
'
ee/boards/components/epic_lane.vue
'
;
import
IssuesLaneList
from
'
ee/boards/components/issues_lane_list.vue
'
;
import
{
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
GlIcon
,
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
getters
from
'
ee/boards/stores/getters
'
;
import
{
mockEpic
,
mockListsWithModel
,
mockIssuesByListId
,
issues
}
from
'
../mock_data
'
;
...
...
@@ -12,18 +12,26 @@ localVue.use(Vuex);
describe
(
'
EpicLane
'
,
()
=>
{
let
wrapper
;
const
createStore
=
()
=>
{
const
findByTestId
=
testId
=>
wrapper
.
find
(
`[data-testid="
${
testId
}
"]`
);
const
createStore
=
isLoading
=>
{
return
new
Vuex
.
Store
({
actions
:
{
fetchIssuesForEpic
:
jest
.
fn
(),
},
state
:
{
issuesByListId
:
mockIssuesByListId
,
issues
,
epicsFlags
:
{
[
mockEpic
.
id
]:
{
isLoading
},
},
},
getters
,
});
};
const
createComponent
=
(
props
=
{})
=>
{
const
store
=
createStore
();
const
createComponent
=
(
{
props
=
{},
isLoading
=
false
}
=
{})
=>
{
const
store
=
createStore
(
isLoading
);
const
defaultProps
=
{
epic
:
mockEpic
,
...
...
@@ -55,12 +63,12 @@ describe('EpicLane', () => {
});
it
(
'
icon aria label is Closed when epic is closed
'
,
()
=>
{
createComponent
({
epic
:
{
...
mockEpic
,
state
:
'
closed
'
}
});
createComponent
({
props
:
{
epic
:
{
...
mockEpic
,
state
:
'
closed
'
}
}
});
expect
(
wrapper
.
find
(
GlIcon
).
attributes
(
'
aria-label
'
)).
toEqual
(
'
Closed
'
);
});
it
(
'
displays count of issues in epic which belong to board
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
[data-testid="epic-lane-issue-count"]
'
).
text
()).
toContain
(
2
);
expect
(
findByTestId
(
'
epic-lane-issue-count
'
).
text
()).
toContain
(
2
);
});
it
(
'
displays 2 icons
'
,
()
=>
{
...
...
@@ -79,12 +87,22 @@ describe('EpicLane', () => {
expect
(
wrapper
.
findAll
(
IssuesLaneList
)).
toHaveLength
(
wrapper
.
props
(
'
lists
'
).
length
);
expect
(
wrapper
.
vm
.
isExpanded
).
toBe
(
true
);
wrapper
.
find
(
'
[data-testid="epic-lane-chevron"]
'
).
vm
.
$emit
(
'
click
'
);
findByTestId
(
'
epic-lane-chevron
'
).
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
wrapper
.
findAll
(
IssuesLaneList
)).
toHaveLength
(
0
);
expect
(
wrapper
.
vm
.
isExpanded
).
toBe
(
false
);
});
});
it
(
'
does not display loading icon when issues are not loading
'
,
()
=>
{
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
false
);
});
it
(
'
displays loading icon and hides issues count when issues are loading
'
,
()
=>
{
createComponent
({
isLoading
:
true
});
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
expect
(
findByTestId
(
'
epic-lane-issue-count
'
).
exists
()).
toBe
(
false
);
});
});
});
ee/spec/frontend/boards/components/epics_swimlanes_spec.js
View file @
5f1f6c53
...
...
@@ -17,12 +17,8 @@ describe('EpicsSwimlanes', () => {
const
createStore
=
()
=>
{
return
new
Vuex
.
Store
({
actions
:
{
fetchIssuesForAllLists
:
jest
.
fn
(),
},
state
:
{
epics
:
mockEpics
,
isLoadingIssues
:
false
,
issuesByListId
:
mockIssuesByListId
,
issues
,
},
...
...
ee/spec/frontend/boards/stores/actions_spec.js
View file @
5f1f6c53
import
axios
from
'
axios
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
boardsStoreEE
from
'
ee/boards/stores/boards_store_ee
'
;
import
actions
from
'
ee/boards/stores/actions
'
;
import
actions
,
{
gqlClient
}
from
'
ee/boards/stores/actions
'
;
import
*
as
types
from
'
ee/boards/stores/mutation_types
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
{
ListType
}
from
'
~/boards/constants
'
;
jest
.
mock
(
'
axios
'
)
;
import
{
formatListIssues
}
from
'
~/boards/boards_util
'
;
import
{
mockLists
,
mockIssue
,
mockEpic
}
from
'
../mock_data
'
;
const
expectNotImplemented
=
action
=>
{
it
(
'
is not implemented
'
,
()
=>
{
...
...
@@ -13,6 +14,16 @@ const expectNotImplemented = action => {
});
};
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
setFilters
'
,
()
=>
{
it
(
'
should commit mutation SET_FILTERS, updates epicId with global id
'
,
done
=>
{
const
state
=
{
...
...
@@ -79,10 +90,16 @@ describe('updateListWipLimit', () => {
};
boardsStoreEE
.
initEESpecific
(
storeMock
);
jest
.
mock
(
'
axios
'
);
axios
.
put
=
jest
.
fn
();
axios
.
put
.
mockResolvedValue
({
data
:
{}
});
});
afterEach
(()
=>
{
jest
.
restoreAllMocks
();
});
it
(
'
should call the correct url
'
,
()
=>
{
axios
.
put
.
mockResolvedValue
({
data
:
{}
});
const
maxIssueCount
=
0
;
const
activeId
=
1
;
...
...
@@ -147,6 +164,73 @@ describe('togglePromotionState', () => {
expectNotImplemented
(
actions
.
updateIssueWeight
);
});
describe
(
'
fetchIssuesForEpic
'
,
()
=>
{
const
listId
=
mockLists
[
0
].
id
;
const
epicId
=
mockEpic
.
id
;
const
state
=
{
endpoints
:
{
fullPath
:
'
gitlab-org
'
,
boardId
:
1
,
},
filterParams
:
{},
boardType
:
'
group
'
,
};
const
queryResponse
=
{
data
:
{
group
:
{
board
:
{
lists
:
{
nodes
:
[
{
id
:
listId
,
issues
:
{
nodes
:
[
mockIssue
],
},
},
],
},
},
},
},
};
const
formattedIssues
=
formatListIssues
(
queryResponse
.
data
.
group
.
board
.
lists
);
it
(
'
should commit mutations REQUEST_ISSUES_FOR_EPIC and RECEIVE_ISSUES_FOR_LIST_SUCCESS on success
'
,
done
=>
{
jest
.
spyOn
(
gqlClient
,
'
query
'
).
mockResolvedValue
(
queryResponse
);
testAction
(
actions
.
fetchIssuesForEpic
,
epicId
,
state
,
[
{
type
:
types
.
REQUEST_ISSUES_FOR_EPIC
,
payload
:
epicId
},
{
type
:
types
.
RECEIVE_ISSUES_FOR_EPIC_SUCCESS
,
payload
:
{
...
formattedIssues
,
epicId
}
},
],
[],
done
,
);
});
it
(
'
should commit mutations REQUEST_ISSUES_FOR_EPIC and RECEIVE_ISSUES_FOR_LIST_FAILURE on failure
'
,
done
=>
{
jest
.
spyOn
(
gqlClient
,
'
query
'
).
mockResolvedValue
(
Promise
.
reject
());
testAction
(
actions
.
fetchIssuesForEpic
,
epicId
,
state
,
[
{
type
:
types
.
REQUEST_ISSUES_FOR_EPIC
,
payload
:
epicId
},
{
type
:
types
.
RECEIVE_ISSUES_FOR_EPIC_FAILURE
,
payload
:
epicId
},
],
[],
done
,
);
});
});
describe
(
'
toggleEpicSwimlanes
'
,
()
=>
{
it
(
'
should commit mutation TOGGLE_EPICS_SWIMLANES
'
,
()
=>
{
const
state
=
{
...
...
ee/spec/frontend/boards/stores/mutations_spec.js
View file @
5f1f6c53
import
mutations
from
'
ee/boards/stores/mutations
'
;
import
{
mockLists
,
mockEpics
}
from
'
../mock_data
'
;
import
{
mockLists
,
mockIssue
,
mockIssue2
,
mockEpics
,
mockEpic
,
mockListsWithModel
,
}
from
'
../mock_data
'
;
const
expectNotImplemented
=
action
=>
{
it
(
'
is not implemented
'
,
()
=>
{
...
...
@@ -7,9 +14,21 @@ const expectNotImplemented = action => {
});
};
const
epicId
=
mockEpic
.
id
;
let
state
=
{
issuesByListId
:
{},
issues
:
{},
boardLists
:
mockListsWithModel
,
epicsFlags
:
{
[
epicId
]:
{
isLoading
:
true
},
},
};
describe
(
'
SET_SHOW_LABELS
'
,
()
=>
{
it
(
'
updates isShowingLabels
'
,
()
=>
{
const
state
=
{
state
=
{
...
state
,
isShowingLabels
:
true
,
};
...
...
@@ -71,9 +90,57 @@ describe('TOGGLE_PROMOTION_STATE', () => {
expectNotImplemented
(
mutations
.
TOGGLE_PROMOTION_STATE
);
});
describe
(
'
REQUEST_ISSUES_FOR_EPIC
'
,
()
=>
{
it
(
'
sets isLoading epicsFlags in state for epicId to true
'
,
()
=>
{
state
=
{
...
state
,
epicsFlags
:
{
[
epicId
]:
{
isLoading
:
false
},
},
};
mutations
.
REQUEST_ISSUES_FOR_EPIC
(
state
,
epicId
);
expect
(
state
.
epicsFlags
[
epicId
].
isLoading
).
toBe
(
true
);
});
});
describe
(
'
RECEIVE_ISSUES_FOR_EPIC_SUCCESS
'
,
()
=>
{
it
(
'
sets issuesByListId and issues state for epic issues and loading state to false
'
,
()
=>
{
const
listIssues
=
{
'
gid://gitlab/List/1
'
:
[
mockIssue
.
id
],
'
gid://gitlab/List/2
'
:
[
mockIssue2
.
id
],
};
const
issues
=
{
'
436
'
:
mockIssue
,
'
437
'
:
mockIssue2
,
};
mutations
.
RECEIVE_ISSUES_FOR_EPIC_SUCCESS
(
state
,
{
listData
:
listIssues
,
issues
,
epicId
,
});
expect
(
state
.
issuesByListId
).
toEqual
(
listIssues
);
expect
(
state
.
issues
).
toEqual
(
issues
);
expect
(
state
.
epicsFlags
[
epicId
].
isLoading
).
toBe
(
false
);
});
});
describe
(
'
RECEIVE_ISSUES_FOR_EPIC_FAILURE
'
,
()
=>
{
it
(
'
sets loading state to false for epic and error message
'
,
()
=>
{
mutations
.
RECEIVE_ISSUES_FOR_EPIC_FAILURE
(
state
,
epicId
);
expect
(
state
.
error
).
toEqual
(
'
An error occurred while fetching issues. Please reload the page.
'
);
expect
(
state
.
epicsFlags
[
epicId
].
isLoading
).
toBe
(
false
);
});
});
describe
(
'
TOGGLE_EPICS_SWIMLANES
'
,
()
=>
{
it
(
'
toggles isShowingEpicsSwimlanes from true to false
'
,
()
=>
{
const
state
=
{
state
=
{
...
state
,
isShowingEpicsSwimlanes
:
true
,
};
...
...
@@ -83,7 +150,8 @@ describe('TOGGLE_EPICS_SWIMLANES', () => {
});
it
(
'
toggles isShowingEpicsSwimlanes from false to true
'
,
()
=>
{
const
state
=
{
state
=
{
...
state
,
isShowingEpicsSwimlanes
:
false
,
};
...
...
@@ -93,7 +161,8 @@ describe('TOGGLE_EPICS_SWIMLANES', () => {
});
it
(
'
sets epicsSwimlanesFetchInProgress to true
'
,
()
=>
{
const
state
=
{
state
=
{
...
state
,
epicsSwimlanesFetchInProgress
:
false
,
};
...
...
@@ -105,7 +174,8 @@ describe('TOGGLE_EPICS_SWIMLANES', () => {
describe
(
'
RECEIVE_BOARD_LISTS_SUCCESS
'
,
()
=>
{
it
(
'
sets epicsSwimlanesFetchInProgress to false and populates boardLists with payload
'
,
()
=>
{
const
state
=
{
state
=
{
...
state
,
epicsSwimlanesFetchInProgress
:
true
,
boardLists
:
{},
};
...
...
@@ -119,7 +189,8 @@ describe('RECEIVE_BOARD_LISTS_SUCCESS', () => {
describe
(
'
RECEIVE_SWIMLANES_FAILURE
'
,
()
=>
{
it
(
'
sets epicsSwimlanesFetchInProgress to false and sets error message
'
,
()
=>
{
const
state
=
{
state
=
{
...
state
,
epicsSwimlanesFetchInProgress
:
true
,
error
:
undefined
,
};
...
...
@@ -134,8 +205,9 @@ describe('RECEIVE_SWIMLANES_FAILURE', () => {
});
describe
(
'
RECEIVE_EPICS_SUCCESS
'
,
()
=>
{
it
(
'
populates epics with payload
'
,
()
=>
{
const
state
=
{
it
(
'
populates epics with payload and set epicsFlags loading to true
'
,
()
=>
{
state
=
{
...
state
,
epics
:
{},
};
...
...
locale/gitlab.pot
View file @
5f1f6c53
...
...
@@ -2681,12 +2681,6 @@ msgstr ""
msgid "An error occurred while checking group path. Please refresh and try again."
msgstr ""
msgid "An error occurred while creating the issue. Please try again."
msgstr ""
msgid "An error occurred while creating the list. Please try again."
msgstr ""
msgid "An error occurred while decoding the file."
msgstr ""
...
...
@@ -2759,18 +2753,12 @@ msgstr ""
msgid "An error occurred while fetching the Service Desk address."
msgstr ""
msgid "An error occurred while fetching the board issues. Please reload the page."
msgstr ""
msgid "An error occurred while fetching the board lists. Please reload the page."
msgstr ""
msgid "An error occurred while fetching the board lists. Please try again."
msgstr ""
msgid "An error occurred while fetching the board swimlanes. Please reload the page."
msgstr ""
msgid "An error occurred while fetching the builds."
msgstr ""
...
...
@@ -2882,9 +2870,6 @@ msgstr ""
msgid "An error occurred while moving the issue."
msgstr ""
msgid "An error occurred while moving the issue. Please try again."
msgstr ""
msgid "An error occurred while parsing recent searches"
msgstr ""
...
...
@@ -2954,9 +2939,6 @@ msgstr ""
msgid "An error occurred while updating the comment"
msgstr ""
msgid "An error occurred while updating the list. Please try again."
msgstr ""
msgid "An error occurred while validating group path"
msgstr ""
...
...
@@ -4093,6 +4075,27 @@ msgstr ""
msgid "Boards and Board Lists"
msgstr ""
msgid "Boards|An error occurred while creating the issue. Please try again."
msgstr ""
msgid "Boards|An error occurred while creating the list. Please try again."
msgstr ""
msgid "Boards|An error occurred while fetching issues. Please reload the page."
msgstr ""
msgid "Boards|An error occurred while fetching the board issues. Please reload the page."
msgstr ""
msgid "Boards|An error occurred while fetching the board swimlanes. Please reload the page."
msgstr ""
msgid "Boards|An error occurred while moving the issue. Please try again."
msgstr ""
msgid "Boards|An error occurred while updating the list. Please try again."
msgstr ""
msgid "Boards|Collapse"
msgstr ""
...
...
spec/frontend/boards/components/board_content_spec.js
View file @
5f1f6c53
...
...
@@ -23,9 +23,6 @@ describe('BoardContent', () => {
return
new
Vuex
.
Store
({
getters
,
state
,
actions
:
{
fetchIssuesForAllLists
:
()
=>
{},
},
});
};
...
...
spec/frontend/boards/stores/actions_spec.js
View file @
5f1f6c53
...
...
@@ -6,12 +6,13 @@ import {
mockIssueWithModel
,
mockIssue2WithModel
,
rawIssue
,
mockIssues
,
}
from
'
../mock_data
'
;
import
actions
,
{
gqlClient
}
from
'
~/boards/stores/actions
'
;
import
*
as
types
from
'
~/boards/stores/mutation_types
'
;
import
{
inactiveId
,
ListType
}
from
'
~/boards/constants
'
;
import
issueMoveListMutation
from
'
~/boards/queries/issue_move_list.mutation.graphql
'
;
import
{
fullBoardId
}
from
'
~/boards/boards_util
'
;
import
{
fullBoardId
,
formatListIssues
}
from
'
~/boards/boards_util
'
;
const
expectNotImplemented
=
action
=>
{
it
(
'
is not implemented
'
,
()
=>
{
...
...
@@ -237,6 +238,77 @@ describe('deleteList', () => {
expectNotImplemented
(
actions
.
deleteList
);
});
describe
(
'
fetchIssuesForList
'
,
()
=>
{
const
listId
=
mockLists
[
0
].
id
;
const
state
=
{
endpoints
:
{
fullPath
:
'
gitlab-org
'
,
boardId
:
1
,
},
filterParams
:
{},
boardType
:
'
group
'
,
};
const
queryResponse
=
{
data
:
{
group
:
{
board
:
{
lists
:
{
nodes
:
[
{
id
:
listId
,
issues
:
{
nodes
:
mockIssues
,
},
},
],
},
},
},
},
};
const
formattedIssues
=
formatListIssues
(
queryResponse
.
data
.
group
.
board
.
lists
);
it
(
'
should commit mutation RECEIVE_ISSUES_FOR_LIST_SUCCESS on success
'
,
done
=>
{
jest
.
spyOn
(
gqlClient
,
'
query
'
).
mockResolvedValue
(
queryResponse
);
testAction
(
actions
.
fetchIssuesForList
,
listId
,
state
,
[
{
type
:
types
.
RECEIVE_ISSUES_FOR_LIST_SUCCESS
,
payload
:
{
listIssues
:
formattedIssues
,
listId
},
},
],
[],
done
,
);
});
it
(
'
should commit mutation RECEIVE_ISSUES_FOR_LIST_FAILURE on failure
'
,
done
=>
{
jest
.
spyOn
(
gqlClient
,
'
query
'
).
mockResolvedValue
(
Promise
.
reject
());
testAction
(
actions
.
fetchIssuesForList
,
listId
,
state
,
[{
type
:
types
.
RECEIVE_ISSUES_FOR_LIST_FAILURE
,
payload
:
listId
}],
[],
done
,
);
});
});
describe
(
'
resetIssues
'
,
()
=>
{
it
(
'
commits RESET_ISSUES mutation
'
,
()
=>
{
return
testAction
(
actions
.
resetIssues
,
{},
{},
[{
type
:
types
.
RESET_ISSUES
}],
[]);
});
});
describe
(
'
moveIssue
'
,
()
=>
{
const
listIssues
=
{
'
gid://gitlab/List/1
'
:
[
436
,
437
],
...
...
spec/frontend/boards/stores/mutations_spec.js
View file @
5f1f6c53
...
...
@@ -145,6 +145,23 @@ describe('Board Store Mutations', () => {
expectNotImplemented
(
mutations
.
RECEIVE_REMOVE_LIST_ERROR
);
});
describe
(
'
RESET_ISSUES
'
,
()
=>
{
it
(
'
should remove issues from issuesByListId state
'
,
()
=>
{
const
issuesByListId
=
{
'
gid://gitlab/List/1
'
:
[
mockIssue
.
id
],
};
state
=
{
...
state
,
issuesByListId
,
};
mutations
[
types
.
RESET_ISSUES
](
state
);
expect
(
state
.
issuesByListId
).
toEqual
({
'
gid://gitlab/List/1
'
:
[]
});
});
});
describe
(
'
RECEIVE_ISSUES_FOR_LIST_SUCCESS
'
,
()
=>
{
it
(
'
updates issuesByListId and issues on state
'
,
()
=>
{
const
listIssues
=
{
...
...
@@ -156,7 +173,6 @@ describe('Board Store Mutations', () => {
state
=
{
...
state
,
isLoadingIssues
:
true
,
issuesByListId
:
{},
issues
:
{},
boardLists
:
mockListsWithModel
,
...
...
@@ -172,16 +188,6 @@ describe('Board Store Mutations', () => {
});
});
describe
(
'
REQUEST_ISSUES_FOR_ALL_LISTS
'
,
()
=>
{
it
(
'
sets isLoadingIssues to true
'
,
()
=>
{
expect
(
state
.
isLoadingIssues
).
toBe
(
false
);
mutations
.
REQUEST_ISSUES_FOR_ALL_LISTS
(
state
);
expect
(
state
.
isLoadingIssues
).
toBe
(
true
);
});
});
describe
(
'
RECEIVE_ISSUES_FOR_LIST_FAILURE
'
,
()
=>
{
it
(
'
sets error message
'
,
()
=>
{
state
=
{
...
...
@@ -200,51 +206,10 @@ describe('Board Store Mutations', () => {
});
});
describe
(
'
RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS
'
,
()
=>
{
it
(
'
sets isLoadingIssues to false and updates issuesByListId object
'
,
()
=>
{
const
listIssues
=
{
'
gid://gitlab/List/1
'
:
[
mockIssue
.
id
],
};
const
issues
=
{
'
1
'
:
mockIssue
,
};
state
=
{
...
state
,
isLoadingIssues
:
true
,
issuesByListId
:
{},
issues
:
{},
};
mutations
.
RECEIVE_ISSUES_FOR_ALL_LISTS_SUCCESS
(
state
,
{
listData
:
listIssues
,
issues
});
expect
(
state
.
isLoadingIssues
).
toBe
(
false
);
expect
(
state
.
issuesByListId
).
toEqual
(
listIssues
);
expect
(
state
.
issues
).
toEqual
(
issues
);
});
});
describe
(
'
REQUEST_ADD_ISSUE
'
,
()
=>
{
expectNotImplemented
(
mutations
.
REQUEST_ADD_ISSUE
);
});
describe
(
'
RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE
'
,
()
=>
{
it
(
'
sets isLoadingIssues to false and sets error message
'
,
()
=>
{
state
=
{
...
state
,
isLoadingIssues
:
true
,
error
:
undefined
,
};
mutations
.
RECEIVE_ISSUES_FOR_ALL_LISTS_FAILURE
(
state
);
expect
(
state
.
isLoadingIssues
).
toBe
(
false
);
expect
(
state
.
error
).
toEqual
(
'
An error occurred while fetching the board issues. Please reload the page.
'
,
);
});
});
describe
(
'
UPDATE_ISSUE_BY_ID
'
,
()
=>
{
const
issueId
=
'
1
'
;
const
prop
=
'
id
'
;
...
...
@@ -254,7 +219,6 @@ describe('Board Store Mutations', () => {
beforeEach
(()
=>
{
state
=
{
...
state
,
isLoadingIssues
:
true
,
error
:
undefined
,
issues
:
{
...
issue
,
...
...
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