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
829d6edf
Commit
829d6edf
authored
Nov 20, 2020
by
Florie Guibert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Boards - Remove List model from GraphQL boards
Refactor boards and swimlanes removing List model
parent
27aa2c6c
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
224 additions
and
221 deletions
+224
-221
app/assets/javascripts/boards/boards_util.js
app/assets/javascripts/boards/boards_util.js
+24
-10
app/assets/javascripts/boards/components/board_column_new.vue
...assets/javascripts/boards/components/board_column_new.vue
+8
-6
app/assets/javascripts/boards/components/board_content.vue
app/assets/javascripts/boards/components/board_content.vue
+0
-3
app/assets/javascripts/boards/components/board_list_header_new.vue
...s/javascripts/boards/components/board_list_header_new.vue
+39
-36
app/assets/javascripts/boards/components/board_list_new.vue
app/assets/javascripts/boards/components/board_list_new.vue
+13
-17
app/assets/javascripts/boards/components/board_settings_sidebar.vue
.../javascripts/boards/components/board_settings_sidebar.vue
+1
-1
app/assets/javascripts/boards/components/issue_card_inner.vue
...assets/javascripts/boards/components/issue_card_inner.vue
+8
-1
app/assets/javascripts/boards/components/project_select.vue
app/assets/javascripts/boards/components/project_select.vue
+5
-1
app/assets/javascripts/boards/stores/actions.js
app/assets/javascripts/boards/stores/actions.js
+1
-6
app/assets/javascripts/boards/stores/mutations.js
app/assets/javascripts/boards/stores/mutations.js
+2
-2
ee/app/assets/javascripts/boards/components/epics_swimlanes.vue
.../assets/javascripts/boards/components/epics_swimlanes.vue
+6
-2
ee/app/assets/javascripts/boards/components/issues_lane_list.vue
...assets/javascripts/boards/components/issues_lane_list.vue
+2
-2
ee/app/assets/javascripts/boards/stores/actions.js
ee/app/assets/javascripts/boards/stores/actions.js
+1
-1
ee/spec/frontend/boards/components/board_list_header_new_spec.js
.../frontend/boards/components/board_list_header_new_spec.js
+7
-10
ee/spec/frontend/boards/components/epic_lane_spec.js
ee/spec/frontend/boards/components/epic_lane_spec.js
+2
-2
ee/spec/frontend/boards/components/epics_swimlanes_spec.js
ee/spec/frontend/boards/components/epics_swimlanes_spec.js
+2
-2
ee/spec/frontend/boards/components/issues_lane_list_spec.js
ee/spec/frontend/boards/components/issues_lane_list_spec.js
+4
-7
ee/spec/frontend/boards/stores/actions_spec.js
ee/spec/frontend/boards/stores/actions_spec.js
+2
-9
ee/spec/frontend/boards/stores/mutations_spec.js
ee/spec/frontend/boards/stores/mutations_spec.js
+3
-3
spec/frontend/boards/board_list_new_spec.js
spec/frontend/boards/board_list_new_spec.js
+18
-18
spec/frontend/boards/components/board_column_new_spec.js
spec/frontend/boards/components/board_column_new_spec.js
+4
-7
spec/frontend/boards/components/board_content_spec.js
spec/frontend/boards/components/board_content_spec.js
+3
-3
spec/frontend/boards/components/board_list_header_new_spec.js
.../frontend/boards/components/board_list_header_new_spec.js
+9
-12
spec/frontend/boards/components/board_new_issue_new_spec.js
spec/frontend/boards/components/board_new_issue_new_spec.js
+2
-2
spec/frontend/boards/mock_data.js
spec/frontend/boards/mock_data.js
+32
-31
spec/frontend/boards/stores/actions_spec.js
spec/frontend/boards/stores/actions_spec.js
+6
-7
spec/frontend/boards/stores/getters_spec.js
spec/frontend/boards/stores/getters_spec.js
+5
-5
spec/frontend/boards/stores/mutations_spec.js
spec/frontend/boards/stores/mutations_spec.js
+15
-15
No files found.
app/assets/javascripts/boards/boards_util.js
View file @
829d6edf
...
...
@@ -2,20 +2,29 @@ import { sortBy } from 'lodash';
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
ListType
}
from
'
./constants
'
;
import
{
getIdFromGraphQLId
}
from
'
~/graphql_shared/utils
'
;
import
boardsStore
from
'
~/boards/stores/boards_store
'
;
export
function
getMilestone
()
{
return
null
;
}
export
function
updateListPosition
(
listObj
)
{
const
{
listType
}
=
listObj
;
let
{
position
}
=
listObj
;
if
(
listType
===
ListType
.
closed
)
{
position
=
Infinity
;
}
else
if
(
listType
===
ListType
.
backlog
)
{
position
=
-
1
;
}
const
list
=
{
...
listObj
,
position
};
return
list
;
}
export
function
formatBoardLists
(
lists
)
{
const
formattedLists
=
lists
.
nodes
.
map
(
list
=>
boardsStore
.
updateListPosition
({
...
list
,
doNotFetchIssues
:
true
}),
);
return
formattedLists
.
reduce
((
map
,
list
)
=>
{
return
lists
.
nodes
.
reduce
((
map
,
list
)
=>
{
return
{
...
map
,
[
list
.
id
]:
list
,
[
list
.
id
]:
updateListPosition
(
list
)
,
};
},
{});
}
...
...
@@ -85,22 +94,22 @@ export function fullLabelId(label) {
export
function
moveIssueListHelper
(
issue
,
fromList
,
toList
)
{
const
updatedIssue
=
issue
;
if
(
toList
.
t
ype
===
ListType
.
label
&&
toList
.
listT
ype
===
ListType
.
label
&&
!
updatedIssue
.
labels
.
find
(
label
=>
label
.
id
===
toList
.
label
.
id
)
)
{
updatedIssue
.
labels
.
push
(
toList
.
label
);
}
if
(
fromList
?.
label
&&
fromList
.
t
ype
===
ListType
.
label
)
{
if
(
fromList
?.
label
&&
fromList
.
listT
ype
===
ListType
.
label
)
{
updatedIssue
.
labels
=
updatedIssue
.
labels
.
filter
(
label
=>
fromList
.
label
.
id
!==
label
.
id
);
}
if
(
toList
.
t
ype
===
ListType
.
assignee
&&
toList
.
listT
ype
===
ListType
.
assignee
&&
!
updatedIssue
.
assignees
.
find
(
assignee
=>
assignee
.
id
===
toList
.
assignee
.
id
)
)
{
updatedIssue
.
assignees
.
push
(
toList
.
assignee
);
}
if
(
fromList
?.
assignee
&&
fromList
.
t
ype
===
ListType
.
assignee
)
{
if
(
fromList
?.
assignee
&&
fromList
.
listT
ype
===
ListType
.
assignee
)
{
updatedIssue
.
assignees
=
updatedIssue
.
assignees
.
filter
(
assignee
=>
assignee
.
id
!==
fromList
.
assignee
.
id
,
);
...
...
@@ -118,6 +127,10 @@ export function getBoardsPath(endpoint, board) {
return
axios
.
post
(
path
,
{
board
});
}
export
function
isListDraggable
(
list
)
{
return
list
.
listType
!==
ListType
.
backlog
&&
list
.
listType
!==
ListType
.
closed
;
}
export
default
{
getMilestone
,
formatIssue
,
...
...
@@ -125,4 +138,5 @@ export default {
fullBoardId
,
fullLabelId
,
getBoardsPath
,
isListDraggable
,
};
app/assets/javascripts/boards/components/board_column_new.vue
View file @
829d6edf
...
...
@@ -2,6 +2,7 @@
import
{
mapGetters
,
mapActions
,
mapState
}
from
'
vuex
'
;
import
BoardListHeader
from
'
ee_else_ce/boards/components/board_list_header_new.vue
'
;
import
BoardList
from
'
./board_list_new.vue
'
;
import
{
isListDraggable
}
from
'
../boards_util
'
;
export
default
{
components
:
{
...
...
@@ -35,6 +36,9 @@ export default {
listIssues
()
{
return
this
.
getIssuesByList
(
this
.
list
.
id
);
},
isListDraggable
()
{
return
isListDraggable
(
this
.
list
);
},
},
watch
:
{
filterParams
:
{
...
...
@@ -47,7 +51,6 @@ export default {
},
methods
:
{
...
mapActions
([
'
fetchIssuesForList
'
]),
// TODO: Reordering of lists https://gitlab.com/gitlab-org/gitlab/-/issues/280515
},
};
</
script
>
...
...
@@ -55,13 +58,12 @@ export default {
<
template
>
<div
:class=
"
{
'is-draggable': !list.preset,
'is-expandable': list.isExpandable,
'is-collapsed': !list.isExpanded,
'board-type-assignee': list.type === 'assignee',
'is-draggable': isListDraggable,
'is-collapsed': list.collapsed,
'board-type-assignee': list.listType === 'assignee',
}"
:data-id="list.id"
class="board gl-display-inline-block gl-h-full gl-px-3 gl-vertical-align-top gl-white-space-normal"
class="board gl-display-inline-block gl-h-full gl-px-3 gl-vertical-align-top gl-white-space-normal
is-expandable
"
data-qa-selector="board_list"
>
<div
...
...
app/assets/javascripts/boards/components/board_content.vue
View file @
829d6edf
...
...
@@ -103,9 +103,6 @@ export default {
:key=
"list.id"
ref=
"board"
:can-admin-list=
"canAdminList"
:class=
"
{
'is-draggable': !list.preset,
}"
:list=
"list"
:disabled=
"disabled"
/>
...
...
app/assets/javascripts/boards/components/board_list_header_new.vue
View file @
829d6edf
...
...
@@ -16,6 +16,7 @@ import eventHub from '../eventhub';
import
sidebarEventHub
from
'
~/sidebar/event_hub
'
;
import
{
inactiveId
,
LIST
,
ListType
}
from
'
../constants
'
;
import
{
isScopedLabel
}
from
'
~/lib/utils/common_utils
'
;
import
{
isListDraggable
}
from
'
~/boards/boards_util
'
;
export
default
{
components
:
{
...
...
@@ -66,47 +67,47 @@ export default {
return
Boolean
(
this
.
currentUserId
);
},
listType
()
{
return
this
.
list
.
t
ype
;
return
this
.
list
.
listT
ype
;
},
listAssignee
()
{
return
this
.
list
?.
assignee
?.
username
||
''
;
},
listTitle
()
{
return
this
.
list
?.
label
?.
description
||
this
.
list
.
title
||
''
;
return
this
.
list
?.
label
?.
description
||
this
.
list
?.
assignee
?.
name
||
this
.
list
.
title
||
''
;
},
showListHeaderButton
()
{
return
!
this
.
disabled
&&
this
.
listType
!==
ListType
.
closed
;
},
showMilestoneListDetails
()
{
return
(
this
.
list
.
t
ype
===
ListType
.
milestone
&&
this
.
list
T
ype
===
ListType
.
milestone
&&
this
.
list
.
milestone
&&
(
this
.
list
.
isExpand
ed
||
!
this
.
isSwimlanesHeader
)
(
!
this
.
list
.
collaps
ed
||
!
this
.
isSwimlanesHeader
)
);
},
showAssigneeListDetails
()
{
return
(
this
.
list
.
type
===
ListType
.
assignee
&&
(
this
.
list
.
isExpand
ed
||
!
this
.
isSwimlanesHeader
)
this
.
list
Type
===
ListType
.
assignee
&&
(
!
this
.
list
.
collaps
ed
||
!
this
.
isSwimlanesHeader
)
);
},
issuesCount
()
{
return
this
.
list
.
issues
Size
;
return
this
.
list
.
issues
Count
;
},
issuesTooltipLabel
()
{
return
n__
(
`%d issue`
,
`%d issues`
,
this
.
issuesCount
);
},
chevronTooltip
()
{
return
this
.
list
.
isExpanded
?
s__
(
'
Boards|Collapse
'
)
:
s__
(
'
Boards|Expand
'
);
return
this
.
list
.
collapsed
?
s__
(
'
Boards|Expand
'
)
:
s__
(
'
Boards|Collapse
'
);
},
chevronIcon
()
{
return
this
.
list
.
isExpanded
?
'
chevron-right
'
:
'
chevron-down
'
;
return
this
.
list
.
collapsed
?
'
chevron-down
'
:
'
chevron-right
'
;
},
isNewIssueShown
()
{
return
this
.
listType
===
ListType
.
backlog
||
this
.
showListHeaderButton
;
},
isSettingsShown
()
{
return
(
this
.
listType
!==
ListType
.
backlog
&&
this
.
showListHeaderButton
&&
this
.
list
.
isExpand
ed
this
.
listType
!==
ListType
.
backlog
&&
this
.
showListHeaderButton
&&
!
this
.
list
.
collaps
ed
);
},
uniqueKey
()
{
...
...
@@ -119,6 +120,9 @@ export default {
headerStyle
()
{
return
{
borderTopColor
:
this
.
list
?.
label
?.
color
};
},
userCanDrag
()
{
return
!
this
.
disabled
&&
isListDraggable
(
this
.
list
);
},
},
methods
:
{
...
mapActions
([
'
updateList
'
,
'
setActiveId
'
]),
...
...
@@ -137,7 +141,7 @@ export default {
eventHub
.
$emit
(
`toggle-issue-form-
${
this
.
list
.
id
}
`
);
},
toggleExpanded
()
{
this
.
list
.
isExpanded
=
!
this
.
list
.
isExpand
ed
;
this
.
list
.
collapsed
=
!
this
.
list
.
collaps
ed
;
if
(
!
this
.
isLoggedIn
)
{
this
.
addToLocalStorage
();
...
...
@@ -151,11 +155,11 @@ export default {
},
addToLocalStorage
()
{
if
(
AccessorUtilities
.
isLocalStorageAccessSafe
())
{
localStorage
.
setItem
(
`
${
this
.
uniqueKey
}
.expanded`
,
this
.
list
.
isExpand
ed
);
localStorage
.
setItem
(
`
${
this
.
uniqueKey
}
.expanded`
,
!
this
.
list
.
collaps
ed
);
}
},
updateListFunction
()
{
this
.
updateList
({
listId
:
this
.
list
.
id
,
collapsed
:
!
this
.
list
.
isExpand
ed
});
this
.
updateList
({
listId
:
this
.
list
.
id
,
collapsed
:
this
.
list
.
collaps
ed
});
},
},
};
...
...
@@ -165,7 +169,7 @@ export default {
<header
:class=
"
{
'has-border': list.label
&&
list.label.color,
'gl-h-full':
!list.isExpand
ed,
'gl-h-full':
list.collaps
ed,
'board-inner gl-rounded-top-left-base gl-rounded-top-right-base': isSwimlanesHeader,
}"
:style="headerStyle"
...
...
@@ -175,16 +179,15 @@ export default {
>
<h3
:class=
"
{
'user-can-drag':
!disabled
&&
!list.preset
,
'gl-py-3 gl-h-full':
!list.isExpand
ed
&&
!isSwimlanesHeader,
'gl-border-b-0':
!list.isExpand
ed || isSwimlanesHeader,
'gl-py-2':
!list.isExpand
ed
&&
isSwimlanesHeader,
'gl-flex-direction-column':
!list.isExpand
ed,
'user-can-drag':
userCanDrag
,
'gl-py-3 gl-h-full':
list.collaps
ed
&&
!isSwimlanesHeader,
'gl-border-b-0':
list.collaps
ed || isSwimlanesHeader,
'gl-py-2':
list.collaps
ed
&&
isSwimlanesHeader,
'gl-flex-direction-column':
list.collaps
ed,
}"
class="board-title gl-m-0 gl-display-flex gl-align-items-center gl-font-base gl-px-3 js-board-handle"
>
<gl-button
v-if=
"list.isExpandable"
v-gl-tooltip
.
hover
:aria-label=
"chevronTooltip"
:title=
"chevronTooltip"
...
...
@@ -200,8 +203,8 @@ export default {
aria-hidden=
"true"
class=
"milestone-icon"
:class=
"
{
'gl-mt-3 gl-rotate-90':
!list.isExpand
ed,
'gl-mr-2':
list.isExpand
ed,
'gl-mt-3 gl-rotate-90':
list.collaps
ed,
'gl-mr-2':
!list.collaps
ed,
}"
>
<gl-icon
name=
"timer"
/>
...
...
@@ -209,17 +212,17 @@ export default {
<a
v-if=
"showAssigneeListDetails"
:href=
"list.assignee.
path
"
:href=
"list.assignee.
webUrl
"
class=
"user-avatar-link js-no-trigger"
:class=
"
{
'gl-mt-3 gl-rotate-90':
!list.isExpand
ed,
'gl-mt-3 gl-rotate-90':
list.collaps
ed,
}"
>
<img
v-gl-tooltip
.
hover
.
bottom
:title=
"listAssignee"
:alt=
"list.assignee.name"
:src=
"list.assignee.avatar"
:src=
"list.assignee.avatar
Url
"
class=
"avatar s20"
height=
"20"
width=
"20"
...
...
@@ -229,9 +232,9 @@ export default {
<div
class=
"board-title-text"
:class=
"
{
'gl-display-none':
!list.isExpand
ed
&&
isSwimlanesHeader,
'gl-flex-grow-0 gl-my-3 gl-mx-0':
!list.isExpand
ed,
'gl-flex-grow-1':
list.isExpand
ed,
'gl-display-none':
list.collaps
ed
&&
isSwimlanesHeader,
'gl-flex-grow-0 gl-my-3 gl-mx-0':
list.collaps
ed,
'gl-flex-grow-1':
!list.collaps
ed,
}"
>
<!-- EE start -->
...
...
@@ -239,16 +242,16 @@ export default {
v-if=
"listType !== 'label'"
v-gl-tooltip
.
hover
:class=
"
{
'gl-display-block':
!list.isExpand
ed || listType === 'milestone',
'gl-display-block':
list.collaps
ed || listType === 'milestone',
}"
:title="listTitle"
class="board-title-main-text gl-text-truncate"
>
{{
list
.
t
itle
}}
{{
list
T
itle
}}
</span>
<span
v-if=
"listType === 'assignee'"
v-show=
"
list.isExpand
ed"
v-show=
"
!list.collaps
ed"
class=
"gl-ml-2 gl-font-weight-normal gl-text-gray-500"
>
@
{{
listAssignee
}}
...
...
@@ -260,21 +263,21 @@ export default {
:background-color=
"list.label.color"
:description=
"list.label.description"
:scoped=
"showScopedLabels(list.label)"
:size=
"
!list.isExpand
ed ? 'sm' : ''"
:size=
"
list.collaps
ed ? 'sm' : ''"
:title=
"list.label.title"
/>
</div>
<!-- EE start -->
<span
v-if=
"isSwimlanesHeader &&
!list.isExpand
ed"
v-if=
"isSwimlanesHeader &&
list.collaps
ed"
ref=
"collapsedInfo"
aria-hidden=
"true"
class=
"board-header-collapsed-info-icon gl-cursor-pointer gl-text-gray-500"
>
<gl-icon
name=
"information"
/>
</span>
<gl-tooltip
v-if=
"isSwimlanesHeader &&
!list.isExpand
ed"
:target=
"() => $refs.collapsedInfo"
>
<gl-tooltip
v-if=
"isSwimlanesHeader &&
list.collaps
ed"
:target=
"() => $refs.collapsedInfo"
>
<div
class=
"gl-font-weight-bold gl-pb-2"
>
{{
collapsedTooltipTitle
}}
</div>
<div
v-if=
"list.maxIssueCount !== 0"
>
•
...
...
@@ -296,8 +299,8 @@ export default {
<div
class=
"issue-count-badge gl-display-inline-flex gl-pr-0 no-drag gl-text-gray-500"
:class=
"{
'gl-display-none!':
!list.isExpand
ed && isSwimlanesHeader,
'gl-p-0':
!list.isExpand
ed,
'gl-display-none!':
list.collaps
ed && isSwimlanesHeader,
'gl-p-0':
list.collaps
ed,
}"
>
<span
class=
"gl-display-inline-flex"
>
...
...
@@ -323,7 +326,7 @@ export default {
>
<gl-button
v-if=
"isNewIssueShown"
v-show=
"
list.isExpand
ed"
v-show=
"
!list.collaps
ed"
ref=
"newIssueBtn"
v-gl-tooltip
.
hover
:aria-label=
"__('New issue')"
...
...
app/assets/javascripts/boards/components/board_list_new.vue
View file @
829d6edf
...
...
@@ -49,11 +49,11 @@ export default {
paginatedIssueText
()
{
return
sprintf
(
__
(
'
Showing %{pageSize} of %{total} issues
'
),
{
pageSize
:
this
.
issues
.
length
,
total
:
this
.
list
.
issues
Size
,
total
:
this
.
list
.
issues
Count
,
});
},
issuesSizeExceedsMax
()
{
return
this
.
list
.
maxIssueCount
>
0
&&
this
.
list
.
issues
Size
>
this
.
list
.
maxIssueCount
;
return
this
.
list
.
maxIssueCount
>
0
&&
this
.
list
.
issues
Count
>
this
.
list
.
maxIssueCount
;
},
hasNextPage
()
{
return
this
.
pageInfoByListId
[
this
.
list
.
id
].
hasNextPage
;
...
...
@@ -61,6 +61,9 @@ export default {
loading
()
{
return
this
.
listsFlags
[
this
.
list
.
id
]?.
isLoading
;
},
loadingMore
()
{
return
this
.
listsFlags
[
this
.
list
.
id
]?.
isLoadingMore
;
},
listRef
()
{
// When list is draggable, the reference to the list needs to be accessed differently
return
this
.
canAdminList
?
this
.
$refs
.
list
.
$el
:
this
.
$refs
.
list
;
...
...
@@ -72,7 +75,7 @@ export default {
const
options
=
{
...
defaultSortableConfig
,
fallbackOnBody
:
false
,
group
:
'
board
s
-list
'
,
group
:
'
board-list
'
,
tag
:
'
ul
'
,
'
ghost-class
'
:
'
board-card-drag-active
'
,
'
data-list-id
'
:
this
.
list
.
id
,
...
...
@@ -85,7 +88,6 @@ export default {
watch
:
{
filters
:
{
handler
()
{
this
.
list
.
loadingMore
=
false
;
this
.
listRef
.
scrollTop
=
0
;
},
deep
:
true
,
...
...
@@ -124,13 +126,7 @@ export default {
this
.
listRef
.
scrollTop
=
0
;
},
loadNextPage
()
{
const
loadingDone
=
()
=>
{
this
.
list
.
loadingMore
=
false
;
};
this
.
list
.
loadingMore
=
true
;
this
.
fetchIssuesForList
({
listId
:
this
.
list
.
id
,
fetchNext
:
true
})
.
then
(
loadingDone
)
.
catch
(
loadingDone
);
this
.
fetchIssuesForList
({
listId
:
this
.
list
.
id
,
fetchNext
:
true
});
},
toggleForm
()
{
this
.
showIssueForm
=
!
this
.
showIssueForm
;
...
...
@@ -138,7 +134,7 @@ export default {
onScroll
()
{
window
.
requestAnimationFrame
(()
=>
{
if
(
!
this
.
l
ist
.
l
oadingMore
&&
!
this
.
loadingMore
&&
this
.
scrollTop
()
>
this
.
scrollHeight
()
-
this
.
scrollOffset
&&
this
.
hasNextPage
)
{
...
...
@@ -198,7 +194,7 @@ export default {
<
template
>
<div
v-show=
"
list.isExpand
ed"
v-show=
"
!list.collaps
ed"
class=
"board-list-component gl-relative gl-h-full gl-display-flex gl-flex-direction-column"
data-qa-selector=
"board_list_cards_area"
>
...
...
@@ -210,14 +206,14 @@ export default {
>
<gl-loading-icon
/>
</div>
<board-new-issue
v-if=
"list.
t
ype !== 'closed' && showIssueForm"
:list=
"list"
/>
<board-new-issue
v-if=
"list.
listT
ype !== 'closed' && showIssueForm"
:list=
"list"
/>
<component
:is=
"treeRootWrapper"
v-show=
"!loading"
ref=
"list"
v-bind=
"treeRootOptions"
:data-board=
"list.id"
:data-board-type=
"list.
t
ype"
:data-board-type=
"list.
listT
ype"
:class=
"
{ 'bg-danger-100': issuesSizeExceedsMax }"
class="board-list gl-w-full gl-h-full gl-list-style-none gl-mb-0 gl-p-2 js-board-list"
data-testid="tree-root-wrapper"
...
...
@@ -234,8 +230,8 @@ export default {
:disabled=
"disabled"
/>
<li
v-if=
"showCount"
class=
"board-list-count gl-text-center"
data-issue-id=
"-1"
>
<gl-loading-icon
v-
show=
"list.
loadingMore"
label=
"Loading more issues"
/>
<span
v-if=
"issues.length === list.issues
Size
"
>
{{
__
(
'
Showing all issues
'
)
}}
</span>
<gl-loading-icon
v-
if=
"
loadingMore"
label=
"Loading more issues"
/>
<span
v-if=
"issues.length === list.issues
Count
"
>
{{
__
(
'
Showing all issues
'
)
}}
</span>
<span
v-else
>
{{
paginatedIssueText
}}
</span>
</li>
</component>
...
...
app/assets/javascripts/boards/components/board_settings_sidebar.vue
View file @
829d6edf
...
...
@@ -53,7 +53,7 @@ export default {
return
this
.
activeList
.
label
;
},
boardListType
()
{
return
this
.
activeList
.
type
||
null
;
return
this
.
activeList
.
type
||
this
.
activeList
.
listType
||
null
;
},
listTypeTitle
()
{
return
this
.
$options
.
labelListText
;
...
...
app/assets/javascripts/boards/components/issue_card_inner.vue
View file @
829d6edf
...
...
@@ -10,6 +10,7 @@ import IssueDueDate from './issue_due_date.vue';
import
IssueTimeEstimate
from
'
./issue_time_estimate.vue
'
;
import
boardsStore
from
'
../stores/boards_store
'
;
import
{
isScopedLabel
}
from
'
~/lib/utils/common_utils
'
;
import
{
ListType
}
from
'
../constants
'
;
export
default
{
components
:
{
...
...
@@ -122,7 +123,13 @@ export default {
return
true
;
},
isNonListLabel
(
label
)
{
return
label
.
id
&&
!
(
this
.
list
.
type
===
'
label
'
&&
this
.
list
.
title
===
label
.
title
);
return
(
label
.
id
&&
!
(
(
this
.
list
.
type
===
ListType
.
label
||
this
.
list
.
listType
===
ListType
.
label
)
&&
this
.
list
.
title
===
label
.
title
)
);
},
filterByLabel
(
label
)
{
if
(
!
this
.
updateFilters
)
return
;
...
...
app/assets/javascripts/boards/components/project_select.vue
View file @
829d6edf
...
...
@@ -7,6 +7,7 @@ import eventHub from '../eventhub';
import
Api
from
'
../../api
'
;
import
{
featureAccessLevel
}
from
'
~/pages/projects/shared/permissions/constants
'
;
import
initDeprecatedJQueryDropdown
from
'
~/deprecated_jquery_dropdown
'
;
import
{
ListType
}
from
'
../constants
'
;
export
default
{
name
:
'
BoardProjectSelect
'
,
...
...
@@ -53,7 +54,10 @@ export default {
this
.
loading
=
true
;
const
additionalAttrs
=
{};
if
(
this
.
list
.
type
&&
this
.
list
.
type
!==
'
backlog
'
)
{
if
(
(
this
.
list
.
type
&&
this
.
list
.
type
!==
ListType
.
backlog
)
||
(
this
.
list
.
listType
&&
this
.
list
.
listType
!==
ListType
.
backlog
)
)
{
additionalAttrs
.
min_access_level
=
featureAccessLevel
.
EVERYONE
;
}
...
...
app/assets/javascripts/boards/stores/actions.js
View file @
829d6edf
...
...
@@ -12,7 +12,6 @@ import {
formatListsPageInfo
,
formatIssue
,
}
from
'
../boards_util
'
;
import
boardStore
from
'
~/boards/stores/boards_store
'
;
import
createFlash
from
'
~/flash
'
;
import
{
__
}
from
'
~/locale
'
;
import
updateAssigneesMutation
from
'
~/vue_shared/components/sidebar/queries/updateAssignees.mutation.graphql
'
;
...
...
@@ -119,11 +118,7 @@ export default {
},
addList
:
({
commit
},
list
)
=>
{
// Temporarily using positioning logic from boardStore
commit
(
types
.
RECEIVE_ADD_LIST_SUCCESS
,
boardStore
.
updateListPosition
({
...
list
,
doNotFetchIssues
:
true
}),
);
commit
(
types
.
RECEIVE_ADD_LIST_SUCCESS
,
list
);
},
fetchLabels
:
({
state
,
commit
},
searchTerm
)
=>
{
...
...
app/assets/javascripts/boards/stores/mutations.js
View file @
829d6edf
...
...
@@ -13,7 +13,7 @@ const notImplemented = () => {
export
const
removeIssueFromList
=
({
state
,
listId
,
issueId
})
=>
{
Vue
.
set
(
state
.
issuesByListId
,
listId
,
pull
(
state
.
issuesByListId
[
listId
],
issueId
));
const
list
=
state
.
boardLists
[
listId
];
Vue
.
set
(
state
.
boardLists
,
listId
,
{
...
list
,
issues
Size
:
list
.
issuesSize
-
1
});
Vue
.
set
(
state
.
boardLists
,
listId
,
{
...
list
,
issues
Count
:
list
.
issuesCount
-
1
});
};
export
const
addIssueToList
=
({
state
,
listId
,
issueId
,
moveBeforeId
,
moveAfterId
,
atIndex
})
=>
{
...
...
@@ -27,7 +27,7 @@ export const addIssueToList = ({ state, listId, issueId, moveBeforeId, moveAfter
listIssues
.
splice
(
newIndex
,
0
,
issueId
);
Vue
.
set
(
state
.
issuesByListId
,
listId
,
listIssues
);
const
list
=
state
.
boardLists
[
listId
];
Vue
.
set
(
state
.
boardLists
,
listId
,
{
...
list
,
issues
Size
:
list
.
issuesSize
+
1
});
Vue
.
set
(
state
.
boardLists
,
listId
,
{
...
list
,
issues
Count
:
list
.
issuesCount
+
1
});
};
export
default
{
...
...
ee/app/assets/javascripts/boards/components/epics_swimlanes.vue
View file @
829d6edf
...
...
@@ -8,6 +8,7 @@ import defaultSortableConfig from '~/sortable/sortable_config';
import
{
n__
}
from
'
~/locale
'
;
import
EpicLane
from
'
./epic_lane.vue
'
;
import
IssuesLaneList
from
'
./issues_lane_list.vue
'
;
import
{
isListDraggable
}
from
'
~/boards/boards_util
'
;
export
default
{
components
:
{
...
...
@@ -94,6 +95,9 @@ export default {
}
});
},
isListDraggable
(
list
)
{
return
isListDraggable
(
list
);
},
},
};
</
script
>
...
...
@@ -115,8 +119,8 @@ export default {
v-for=
"list in lists"
:key=
"list.id"
:class=
"
{
'is-collapsed':
!list.isExpand
ed,
'is-draggable':
!list.preset
,
'is-collapsed':
list.collaps
ed,
'is-draggable':
isListDraggable(list)
,
}"
class="board gl-display-inline-block gl-px-3 gl-vertical-align-top gl-white-space-normal"
:data-list-id="list.id"
...
...
ee/app/assets/javascripts/boards/components/issues_lane_list.vue
View file @
829d6edf
...
...
@@ -155,7 +155,7 @@ export default {
<
template
>
<div
class=
"board gl-px-3 gl-vertical-align-top gl-white-space-normal gl-display-flex gl-flex-shrink-0"
:class=
"
{ 'is-collapsed':
!list.isExpand
ed }"
:class=
"
{ 'is-collapsed':
list.collaps
ed }"
>
<div
class=
"board-inner gl-rounded-base gl-relative gl-w-full"
>
<board-new-issue
...
...
@@ -164,7 +164,7 @@ export default {
/>
<component
:is=
"treeRootWrapper"
v-if=
"
list.isExpand
ed"
v-if=
"
!list.collaps
ed"
v-bind=
"treeRootOptions"
class=
"board-cell gl-p-2 gl-m-0 gl-h-full"
data-testid=
"tree-root-wrapper"
...
...
ee/app/assets/javascripts/boards/stores/actions.js
View file @
829d6edf
...
...
@@ -212,7 +212,7 @@ export default {
const
list
=
data
.
boardListUpdateLimitMetrics
?.
list
;
commit
(
types
.
UPDATE_LIST_SUCCESS
,
{
listId
,
list
:
boardsStore
.
updateListPosition
({
...
list
,
doNotFetchIssues
:
true
})
,
list
,
});
}
})
...
...
ee/spec/frontend/boards/components/board_list_header_new_spec.js
View file @
829d6edf
...
...
@@ -3,9 +3,8 @@ import Vuex from 'vuex';
import
BoardListHeader
from
'
ee/boards/components/board_list_header_new.vue
'
;
import
getters
from
'
ee/boards/stores/getters
'
;
import
{
listObj
}
from
'
jest/boards/mock_data
'
;
import
{
mockList2
}
from
'
jest/boards/mock_data
'
;
import
{
ListType
,
inactiveId
}
from
'
~/boards/constants
'
;
import
List
from
'
~/boards/models/list
'
;
import
sidebarEventHub
from
'
~/sidebar/event_hub
'
;
const
localVue
=
createLocalVue
();
...
...
@@ -38,21 +37,19 @@ describe('Board List Header Component', () => {
const
boardId
=
'
1
'
;
const
listMock
=
{
...
listObj
,
list
_type
:
list
Type
,
...
mockList2
,
listType
,
collapsed
,
};
if
(
listType
===
ListType
.
assignee
)
{
delete
listMock
.
label
;
listMock
.
user
=
{};
listMock
.
assignee
=
{};
}
const
list
=
new
List
({
...
listMock
,
doNotFetchIssues
:
true
});
if
(
withLocalStorage
)
{
localStorage
.
setItem
(
`boards.
${
boardId
}
.
${
list
.
type
}
.
${
list
.
id
}
.expanded`
,
`boards.
${
boardId
}
.
${
list
Mock
.
listType
}
.
${
listMock
.
id
}
.expanded`
,
(
!
collapsed
).
toString
(),
);
}
...
...
@@ -62,7 +59,7 @@ describe('Board List Header Component', () => {
localVue
,
propsData
:
{
disabled
:
false
,
list
,
list
:
listMock
,
isSwimlanesHeader
,
},
provide
:
{
...
...
@@ -112,7 +109,7 @@ describe('Board List Header Component', () => {
});
it
(
'
does not emit event when there is an active List
'
,
()
=>
{
store
.
state
.
activeId
=
listObj
.
id
;
store
.
state
.
activeId
=
mockList2
.
id
;
createComponent
({
listType
:
hasSettings
[
0
]
});
wrapper
.
vm
.
openSidebarSettings
();
...
...
ee/spec/frontend/boards/components/epic_lane_spec.js
View file @
829d6edf
...
...
@@ -4,7 +4,7 @@ import Vuex from 'vuex';
import
EpicLane
from
'
ee/boards/components/epic_lane.vue
'
;
import
IssuesLaneList
from
'
ee/boards/components/issues_lane_list.vue
'
;
import
getters
from
'
ee/boards/stores/getters
'
;
import
{
mockEpic
,
mockLists
WithModel
,
mockIssuesByListId
,
issues
}
from
'
../mock_data
'
;
import
{
mockEpic
,
mockLists
,
mockIssuesByListId
,
issues
}
from
'
../mock_data
'
;
const
localVue
=
createLocalVue
();
localVue
.
use
(
Vuex
);
...
...
@@ -42,7 +42,7 @@ describe('EpicLane', () => {
const
defaultProps
=
{
epic
:
mockEpic
,
lists
:
mockLists
WithModel
,
lists
:
mockLists
,
disabled
:
false
,
};
...
...
ee/spec/frontend/boards/components/epics_swimlanes_spec.js
View file @
829d6edf
...
...
@@ -7,7 +7,7 @@ import EpicsSwimlanes from 'ee/boards/components/epics_swimlanes.vue';
import
IssueLaneList
from
'
ee/boards/components/issues_lane_list.vue
'
;
import
getters
from
'
ee/boards/stores/getters
'
;
import
BoardListHeader
from
'
ee_else_ce/boards/components/board_list_header_new.vue
'
;
import
{
mockLists
WithModel
,
mockEpics
,
mockIssuesByListId
,
issues
}
from
'
../mock_data
'
;
import
{
mockLists
,
mockEpics
,
mockIssuesByListId
,
issues
}
from
'
../mock_data
'
;
const
localVue
=
createLocalVue
();
localVue
.
use
(
Vuex
);
...
...
@@ -41,7 +41,7 @@ describe('EpicsSwimlanes', () => {
const
createComponent
=
(
props
=
{})
=>
{
const
store
=
createStore
();
const
defaultProps
=
{
lists
:
mockLists
WithModel
,
lists
:
mockLists
,
disabled
:
false
,
};
...
...
ee/spec/frontend/boards/components/issues_lane_list_spec.js
View file @
829d6edf
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
IssuesLaneList
from
'
ee/boards/components/issues_lane_list.vue
'
;
import
{
listObj
}
from
'
jest/boards/mock_data
'
;
import
{
mockList
}
from
'
jest/boards/mock_data
'
;
import
BoardCard
from
'
~/boards/components/board_card_layout.vue
'
;
import
{
ListType
}
from
'
~/boards/constants
'
;
import
List
from
'
~/boards/models/list
'
;
import
{
createStore
}
from
'
~/boards/stores
'
;
import
{
mockIssues
}
from
'
../mock_data
'
;
...
...
@@ -13,8 +12,8 @@ describe('IssuesLaneList', () => {
const
createComponent
=
({
listType
=
ListType
.
backlog
,
collapsed
=
false
}
=
{})
=>
{
const
listMock
=
{
...
listObj
,
list
_type
:
list
Type
,
...
mockList
,
listType
,
collapsed
,
};
...
...
@@ -23,12 +22,10 @@ describe('IssuesLaneList', () => {
listMock
.
user
=
{};
}
const
list
=
new
List
({
...
listMock
,
doNotFetchIssues
:
true
});
wrapper
=
shallowMount
(
IssuesLaneList
,
{
store
,
propsData
:
{
list
,
list
:
listMock
,
issues
:
mockIssues
,
disabled
:
false
,
canAdminList
:
true
,
...
...
ee/spec/frontend/boards/stores/actions_spec.js
View file @
829d6edf
...
...
@@ -10,14 +10,7 @@ import { formatListIssues } from '~/boards/boards_util';
import
*
as
typesCE
from
'
~/boards/stores/mutation_types
'
;
import
*
as
commonUtils
from
'
~/lib/utils/common_utils
'
;
import
{
mergeUrlParams
,
removeParams
}
from
'
~/lib/utils/url_utility
'
;
import
{
mockLists
,
mockIssue
,
mockIssue2
,
mockEpic
,
rawIssue
,
mockListsWithModel
,
}
from
'
../mock_data
'
;
import
{
mockLists
,
mockIssue
,
mockIssue2
,
mockEpic
,
rawIssue
}
from
'
../mock_data
'
;
const
expectNotImplemented
=
action
=>
{
it
(
'
is not implemented
'
,
()
=>
{
...
...
@@ -605,7 +598,7 @@ describe('moveIssue', () => {
endpoints
:
{
fullPath
:
'
gitlab-org
'
,
boardId
:
'
1
'
},
boardType
:
'
group
'
,
disabled
:
false
,
boardLists
:
mockLists
WithModel
,
boardLists
:
mockLists
,
issuesByListId
:
listIssues
,
issues
,
};
...
...
ee/spec/frontend/boards/stores/mutations_spec.js
View file @
829d6edf
import
mutations
from
'
ee/boards/stores/mutations
'
;
import
{
mockIssue
,
mockIssue2
,
mockEpics
,
mockEpic
,
mockLists
WithModel
}
from
'
../mock_data
'
;
import
{
mockIssue
,
mockIssue2
,
mockEpics
,
mockEpic
,
mockLists
}
from
'
../mock_data
'
;
const
expectNotImplemented
=
action
=>
{
it
(
'
is not implemented
'
,
()
=>
{
...
...
@@ -10,8 +10,8 @@ const expectNotImplemented = action => {
const
epicId
=
mockEpic
.
id
;
const
initialBoardListsState
=
{
'
gid://gitlab/List/1
'
:
mockLists
WithModel
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
WithModel
[
1
],
'
gid://gitlab/List/1
'
:
mockLists
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
[
1
],
};
let
state
=
{
...
...
spec/frontend/boards/board_list_new_spec.js
View file @
829d6edf
/* global List */
import
Vuex
from
'
vuex
'
;
import
{
useFakeRequestAnimationFrame
}
from
'
helpers/fake_request_animation_frame
'
;
import
{
createLocalVue
,
mount
}
from
'
@vue/test-utils
'
;
...
...
@@ -7,7 +5,7 @@ import eventHub from '~/boards/eventhub';
import
BoardList
from
'
~/boards/components/board_list_new.vue
'
;
import
BoardCard
from
'
~/boards/components/board_card.vue
'
;
import
'
~/boards/models/list
'
;
import
{
listObj
,
mockIssuesByListId
,
issues
,
mockIssues
}
from
'
./mock_data
'
;
import
{
mockList
,
mockIssuesByListId
,
issues
,
mockIssues
}
from
'
./mock_data
'
;
import
defaultState
from
'
~/boards/stores/state
'
;
const
localVue
=
createLocalVue
();
...
...
@@ -44,12 +42,10 @@ const createComponent = ({
...
state
,
});
const
list
=
new
List
({
...
listObj
,
id
:
'
gid://gitlab/List/1
'
,
const
list
=
{
...
mockList
,
...
listProps
,
doNotFetchIssues
:
true
,
});
};
const
issue
=
{
title
:
'
Testing
'
,
id
:
1
,
...
...
@@ -59,8 +55,8 @@ const createComponent = ({
assignees
:
[],
...
listIssueProps
,
};
if
(
!
Object
.
prototype
.
hasOwnProperty
.
call
(
listProps
,
'
issues
Size
'
))
{
list
.
issues
Size
=
1
;
if
(
!
Object
.
prototype
.
hasOwnProperty
.
call
(
listProps
,
'
issues
Count
'
))
{
list
.
issues
Count
=
1
;
}
const
component
=
mount
(
BoardList
,
{
...
...
@@ -158,7 +154,7 @@ describe('Board list component', () => {
it
(
'
shows how many more issues to load
'
,
async
()
=>
{
wrapper
.
vm
.
showCount
=
true
;
wrapper
.
setProps
({
list
:
{
issues
Size
:
20
}
});
wrapper
.
setProps
({
list
:
{
issues
Count
:
20
}
});
await
wrapper
.
vm
.
$nextTick
();
expect
(
wrapper
.
find
(
'
.board-list-count
'
).
text
()).
toBe
(
'
Showing 1 of 20 issues
'
);
...
...
@@ -168,7 +164,7 @@ describe('Board list component', () => {
describe
(
'
load more issues
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
listProps
:
{
issues
Size
:
25
},
listProps
:
{
issues
Count
:
25
},
});
});
...
...
@@ -179,15 +175,19 @@ describe('Board list component', () => {
});
it
(
'
does not load issues if already loading
'
,
()
=>
{
wrapper
.
vm
.
listRef
.
dispatchEvent
(
new
Event
(
'
scroll
'
));
wrapper
=
createComponent
({
state
:
{
listsFlags
:
{
'
gid://gitlab/List/1
'
:
{
isLoadingMore
:
true
}
}
},
});
wrapper
.
vm
.
listRef
.
dispatchEvent
(
new
Event
(
'
scroll
'
));
expect
(
actions
.
fetchIssuesForList
).
toHaveBeenCalledTimes
(
1
);
expect
(
actions
.
fetchIssuesForList
).
not
.
toHaveBeenCalled
(
);
});
it
(
'
shows loading more spinner
'
,
async
()
=>
{
wrapper
=
createComponent
({
state
:
{
listsFlags
:
{
'
gid://gitlab/List/1
'
:
{
isLoadingMore
:
true
}
}
},
});
wrapper
.
vm
.
showCount
=
true
;
wrapper
.
vm
.
list
.
loadingMore
=
true
;
await
wrapper
.
vm
.
$nextTick
();
expect
(
wrapper
.
find
(
'
.board-list-count .gl-spinner
'
).
exists
()).
toBe
(
true
);
...
...
@@ -197,13 +197,13 @@ describe('Board list component', () => {
describe
(
'
max issue count warning
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
listProps
:
{
issues
Size
:
50
},
listProps
:
{
issues
Count
:
50
},
});
});
describe
(
'
when issue count exceeds max issue count
'
,
()
=>
{
it
(
'
sets background to bg-danger-100
'
,
async
()
=>
{
wrapper
.
setProps
({
list
:
{
issues
Size
:
4
,
maxIssueCount
:
3
}
});
wrapper
.
setProps
({
list
:
{
issues
Count
:
4
,
maxIssueCount
:
3
}
});
await
wrapper
.
vm
.
$nextTick
();
expect
(
wrapper
.
find
(
'
.bg-danger-100
'
).
exists
()).
toBe
(
true
);
...
...
@@ -212,7 +212,7 @@ describe('Board list component', () => {
describe
(
'
when list issue count does NOT exceed list max issue count
'
,
()
=>
{
it
(
'
does not sets background to bg-danger-100
'
,
()
=>
{
wrapper
.
setProps
({
list
:
{
issues
Size
:
2
,
maxIssueCount
:
3
}
});
wrapper
.
setProps
({
list
:
{
issues
Count
:
2
,
maxIssueCount
:
3
}
});
expect
(
wrapper
.
find
(
'
.bg-danger-100
'
).
exists
()).
toBe
(
false
);
});
...
...
spec/frontend/boards/components/board_column_new_spec.js
View file @
829d6edf
...
...
@@ -2,7 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import
{
listObj
}
from
'
jest/boards/mock_data
'
;
import
BoardColumn
from
'
~/boards/components/board_column_new.vue
'
;
import
List
from
'
~/boards/models/list
'
;
import
{
ListType
}
from
'
~/boards/constants
'
;
import
{
createStore
}
from
'
~/boards/stores
'
;
...
...
@@ -20,24 +19,22 @@ describe('Board Column Component', () => {
const
listMock
=
{
...
listObj
,
list
_type
:
list
Type
,
listType
,
collapsed
,
};
if
(
listType
===
ListType
.
assignee
)
{
delete
listMock
.
label
;
listMock
.
user
=
{};
listMock
.
assignee
=
{};
}
const
list
=
new
List
({
...
listMock
,
doNotFetchIssues
:
true
});
store
=
createStore
();
wrapper
=
shallowMount
(
BoardColumn
,
{
store
,
propsData
:
{
disabled
:
false
,
list
,
list
:
listMock
,
},
provide
:
{
boardId
,
...
...
@@ -60,7 +57,7 @@ describe('Board Column Component', () => {
it
(
'
has class is-collapsed when list is collapsed
'
,
()
=>
{
createComponent
({
collapsed
:
false
});
expect
(
wrapper
.
vm
.
list
.
isExpanded
).
toBe
(
tru
e
);
expect
(
isCollapsed
()).
toBe
(
fals
e
);
});
it
(
'
does not have class is-collapsed when list is expanded
'
,
()
=>
{
...
...
spec/frontend/boards/components/board_content_spec.js
View file @
829d6edf
...
...
@@ -5,7 +5,7 @@ import Draggable from 'vuedraggable';
import
EpicsSwimlanes
from
'
ee_component/boards/components/epics_swimlanes.vue
'
;
import
getters
from
'
ee_else_ce/boards/stores/getters
'
;
import
BoardColumn
from
'
~/boards/components/board_column.vue
'
;
import
{
mockListsWithModel
}
from
'
../mock_data
'
;
import
{
mockLists
,
mockLists
WithModel
}
from
'
../mock_data
'
;
import
BoardContent
from
'
~/boards/components/board_content.vue
'
;
const
localVue
=
createLocalVue
();
...
...
@@ -20,7 +20,7 @@ describe('BoardContent', () => {
const
defaultState
=
{
isShowingEpicsSwimlanes
:
false
,
boardLists
:
mockLists
WithModel
,
boardLists
:
mockLists
,
error
:
undefined
,
};
...
...
@@ -59,7 +59,7 @@ describe('BoardContent', () => {
it
(
'
renders a BoardColumn component per list
'
,
()
=>
{
createComponent
();
expect
(
wrapper
.
findAll
(
BoardColumn
)).
toHaveLength
(
mockLists
WithModel
.
length
);
expect
(
wrapper
.
findAll
(
BoardColumn
)).
toHaveLength
(
mockLists
.
length
);
});
it
(
'
does not display EpicsSwimlanes component
'
,
()
=>
{
...
...
spec/frontend/boards/components/board_list_header_new_spec.js
View file @
829d6edf
import
Vuex
from
'
vuex
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
listObj
}
from
'
jest/boards/mock_data
'
;
import
{
mockList2
}
from
'
jest/boards/mock_data
'
;
import
BoardListHeader
from
'
~/boards/components/board_list_header_new.vue
'
;
import
List
from
'
~/boards/models/list
'
;
import
{
ListType
}
from
'
~/boards/constants
'
;
const
localVue
=
createLocalVue
();
...
...
@@ -32,21 +31,19 @@ describe('Board List Header Component', () => {
const
boardId
=
'
1
'
;
const
listMock
=
{
...
listObj
,
list
_type
:
list
Type
,
...
mockList2
,
listType
,
collapsed
,
};
if
(
listType
===
ListType
.
assignee
)
{
delete
listMock
.
label
;
listMock
.
user
=
{};
listMock
.
assignee
=
{};
}
const
list
=
new
List
({
...
listMock
,
doNotFetchIssues
:
true
});
if
(
withLocalStorage
)
{
localStorage
.
setItem
(
`boards.
${
boardId
}
.
${
list
.
type
}
.
${
list
.
id
}
.expanded`
,
`boards.
${
boardId
}
.
${
list
Mock
.
listType
}
.
${
listMock
.
id
}
.expanded`
,
(
!
collapsed
).
toString
(),
);
}
...
...
@@ -62,7 +59,7 @@ describe('Board List Header Component', () => {
localVue
,
propsData
:
{
disabled
:
false
,
list
,
list
:
listMock
,
},
provide
:
{
boardId
,
...
...
@@ -72,8 +69,8 @@ describe('Board List Header Component', () => {
});
};
const
is
Expanded
=
()
=>
wrapper
.
vm
.
list
.
isExpand
ed
;
const
is
Collapsed
=
()
=>
!
isExpanded
()
;
const
is
Collapsed
=
()
=>
wrapper
.
vm
.
list
.
collaps
ed
;
const
is
Expanded
=
()
=>
!
isCollapsed
;
const
findAddIssueButton
=
()
=>
wrapper
.
find
({
ref
:
'
newIssueBtn
'
});
const
findCaret
=
()
=>
wrapper
.
find
(
'
.board-title-caret
'
);
...
...
@@ -125,7 +122,7 @@ describe('Board List Header Component', () => {
it
(
'
collapses expanded Column when clicking the collapse icon
'
,
async
()
=>
{
createComponent
();
expect
(
is
Expanded
()).
toBe
(
tru
e
);
expect
(
is
Collapsed
()).
toBe
(
fals
e
);
findCaret
().
vm
.
$emit
(
'
click
'
);
...
...
spec/frontend/boards/components/board_new_issue_new_spec.js
View file @
829d6edf
...
...
@@ -3,7 +3,7 @@ import { shallowMount, createLocalVue } from '@vue/test-utils';
import
BoardNewIssue
from
'
~/boards/components/board_new_issue_new.vue
'
;
import
'
~/boards/models/list
'
;
import
{
mockList
sWithModel
}
from
'
../mock_data
'
;
import
{
mockList
}
from
'
../mock_data
'
;
const
localVue
=
createLocalVue
();
...
...
@@ -37,7 +37,7 @@ describe('Issue boards new issue form', () => {
wrapper
=
shallowMount
(
BoardNewIssue
,
{
propsData
:
{
disabled
:
false
,
list
:
mockList
sWithModel
[
0
]
,
list
:
mockList
,
},
store
,
localVue
,
...
...
spec/frontend/boards/mock_data.js
View file @
829d6edf
...
...
@@ -97,7 +97,7 @@ export const mockMilestone = {
due_date
:
'
2019-12-31
'
,
};
const
assignees
=
[
export
const
assignees
=
[
{
id
:
'
gid://gitlab/User/2
'
,
username
:
'
angelina.herman
'
,
...
...
@@ -282,38 +282,39 @@ export const setMockEndpoints = (opts = {}) => {
});
};
export
const
mockLists
=
[
{
id
:
'
gid://gitlab/List/1
'
,
title
:
'
Backlog
'
,
position
:
null
,
listType
:
'
backlog
'
,
collapsed
:
false
,
label
:
null
,
assignee
:
null
,
milestone
:
null
,
loading
:
false
,
issuesSize
:
1
,
},
{
id
:
'
gid://gitlab/List/2
'
,
export
const
mockList
=
{
id
:
'
gid://gitlab/List/1
'
,
title
:
'
Backlog
'
,
position
:
null
,
listType
:
'
backlog
'
,
collapsed
:
false
,
label
:
null
,
assignee
:
null
,
milestone
:
null
,
loading
:
false
,
issuesCount
:
1
,
};
export
const
mockList2
=
{
id
:
'
gid://gitlab/List/2
'
,
title
:
'
To Do
'
,
position
:
0
,
listType
:
'
label
'
,
collapsed
:
false
,
label
:
{
id
:
'
gid://gitlab/GroupLabel/121
'
,
title
:
'
To Do
'
,
position
:
0
,
listType
:
'
label
'
,
collapsed
:
false
,
label
:
{
id
:
'
gid://gitlab/GroupLabel/121
'
,
title
:
'
To Do
'
,
color
:
'
#F0AD4E
'
,
textColor
:
'
#FFFFFF
'
,
description
:
null
,
},
assignee
:
null
,
milestone
:
null
,
loading
:
false
,
issuesSize
:
0
,
color
:
'
#F0AD4E
'
,
textColor
:
'
#FFFFFF
'
,
description
:
null
,
},
];
assignee
:
null
,
milestone
:
null
,
loading
:
false
,
issuesCount
:
0
,
};
export
const
mockLists
=
[
mockList
,
mockList2
];
export
const
mockListsById
=
keyBy
(
mockLists
,
'
id
'
);
...
...
spec/frontend/boards/stores/actions_spec.js
View file @
829d6edf
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
{
mockListsWithModel
,
mockLists
,
mockListsById
,
mockIssue
,
...
...
@@ -229,8 +228,8 @@ describe('createList', () => {
describe
(
'
moveList
'
,
()
=>
{
it
(
'
should commit MOVE_LIST mutation and dispatch updateList action
'
,
done
=>
{
const
initialBoardListsState
=
{
'
gid://gitlab/List/1
'
:
mockLists
WithModel
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
WithModel
[
1
],
'
gid://gitlab/List/1
'
:
mockLists
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
[
1
],
};
const
state
=
{
...
...
@@ -252,7 +251,7 @@ describe('moveList', () => {
[
{
type
:
types
.
MOVE_LIST
,
payload
:
{
movedList
:
mockLists
WithModel
[
0
],
listAtNewIndex
:
mockListsWithModel
[
1
]
},
payload
:
{
movedList
:
mockLists
[
0
],
listAtNewIndex
:
mockLists
[
1
]
},
},
],
[
...
...
@@ -271,8 +270,8 @@ describe('moveList', () => {
it
(
'
should not commit MOVE_LIST or dispatch updateList if listId and replacedListId are the same
'
,
()
=>
{
const
initialBoardListsState
=
{
'
gid://gitlab/List/1
'
:
mockLists
WithModel
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
WithModel
[
1
],
'
gid://gitlab/List/1
'
:
mockLists
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
[
1
],
};
const
state
=
{
...
...
@@ -512,7 +511,7 @@ describe('moveIssue', () => {
endpoints
:
{
fullPath
:
'
gitlab-org
'
,
boardId
:
'
1
'
},
boardType
:
'
group
'
,
disabled
:
false
,
boardLists
:
mockLists
WithModel
,
boardLists
:
mockLists
,
issuesByListId
:
listIssues
,
issues
,
};
...
...
spec/frontend/boards/stores/getters_spec.js
View file @
829d6edf
...
...
@@ -6,7 +6,7 @@ import {
mockIssues
,
mockIssuesByListId
,
issues
,
mockLists
WithModel
,
mockLists
,
}
from
'
../mock_data
'
;
describe
(
'
Boards - Getters
'
,
()
=>
{
...
...
@@ -94,22 +94,22 @@ describe('Boards - Getters', () => {
const boardsState = {
boardLists: {
'gid://gitlab/List/1': mockLists
WithModel
[0],
'gid://gitlab/List/2': mockLists
WithModel
[1],
'gid://gitlab/List/1': mockLists[0],
'gid://gitlab/List/2': mockLists[1],
},
};
describe('getListByLabelId', () => {
it('returns list for a given label id', () => {
expect(getters.getListByLabelId(boardsState)('gid://gitlab/GroupLabel/121')).toEqual(
mockLists
WithModel
[1],
mockLists[1],
);
});
});
describe('getListByTitle', () => {
it('returns list for a given list title', () => {
expect(getters.getListByTitle(boardsState)('To Do')).toEqual(mockLists
WithModel
[1]);
expect(getters.getListByTitle(boardsState)('To Do')).toEqual(mockLists[1]);
});
});
});
spec/frontend/boards/stores/mutations_spec.js
View file @
829d6edf
import
mutations
from
'
~/boards/stores/mutations
'
;
import
*
as
types
from
'
~/boards/stores/mutation_types
'
;
import
defaultState
from
'
~/boards/stores/state
'
;
import
{
mockLists
WithModel
,
mockLists
,
rawIssue
,
mockIssue
,
mockIssue2
}
from
'
../mock_data
'
;
import
{
mockLists
,
rawIssue
,
mockIssue
,
mockIssue2
}
from
'
../mock_data
'
;
const
expectNotImplemented
=
action
=>
{
it
(
'
is not implemented
'
,
()
=>
{
...
...
@@ -13,8 +13,8 @@ describe('Board Store Mutations', () => {
let
state
;
const
initialBoardListsState
=
{
'
gid://gitlab/List/1
'
:
mockLists
WithModel
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
WithModel
[
1
],
'
gid://gitlab/List/1
'
:
mockLists
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
[
1
],
};
beforeEach
(()
=>
{
...
...
@@ -124,10 +124,10 @@ describe('Board Store Mutations', () => {
describe
(
'
RECEIVE_ADD_LIST_SUCCESS
'
,
()
=>
{
it
(
'
adds list to boardLists state
'
,
()
=>
{
mutations
.
RECEIVE_ADD_LIST_SUCCESS
(
state
,
mockLists
WithModel
[
0
]);
mutations
.
RECEIVE_ADD_LIST_SUCCESS
(
state
,
mockLists
[
0
]);
expect
(
state
.
boardLists
).
toEqual
({
[
mockLists
WithModel
[
0
].
id
]:
mockListsWithModel
[
0
],
[
mockLists
[
0
].
id
]:
mockLists
[
0
],
});
});
});
...
...
@@ -144,13 +144,13 @@ describe('Board Store Mutations', () => {
};
mutations
.
MOVE_LIST
(
state
,
{
movedList
:
mockLists
WithModel
[
0
],
listAtNewIndex
:
mockLists
WithModel
[
1
],
movedList
:
mockLists
[
0
],
listAtNewIndex
:
mockLists
[
1
],
});
expect
(
state
.
boardLists
).
toEqual
({
'
gid://gitlab/List/2
'
:
mockLists
WithModel
[
1
],
'
gid://gitlab/List/1
'
:
mockLists
WithModel
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
[
1
],
'
gid://gitlab/List/1
'
:
mockLists
[
0
],
});
});
});
...
...
@@ -160,8 +160,8 @@ describe('Board Store Mutations', () => {
state
=
{
...
state
,
boardLists
:
{
'
gid://gitlab/List/2
'
:
mockLists
WithModel
[
1
],
'
gid://gitlab/List/1
'
:
mockLists
WithModel
[
0
],
'
gid://gitlab/List/2
'
:
mockLists
[
1
],
'
gid://gitlab/List/1
'
:
mockLists
[
0
],
},
error
:
undefined
,
};
...
...
@@ -175,7 +175,7 @@ describe('Board Store Mutations', () => {
describe
(
'
REMOVE_LIST
'
,
()
=>
{
it
(
'
removes list from boardLists
'
,
()
=>
{
const
[
list
,
secondList
]
=
mockLists
WithModel
;
const
[
list
,
secondList
]
=
mockLists
;
const
expected
=
{
[
secondList
.
id
]:
secondList
,
};
...
...
@@ -455,13 +455,13 @@ describe('Board Store Mutations', () => {
boardLists
:
initialBoardListsState
,
};
expect
(
state
.
boardLists
[
'
gid://gitlab/List/1
'
].
issues
Size
).
toBe
(
1
);
expect
(
state
.
boardLists
[
'
gid://gitlab/List/1
'
].
issues
Count
).
toBe
(
1
);
mutations
.
ADD_ISSUE_TO_LIST
(
state
,
{
list
:
mockLists
WithModel
[
0
],
issue
:
mockIssue2
});
mutations
.
ADD_ISSUE_TO_LIST
(
state
,
{
list
:
mockLists
[
0
],
issue
:
mockIssue2
});
expect
(
state
.
issuesByListId
[
'
gid://gitlab/List/1
'
]).
toContain
(
mockIssue2
.
id
);
expect
(
state
.
issues
[
mockIssue2
.
id
]).
toEqual
(
mockIssue2
);
expect
(
state
.
boardLists
[
'
gid://gitlab/List/1
'
].
issues
Size
).
toBe
(
2
);
expect
(
state
.
boardLists
[
'
gid://gitlab/List/1
'
].
issues
Count
).
toBe
(
2
);
});
});
...
...
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