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
06de789b
Commit
06de789b
authored
Feb 17, 2021
by
Florie Guibert
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Epic multiple boards switcher
Review feedback
parent
8ae3a496
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
213 additions
and
38 deletions
+213
-38
app/assets/javascripts/boards/components/boards_selector.vue
app/assets/javascripts/boards/components/boards_selector.vue
+17
-12
app/helpers/boards_helper.rb
app/helpers/boards_helper.rb
+1
-3
ee/app/assets/javascripts/boards/components/boards_selector.vue
.../assets/javascripts/boards/components/boards_selector.vue
+24
-22
ee/app/assets/javascripts/epic_boards/index.js
ee/app/assets/javascripts/epic_boards/index.js
+0
-1
ee/app/helpers/ee/boards_helper.rb
ee/app/helpers/ee/boards_helper.rb
+7
-0
ee/spec/frontend/boards/components/boards_selector_spec.js
ee/spec/frontend/boards/components/boards_selector_spec.js
+151
-0
ee/spec/helpers/boards_helper_spec.rb
ee/spec/helpers/boards_helper_spec.rb
+13
-0
No files found.
app/assets/javascripts/boards/components/boards_selector.vue
View file @
06de789b
...
...
@@ -158,6 +158,18 @@ export default {
cancel
()
{
this
.
showPage
(
''
);
},
boardUpdate
(
data
)
{
if
(
!
data
?.[
this
.
parentType
])
{
return
[];
}
return
data
[
this
.
parentType
].
boards
.
edges
.
map
(({
node
})
=>
({
id
:
getIdFromGraphQLId
(
node
.
id
),
name
:
node
.
name
,
}));
},
boardQuery
()
{
return
this
.
groupId
?
groupQuery
:
projectQuery
;
},
loadBoards
(
toggleDropdown
=
true
)
{
if
(
toggleDropdown
&&
this
.
boards
.
length
>
0
)
{
return
;
...
...
@@ -167,21 +179,14 @@ export default {
variables
()
{
return
{
fullPath
:
this
.
fullPath
};
},
query
()
{
return
this
.
groupId
?
groupQuery
:
projectQuery
;
},
query
:
this
.
boardQuery
,
loadingKey
:
'
loadingBoards
'
,
update
(
data
)
{
if
(
!
data
?.[
this
.
parentType
])
{
return
[];
}
return
data
[
this
.
parentType
].
boards
.
edges
.
map
(({
node
})
=>
({
id
:
getIdFromGraphQLId
(
node
.
id
),
name
:
node
.
name
,
}));
},
update
:
this
.
boardUpdate
,
});
this
.
loadRecentBoards
();
},
loadRecentBoards
()
{
this
.
loadingRecentBoards
=
true
;
// Follow up to fetch recent boards using GraphQL
// https://gitlab.com/gitlab-org/gitlab/-/issues/300985
...
...
app/helpers/boards_helper.rb
View file @
06de789b
...
...
@@ -59,9 +59,7 @@ module BoardsHelper
end
def
board_base_url
if
board
.
to_type
==
"EpicBoard"
group_epic_boards_url
(
@group
)
elsif
board
.
group_board?
if
board
.
group_board?
group_boards_url
(
@group
)
else
project_boards_path
(
@project
)
...
...
ee/app/assets/javascripts/boards/components/boards_selector.vue
View file @
06de789b
...
...
@@ -10,35 +10,37 @@ import epicBoardsQuery from '../graphql/epic_boards.query.graphql';
export
default
{
extends
:
BoardsSelectorFoss
,
computed
:
{
...
mapState
([
'
isEpicBoard
'
,
'
fullPath
'
]),
...
mapState
([
'
isEpicBoard
'
]),
},
methods
:
{
epicBoardUpdate
(
data
)
{
if
(
!
data
?.
group
)
{
return
[];
}
return
data
.
group
.
epicBoards
.
nodes
.
map
((
node
)
=>
({
id
:
getIdFromGraphQLId
(
node
.
id
),
name
:
node
.
name
,
}));
},
epicBoardQuery
()
{
return
epicBoardsQuery
;
},
loadBoards
(
toggleDropdown
=
true
)
{
if
(
toggleDropdown
&&
this
.
boards
.
length
>
0
)
{
return
;
}
if
(
this
.
isEpicBoard
)
{
this
.
$apollo
.
addSmartQuery
(
'
boards
'
,
{
variables
()
{
return
{
fullPath
:
this
.
fullPath
};
},
query
()
{
return
epicBoardsQuery
;
},
loadingKey
:
'
loadingBoards
'
,
update
(
data
)
{
if
(
!
data
?.
group
)
{
return
[];
}
return
data
.
group
.
epicBoards
.
nodes
.
map
((
node
)
=>
({
id
:
getIdFromGraphQLId
(
node
.
id
),
name
:
node
.
name
,
}));
},
});
}
else
{
BoardsSelectorFoss
.
methods
.
loadBoards
.
call
(
this
);
this
.
$apollo
.
addSmartQuery
(
'
boards
'
,
{
variables
()
{
return
{
fullPath
:
this
.
fullPath
};
},
query
:
this
.
isEpicBoard
?
this
.
epicBoardQuery
:
this
.
boardQuery
,
loadingKey
:
'
loadingBoards
'
,
update
:
this
.
isEpicBoard
?
this
.
epicBoardUpdate
:
this
.
boardUpdate
,
});
if
(
!
this
.
isEpicBoard
)
{
this
.
loadRecentBoards
();
}
},
},
...
...
ee/app/assets/javascripts/epic_boards/index.js
View file @
06de789b
...
...
@@ -97,7 +97,6 @@ export default () => {
?
parseInt
(
$boardApp
.
dataset
.
boardWeight
,
10
)
:
null
,
},
isEpicBoard
:
true
,
});
},
mounted
()
{
...
...
ee/app/helpers/ee/boards_helper.rb
View file @
06de789b
...
...
@@ -33,6 +33,13 @@ module EE
super
.
merge
(
data
)
end
override
:board_base_url
def
board_base_url
return
group_epic_boards_url
(
@group
)
if
board
.
is_a?
(
::
Boards
::
EpicBoard
)
super
end
override
:recent_boards_path
def
recent_boards_path
return
recent_group_boards_path
(
@group
)
if
current_board_parent
.
is_a?
(
Group
)
...
...
ee/spec/frontend/boards/components/boards_selector_spec.js
0 → 100644
View file @
06de789b
import
{
GlDropdown
,
GlLoadingIcon
,
GlDropdownSectionHeader
}
from
'
@gitlab/ui
'
;
import
{
createLocalVue
,
mount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
BoardsSelector
from
'
ee/boards/components/boards_selector.vue
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
const
throttleDuration
=
1
;
const
localVue
=
createLocalVue
();
localVue
.
use
(
Vuex
);
function
boardGenerator
(
n
)
{
return
new
Array
(
n
).
fill
().
map
((
board
,
index
)
=>
{
const
id
=
`
${
index
}
`
;
const
name
=
`board
${
id
}
`
;
return
{
id
,
name
,
};
});
}
describe
(
'
BoardsSelector
'
,
()
=>
{
let
wrapper
;
let
allBoardsResponse
;
let
recentBoardsResponse
;
let
mock
;
const
boards
=
boardGenerator
(
20
);
const
recentBoards
=
boardGenerator
(
5
);
const
createStore
=
()
=>
{
return
new
Vuex
.
Store
({
state
:
{
isEpicBoard
:
false
,
},
});
};
const
getDropdownItems
=
()
=>
wrapper
.
findAll
(
'
.js-dropdown-item
'
);
const
getDropdownHeaders
=
()
=>
wrapper
.
findAllComponents
(
GlDropdownSectionHeader
);
const
getLoadingIcon
=
()
=>
wrapper
.
findComponent
(
GlLoadingIcon
);
const
findDropdown
=
()
=>
wrapper
.
findComponent
(
GlDropdown
);
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
const
$apollo
=
{
queries
:
{
boards
:
{
loading
:
false
,
},
},
};
allBoardsResponse
=
Promise
.
resolve
({
data
:
{
group
:
{
boards
:
{
edges
:
boards
.
map
((
board
)
=>
({
node
:
board
})),
},
},
},
});
recentBoardsResponse
=
Promise
.
resolve
({
data
:
recentBoards
,
});
const
store
=
createStore
();
wrapper
=
mount
(
BoardsSelector
,
{
localVue
,
propsData
:
{
throttleDuration
,
currentBoard
:
{
id
:
1
,
name
:
'
Development
'
,
milestone_id
:
null
,
weight
:
null
,
assignee_id
:
null
,
labels
:
[],
},
boardBaseUrl
:
`
${
TEST_HOST
}
/board/base/url`
,
hasMissingBoards
:
false
,
canAdminBoard
:
true
,
multipleIssueBoardsAvailable
:
true
,
labelsPath
:
`
${
TEST_HOST
}
/labels/path`
,
labelsWebUrl
:
`
${
TEST_HOST
}
/labels`
,
projectId
:
42
,
groupId
:
19
,
scopedIssueBoardFeatureEnabled
:
true
,
weights
:
[],
},
mocks
:
{
$apollo
},
attachTo
:
document
.
body
,
provide
:
{
fullPath
:
''
,
recentBoardsEndpoint
:
`
${
TEST_HOST
}
/recent`
,
},
store
,
});
wrapper
.
vm
.
$apollo
.
addSmartQuery
=
jest
.
fn
((
_
,
options
)
=>
{
wrapper
.
setData
({
[
options
.
loadingKey
]:
true
,
});
});
mock
.
onGet
(
`
${
TEST_HOST
}
/recent`
).
replyOnce
(
200
,
recentBoards
);
// Emits gl-dropdown show event to simulate the dropdown is opened at initialization time
findDropdown
().
vm
.
$emit
(
'
show
'
);
});
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
mock
.
restore
();
});
describe
(
'
loading
'
,
()
=>
{
// we are testing loading state, so don't resolve responses until after the tests
afterEach
(
async
()
=>
{
await
Promise
.
all
([
allBoardsResponse
,
recentBoardsResponse
]);
return
nextTick
();
});
it
(
'
shows loading spinner
'
,
()
=>
{
expect
(
getDropdownHeaders
()).
toHaveLength
(
0
);
expect
(
getDropdownItems
()).
toHaveLength
(
0
);
expect
(
getLoadingIcon
().
exists
()).
toBe
(
true
);
});
});
describe
(
'
loaded
'
,
()
=>
{
beforeEach
(
async
()
=>
{
await
wrapper
.
setData
({
loadingBoards
:
false
,
});
await
Promise
.
all
([
allBoardsResponse
,
recentBoardsResponse
]);
return
nextTick
();
});
it
(
'
hides loading spinner
'
,
async
()
=>
{
await
wrapper
.
vm
.
$nextTick
();
expect
(
getLoadingIcon
().
exists
()).
toBe
(
false
);
});
});
});
ee/spec/helpers/boards_helper_spec.rb
View file @
06de789b
...
...
@@ -33,6 +33,19 @@ RSpec.describe BoardsHelper do
end
end
describe
'#board_base_url'
do
context
'when epic board'
do
let_it_be
(
:epic_board
)
{
create
(
:epic_board
,
group:
group
)
}
it
'generates the correct url'
do
@board
=
epic_board
@group
=
group
expect
(
board_base_url
).
to
eq
"http://test.host/groups/
#{
group
.
full_path
}
/-/epic_boards"
end
end
end
describe
'#board_data'
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:board
)
{
create
(
:board
,
project:
project
)
}
...
...
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