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
306c153f
Commit
306c153f
authored
Oct 08, 2020
by
Ezekiel Kigbo
Committed by
Jacques Erasmus
Oct 08, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Retrieve selected value stream from BE
Builds the selectedValueStream data from the BE initialized data
parent
8c66149b
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
129 additions
and
28 deletions
+129
-28
ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
...javascripts/analytics/cycle_analytics/components/base.vue
+2
-0
ee/app/assets/javascripts/analytics/cycle_analytics/components/value_stream_select.vue
...lytics/cycle_analytics/components/value_stream_select.vue
+2
-2
ee/app/assets/javascripts/analytics/cycle_analytics/constants.js
...assets/javascripts/analytics/cycle_analytics/constants.js
+2
-0
ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
...ts/javascripts/analytics/cycle_analytics/store/actions.js
+10
-6
ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js
.../javascripts/analytics/cycle_analytics/store/mutations.js
+4
-2
ee/app/assets/javascripts/analytics/shared/utils.js
ee/app/assets/javascripts/analytics/shared/utils.js
+13
-0
ee/lib/gitlab/analytics/cycle_analytics/request_params.rb
ee/lib/gitlab/analytics/cycle_analytics/request_params.rb
+4
-2
ee/spec/frontend/analytics/cycle_analytics/components/base_spec.js
...rontend/analytics/cycle_analytics/components/base_spec.js
+35
-5
ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js
.../frontend/analytics/cycle_analytics/store/actions_spec.js
+20
-2
ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
...rontend/analytics/cycle_analytics/store/mutations_spec.js
+3
-3
ee/spec/frontend/analytics/shared/utils_spec.js
ee/spec/frontend/analytics/shared/utils_spec.js
+34
-6
No files found.
ee/app/assets/javascripts/analytics/cycle_analytics/components/base.vue
View file @
306c153f
...
...
@@ -65,6 +65,7 @@ export default {
'
medians
'
,
'
isLoadingValueStreams
'
,
'
selectedStageError
'
,
'
selectedValueStream
'
,
]),
// NOTE: formEvents are fetched in the same request as the list of stages (fetchGroupStagesAndEvents)
// so i think its ok to bind formEvents here even though its only used as a prop to the custom-stage-form
...
...
@@ -106,6 +107,7 @@ export default {
const
selectedProjectIds
=
this
.
selectedProjectIds
?.
length
?
this
.
selectedProjectIds
:
null
;
return
{
value_stream_id
:
this
.
selectedValueStream
?.
id
||
null
,
project_ids
:
selectedProjectIds
,
created_after
:
toYmd
(
this
.
startDate
),
created_before
:
toYmd
(
this
.
endDate
),
...
...
ee/app/assets/javascripts/analytics/cycle_analytics/components/value_stream_select.vue
View file @
306c153f
...
...
@@ -129,8 +129,8 @@ export default {
isSelected
(
id
)
{
return
Boolean
(
this
.
selectedValueStreamId
&&
this
.
selectedValueStreamId
===
id
);
},
onSelect
(
i
d
)
{
this
.
setSelectedValueStream
(
id
);
onSelect
(
selectedI
d
)
{
this
.
setSelectedValueStream
(
this
.
data
.
find
(({
id
})
=>
id
===
selectedId
)
);
},
onDelete
()
{
const
name
=
this
.
selectedValueStreamName
;
...
...
ee/app/assets/javascripts/analytics/cycle_analytics/constants.js
View file @
306c153f
...
...
@@ -61,3 +61,5 @@ export const OVERVIEW_METRICS = {
TIME_SUMMARY
:
'
TIME_SUMMARY
'
,
RECENT_ACTIVITY
:
'
RECENT_ACTIVITY
'
,
};
export
const
FETCH_VALUE_STREAM_DATA
=
'
fetchValueStreamData
'
;
ee/app/assets/javascripts/analytics/cycle_analytics/store/actions.js
View file @
306c153f
...
...
@@ -3,6 +3,7 @@ import { deprecatedCreateFlash as createFlash } from '~/flash';
import
{
__
,
sprintf
}
from
'
~/locale
'
;
import
httpStatus
from
'
~/lib/utils/http_status
'
;
import
*
as
types
from
'
./mutation_types
'
;
import
{
FETCH_VALUE_STREAM_DATA
}
from
'
../constants
'
;
import
{
removeFlash
,
throwIfUserForbidden
,
...
...
@@ -373,16 +374,19 @@ export const fetchValueStreamData = ({ dispatch }) =>
export
const
setSelectedValueStream
=
({
commit
,
dispatch
},
streamId
)
=>
{
commit
(
types
.
SET_SELECTED_VALUE_STREAM
,
streamId
);
return
dispatch
(
'
fetchValueStreamData
'
);
return
dispatch
(
FETCH_VALUE_STREAM_DATA
);
};
export
const
receiveValueStreamsSuccess
=
({
commit
,
dispatch
},
data
=
[])
=>
{
export
const
receiveValueStreamsSuccess
=
(
{
state
:
{
selectedValueStream
=
null
},
commit
,
dispatch
},
data
=
[],
)
=>
{
commit
(
types
.
RECEIVE_VALUE_STREAMS_SUCCESS
,
data
);
if
(
data
.
length
)
{
if
(
!
selectedValueStream
&&
data
.
length
)
{
const
[
firstStream
]
=
data
;
return
dispatch
(
'
setSelectedValueStream
'
,
firstStream
.
id
);
return
dispatch
(
'
setSelectedValueStream
'
,
firstStream
);
}
return
Promise
.
resolve
(
);
return
dispatch
(
FETCH_VALUE_STREAM_DATA
);
};
export
const
fetchValueStreams
=
({
commit
,
dispatch
,
getters
,
state
})
=>
{
...
...
@@ -404,7 +408,7 @@ export const fetchValueStreams = ({ commit, dispatch, getters, state }) => {
throw
error
;
});
}
return
dispatch
(
'
fetchValueStreamData
'
);
return
dispatch
(
FETCH_VALUE_STREAM_DATA
);
};
export
const
setFilters
=
({
dispatch
})
=>
{
...
...
ee/app/assets/javascripts/analytics/cycle_analytics/store/mutations.js
View file @
306c153f
...
...
@@ -91,11 +91,13 @@ export default {
createdAfter
:
startDate
=
null
,
createdBefore
:
endDate
=
null
,
selectedProjects
=
[],
selectedValueStream
=
{},
}
=
{},
)
{
state
.
isLoading
=
true
;
state
.
currentGroup
=
group
;
state
.
selectedProjects
=
selectedProjects
;
state
.
selectedValueStream
=
selectedValueStream
;
state
.
startDate
=
startDate
;
state
.
endDate
=
endDate
;
},
...
...
@@ -138,8 +140,8 @@ export default {
state
.
isDeletingValueStream
=
false
;
state
.
deleteValueStreamError
=
null
;
},
[
types
.
SET_SELECTED_VALUE_STREAM
](
state
,
streamId
)
{
state
.
selectedValueStream
=
state
.
valueStreams
?.
find
(({
id
})
=>
id
===
streamId
)
||
null
;
[
types
.
SET_SELECTED_VALUE_STREAM
](
state
,
valueStream
)
{
state
.
selectedValueStream
=
valueStream
;
},
[
types
.
REQUEST_VALUE_STREAMS
](
state
)
{
state
.
isLoadingValueStreams
=
true
;
...
...
ee/app/assets/javascripts/analytics/shared/utils.js
View file @
306c153f
...
...
@@ -10,6 +10,17 @@ export default {
export
const
formattedDate
=
d
=>
dateFormat
(
d
,
dateFormats
.
defaultDate
);
/**
* Creates a value stream object from a dataset. Returns null if no valueStreamId is present.
*
* @param {Object} dataset - The raw value stream object
* @returns {Object} - A value stream object
*/
export
const
buildValueStreamFromJson
=
valueStream
=>
{
const
{
id
,
name
,
is_custom
:
isCustom
}
=
valueStream
?
JSON
.
parse
(
valueStream
)
:
{};
return
id
?
{
id
,
name
,
isCustom
}
:
null
;
};
/**
* Creates a group object from a dataset. Returns null if no groupId is present.
*
...
...
@@ -71,6 +82,7 @@ const buildProjectsFromJSON = (projects = []) => {
* @returns {Object} - The initial data to load the app with
*/
export
const
buildCycleAnalyticsInitialData
=
({
valueStream
=
null
,
groupId
=
null
,
createdBefore
=
null
,
createdAfter
=
null
,
...
...
@@ -82,6 +94,7 @@ export const buildCycleAnalyticsInitialData = ({
labelsPath
=
''
,
milestonesPath
=
''
,
}
=
{})
=>
({
selectedValueStream
:
buildValueStreamFromJson
(
valueStream
),
group
:
groupId
?
convertObjectPropsToCamelCase
(
buildGroupFromDataset
({
...
...
ee/lib/gitlab/analytics/cycle_analytics/request_params.rb
View file @
306c153f
...
...
@@ -69,7 +69,7 @@ module Gitlab
def
to_data_attributes
{}.
tap
do
|
attrs
|
attrs
[
:group
]
=
group_data_attributes
if
group
attrs
[
:value_stream
]
=
value_stream_data_attributes
if
value_stream
attrs
[
:value_stream
]
=
value_stream_data_attributes
.
to_json
if
value_stream
attrs
[
:created_after
]
=
created_after
.
to_date
.
iso8601
attrs
[
:created_before
]
=
created_before
.
to_date
.
iso8601
attrs
[
:projects
]
=
group_projects
(
project_ids
)
if
group
&&
project_ids
.
present?
...
...
@@ -94,7 +94,9 @@ module Gitlab
def
value_stream_data_attributes
{
id:
value_stream
.
id
id:
value_stream
.
id
,
name:
value_stream
.
name
,
is_custom:
value_stream
.
custom?
}
end
...
...
ee/spec/frontend/analytics/cycle_analytics/components/base_spec.js
View file @
306c153f
...
...
@@ -52,7 +52,10 @@ const defaultFeatureFlags = {
hasCreateMultipleValueStreams
:
false
,
};
const
[
selectedValueStream
]
=
mockData
.
valueStreams
;
const
initialCycleAnalyticsState
=
{
selectedValueStream
,
createdAfter
:
mockData
.
startDate
,
createdBefore
:
mockData
.
endDate
,
group
:
currentGroup
,
...
...
@@ -627,6 +630,7 @@ describe('Cycle Analytics component', () => {
describe
(
'
Url parameters
'
,
()
=>
{
const
defaultParams
=
{
value_stream_id
:
selectedValueStream
.
id
,
created_after
:
toYmd
(
mockData
.
startDate
),
created_before
:
toYmd
(
mockData
.
endDate
),
project_ids
:
null
,
...
...
@@ -640,9 +644,6 @@ describe('Cycle Analytics component', () => {
mock
=
new
MockAdapter
(
axios
);
mockRequiredRoutes
(
mock
);
wrapper
=
await
createComponent
();
await
store
.
dispatch
(
'
initializeCycleAnalytics
'
,
initialCycleAnalyticsState
);
});
afterEach
(()
=>
{
...
...
@@ -651,12 +652,41 @@ describe('Cycle Analytics component', () => {
wrapper
=
null
;
});
it
(
'
sets the created_after and created_before url parameters
'
,
async
()
=>
{
await
shouldMergeUrlParams
(
wrapper
,
defaultParams
);
describe
(
'
with minimal parameters set set
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
await
createComponent
();
await
store
.
dispatch
(
'
initializeCycleAnalytics
'
,
{
...
initialCycleAnalyticsState
,
selectedValueStream
:
null
,
});
});
it
(
'
sets the created_after and created_before url parameters
'
,
async
()
=>
{
await
shouldMergeUrlParams
(
wrapper
,
defaultParams
);
});
});
describe
(
'
with selectedValueStream set
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
await
createComponent
();
await
store
.
dispatch
(
'
initializeCycleAnalytics
'
,
initialCycleAnalyticsState
);
await
wrapper
.
vm
.
$nextTick
();
});
it
(
'
sets the value_stream_id url parameter
'
,
async
()
=>
{
await
shouldMergeUrlParams
(
wrapper
,
{
...
defaultParams
,
created_after
:
toYmd
(
mockData
.
startDate
),
created_before
:
toYmd
(
mockData
.
endDate
),
project_ids
:
null
,
});
});
});
describe
(
'
with selectedProjectIds set
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
await
createComponent
();
store
.
dispatch
(
'
setSelectedProjects
'
,
mockData
.
selectedProjects
);
await
wrapper
.
vm
.
$nextTick
();
});
...
...
ee/spec/frontend/analytics/cycle_analytics/store/actions_spec.js
View file @
306c153f
...
...
@@ -1047,7 +1047,7 @@ describe('Cycle analytics actions', () => {
});
describe
(
'
receiveValueStreamsSuccess
'
,
()
=>
{
it
(
`
commits the
${
types
.
RECEIVE_VALUE_STREAMS_SUCCESS
}
mutation
`
,
()
=>
{
it
(
`
with a selectedValueStream in state commits the
${
types
.
RECEIVE_VALUE_STREAMS_SUCCESS
}
mutation and dispatches 'fetchValueStreamData'
`
,
()
=>
{
return
testAction
(
actions
.
receiveValueStreamsSuccess
,
valueStreams
,
...
...
@@ -1058,7 +1058,25 @@ describe('Cycle analytics actions', () => {
payload
:
valueStreams
,
},
],
[{
type
:
'
setSelectedValueStream
'
,
payload
:
selectedValueStream
.
id
}],
[{
type
:
'
fetchValueStreamData
'
}],
);
});
it
(
`commits the
${
types
.
RECEIVE_VALUE_STREAMS_SUCCESS
}
mutation and dispatches 'setSelectedValueStream'`
,
()
=>
{
return
testAction
(
actions
.
receiveValueStreamsSuccess
,
valueStreams
,
{
...
state
,
selectedValueStream
:
null
,
},
[
{
type
:
types
.
RECEIVE_VALUE_STREAMS_SUCCESS
,
payload
:
valueStreams
,
},
],
[{
type
:
'
setSelectedValueStream
'
,
payload
:
selectedValueStream
}],
);
});
});
...
...
ee/spec/frontend/analytics/cycle_analytics/store/mutations_spec.js
View file @
306c153f
...
...
@@ -96,9 +96,9 @@ describe('Cycle analytics mutations', () => {
describe
(
'
with value streams available
'
,
()
=>
{
it
.
each
`
mutation | payload
| expectedState
${
types
.
SET_SELECTED_VALUE_STREAM
}
|
${
valueStreams
[
1
]
.
id
}
|
${{
selectedValueStream
:
valueStreams
[
1
]
}
}
${
types
.
SET_SELECTED_VALUE_STREAM
}
|
${
'
fake-id
'
}
|
${{
selectedValueStream
:
{}
}}
mutation | payload | expectedState
${
types
.
SET_SELECTED_VALUE_STREAM
}
|
${
valueStreams
[
1
]}
|
${{
selectedValueStream
:
valueStreams
[
1
]
}
}
${
types
.
SET_SELECTED_VALUE_STREAM
}
|
${
'
fake-id
'
}
|
${{
selectedValueStream
:
{}
}}
`(
'$mutation with payload $payload will update state with $expectedState',
({ mutation, payload, expectedState }) => {
...
...
ee/spec/frontend/analytics/shared/utils_spec.js
View file @
306c153f
...
...
@@ -5,6 +5,12 @@ import {
filterBySearchTerm
,
}
from
'
ee/analytics/shared/utils
'
;
const
rawValueStream
=
`{
"id": 1,
"name": "Custom value stream 1",
"is_custom": true
}`
;
const
groupDataset
=
{
groupId
:
'
1
'
,
groupName
:
'
My Group
'
,
...
...
@@ -27,13 +33,13 @@ const projectDataset = {
projectPathWithNamespace
:
'
my-group/my-project
'
,
};
const
rawProjects
=
JSON
.
stringify
(
[
const
rawProjects
=
`
[
{
project_id
:
'
1
'
,
project_name
:
'
My Project
'
,
project_path_with_namespace
:
'
my-group/my-project
'
,
}
,
]
)
;
"project_id": "1"
,
"project_name": "My Project"
,
"project_path_with_namespace": "my-group/my-project"
}
]
`
;
describe
(
'
buildGroupFromDataset
'
,
()
=>
{
it
(
'
returns null if groupId is missing
'
,
()
=>
{
...
...
@@ -90,6 +96,28 @@ describe('buildCycleAnalyticsInitialData', () => {
});
});
describe
(
'
value stream
'
,
()
=>
{
it
(
'
will be set given an array of projects
'
,
()
=>
{
expect
(
buildCycleAnalyticsInitialData
({
valueStream
:
rawValueStream
})).
toMatchObject
({
selectedValueStream
:
{
id
:
1
,
name
:
'
Custom value stream 1
'
,
isCustom
:
true
,
},
});
});
it
.
each
`
value
${
null
}
${
''
}
`
(
'
will be null if given a value of `$value`
'
,
({
value
})
=>
{
expect
(
buildCycleAnalyticsInitialData
({
valueStream
:
value
})).
toMatchObject
({
selectedValueStream
:
null
,
});
});
});
describe
(
'
group
'
,
()
=>
{
it
(
"
will be set given a valid 'groupId' and all group parameters
"
,
()
=>
{
expect
(
buildCycleAnalyticsInitialData
(
groupDataset
)).
toMatchObject
({
...
...
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