BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
e49c6f86
Commit
e49c6f86
authored
Sep 19, 2016
by
Fatih Acet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Finalise cycle analytics frontend.
parent
3f3bdece
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
164 additions
and
139 deletions
+164
-139
cycle-analytics.js.es6
app/assets/javascripts/cycle-analytics.js.es6
+59
-36
dispatcher.js
app/assets/javascripts/dispatcher.js
+2
-2
cycle_analytics.scss
app/assets/stylesheets/pages/cycle_analytics.scss
+49
-47
cycle_analytics_helper.rb
app/helpers/cycle_analytics_helper.rb
+2
-2
show.html.haml
app/views/projects/cycle_analytics/show.html.haml
+52
-52
No files found.
app/assets/javascripts/cycle-analytics.js.es6
View file @
e49c6f86
((global) => {
const COOKIE_NAME = 'cycle_analytics_help_dismissed';
gl.CycleAnalytics = class CycleAnalytics {
constructor() {
const that = this;
this.isHelpDismissed = $.cookie(COOKIE_NAME);
this.vue = new Vue({
el: '#cycle-analytics',
name: 'CycleAnalytics',
created: this.fetchData(),
data: this.getData({ isLoading: true })
data: this.decorateData({ isLoading: true }),
methods: {
dismissLanding() {
that.dismissLanding();
}
}
});
}
fetchData() {
$.get('cycle_analytics.json')
.done((data) => {
this.vue.$data = this.getData(data);
this.initDropdown();
})
.error((data) => {
this.handleError(data);
})
.always(() => {
this.vue.isLoading = false;
})
fetchData(options) {
options = options || { startDate: 30 };
$.ajax({
url: $('#cycle-analytics').data('request-path'),
method: 'GET',
dataType: 'json',
contentType: 'application/json',
data: { start_date: options.startDate }
}).done((data) => {
this.vue.$data = this.decorateData(data);
this.initDropdown();
})
.error((data) => {
this.handleError(data);
})
.always(() => {
this.vue.isLoading = false;
})
}
getData(data) {
return {
notAvailable: data.notAvailable || false,
isLoading: data.isLoading || false,
analytics: {
summary: [
{ desc: 'New Issues', value: data.issues || '-' },
{ desc: 'Commits', value: data.commits || '-' },
{ desc: 'Deploys', value: data.deploys || '-' }
],
data: [
{ title: 'Issue', desc: 'Time before an issue get scheduled', value: data.issue || '-' },
{ title: 'Plan', desc: 'Time before an issue starts implementation', value: data.plan || '-' },
{ title: 'Code', desc: 'Time until first merge request', value: data.code || '-' },
{ title: 'Test', desc: 'CI test time of the default branch', value: data.test || '-' },
{ title: 'Review', desc: 'Time between MR creation and merge/close', value: data.review || '-' },
{ title: 'Deploy', desc: 'Time for a new commit to land in one of the environments', value: data.deploy || '-' }
]
}
}
decorateData(data) {
data.summary = data.summary || [];
data.stats = data.stats || [];
data.isHelpDismissed = this.isHelpDismissed;
data.isLoading = data.isLoading || false;
data.summary.forEach((item) => {
item.value = item.value || '-';
});
data.stats.forEach((item) => {
item.value = item.value || '-';
})
return data;
}
handleError(data) {
// TODO: Make sure that this is the proper error handling
new Flash('There was an error while fetching cycyle analytics data.', 'alert');
this.vue.$data = {
hasError: true,
isHelpDismissed: this.isHelpDismissed
};
new Flash('There was an error while fetching cycle analytics data.', 'alert');
}
dismissLanding() {
this.vue.isHelpDismissed = true;
$.cookie(COOKIE_NAME, true);
}
initDropdown() {
const $dropdown = $('.js-ca-dropdown');
const $label = $dropdown.find('.dropdown-label');
$dropdown.find('li a').on('click', (e) => {
$dropdown.find('li a').o
ff('click').o
n('click', (e) => {
e.preventDefault();
const $target = $(e.currentTarget);
const value = $target.data('value');
$label.text($target.text().trim());
this.vue.isLoading = true;
this.fetchData({ startDate: value });
})
}
}
})(window.gl || (window.gl = {}));
app/assets/javascripts/dispatcher.js
View file @
e49c6f86
...
...
@@ -92,7 +92,7 @@
new
MergedButtons
();
break
;
case
"projects:merge_requests:conflicts"
:
window
.
mcui
=
new
MergeConflictResolver
()
new
MergeConflictResolver
()
case
'projects:merge_requests:index'
:
shortcut_handler
=
new
ShortcutsNavigation
();
Issuable
.
init
();
...
...
@@ -187,7 +187,7 @@
new
gl
.
ProtectedBranchEditList
();
break
;
case
'projects:cycle_analytics:show'
:
window
.
ca
=
new
gl
.
CycleAnalytics
();
new
gl
.
CycleAnalytics
();
break
;
}
switch
(
path
.
first
())
{
...
...
app/assets/stylesheets/pages/cycle_analytics.scss
View file @
e49c6f86
#cycle-analytics
{
margin-top
:
24px
;
margin
:
24px
auto
0
;
width
:
800px
;
position
:
relative
;
.panel
{
...
...
@@ -22,6 +24,10 @@
.text
{
color
:
$layout-link-gray
;
}
&
:last-child
{
text-align
:
right
;
}
}
.dropdown
{
...
...
@@ -39,9 +45,13 @@
.content-list
{
li
{
padding
:
18px
$gl-padding
$gl-padding
;
.container-fluid
{
padding
:
0
;
}
}
.
col-md-10
{
.
title-col
{
span
{
&
:first-child
{
line-height
:
19px
;
...
...
@@ -54,62 +64,54 @@
}
}
.col-md-2
span
{
line-height
:
42px
;
}
}
.inner-content
{
width
:
450px
;
text-align
:
center
;
margin
:
0
auto
;
padding
:
62px
0
;
.value-col
{
text-align
:
right
;
.btn-block
{
max-width
:
130
px
;
margin
:
0
auto
;
span
{
line-height
:
42
px
;
}
}
}
h4
{
color
:
$gl-text-color
;
font-size
:
17px
;
}
.landing
{
margin-bottom
:
$gl-padding
;
overflow
:
hidden
;
p
{
color
:
#8C8C8C
;
margin-bottom
:
$gl-padding
;
.dismiss-icon
{
position
:
absolute
;
right
:
$gl-padding
;
cursor
:
pointer
;
}
}
&
.waitin
g
{
.panel
.header
{
width
:
35px
;
height
:
35
px
;
margin-bottom
:
3
px
;
sv
g
{
margin
:
0
20px
;
float
:
left
;
width
:
136
px
;
height
:
136
px
;
}
span
{
background-color
:
#F8F8F8
;
color
:
#F8F8F8
!
important
;
display
:
inline-block
;
line-height
:
13px
!
important
;
}
.inner-content
{
width
:
480px
;
float
:
left
;
.dropdown
{
opacity
:
.33
;
}
h4
{
color
:
$gl-text-color
;
font-size
:
17px
;
}
.col-md-2
span
{
position
:
relative
;
top
:
11px
;
p
{
color
:
#8C8C8C
;
margin-bottom
:
$gl-padding
;
}
}
}
.fa-spinner
{
font-size
:
32px
;
position
:
absolute
;
left
:
50%
;
top
:
50%
;
margin
:
-16px
0
0
-16px
;
}
.fa-spinner
{
font-size
:
28px
;
position
:
relative
;
margin-left
:
-20px
;
left
:
50%
;
margin-top
:
36px
;
}
}
app/helpers/cycle_analytics_helper.rb
View file @
e49c6f86
...
...
@@ -6,8 +6,8 @@ module CycleAnalyticsHelper
[
:plan
,
"Plan"
,
"Time before an issue starts implementation"
],
[
:code
,
"Code"
,
"Time until first merge request"
],
[
:test
,
"Test"
,
"Total test time for all commits/merges"
],
[
:review
,
"Review"
,
"Time between
MR
creation and merge/close"
],
[
:staging
,
"Staging"
,
"From
MR
merge until deploy to production"
],
[
:review
,
"Review"
,
"Time between
merge request
creation and merge/close"
],
[
:staging
,
"Staging"
,
"From
merge request
merge until deploy to production"
],
[
:production
,
"Production"
,
"From issue creation until deploy to production"
]]
stats
=
cycle_analytics_view_data
.
reduce
([])
do
|
stats
,
(
stage_method
,
stage_text
,
stage_description
)
|
...
...
app/views/projects/cycle_analytics/show.html.haml
View file @
e49c6f86
=
render
'projects/pipelines/head'
#cycle-analytics
{
"v-cloak"
=>
"true"
,
":class"
=>
"{ 'waiting': isLoading }"
}
.panel.panel-default
.panel-heading
Pipeline Health
#cycle-analytics
{
"v-cloak"
=>
"true"
,
data:
{
request_path:
"#{project_cycle_analytics_path(@project)}"
}}
.content-block
=
icon
(
"spinner spin"
,
"v-if"
=>
"isLoading"
)
.bordered-box.landing.content-block
{
"v-if"
=>
"!isHelpDismissed"
}
=
icon
(
'times'
,
class:
'dismiss-icon'
,
"@click"
:
"dismissLanding()"
)
=
custom_icon
(
'icon_cycle_analytics_splash'
)
.inner-content
%h4
Introducing Cycle Analytics
%p
Cycle Analytics gives an overview on how much time it takes to go from idea to production in your project.
.container-fluid
.row
%template
{
"v-for"
=>
"info in analytics.summary"
}
.col-xs-3.column
%span
.header
{{info.value}}
%br
%span
.text
{{info.desc}}
.col-xs-3.column
.dropdown.inline.js-ca-dropdown
%button
.dropdown-menu-toggle
{
"aria-expanded"
=>
"false"
,
"data-toggle"
=>
"dropdown"
,
:type
=>
"button"
}
%span
.dropdown-label
Last 30 days
%i
.fa.fa-chevron-down
%ul
.dropdown-menu.dropdown-menu-align-right
%li
%a
{
'href'
=>
"#"
,
'data-value'
=>
'30days'
}
Last 30 days
%li
%a
{
'href'
=>
"#"
,
'data-value'
=>
'90days'
}
Last 90 days
.bordered-box
=
icon
(
"spinner spin"
,
"v-if"
=>
"isLoading"
)
%ul
.content-list
{{
"v-if"
=>
"!notAvailable"
}}
%li
{
"v-for"
=>
"info in analytics.data"
}
=
button_tag
'Read more'
,
class:
'btn'
=
icon
(
"spinner spin"
,
"v-show"
=>
"isLoading"
)
.wrapper
{
"v-show"
=>
"!isLoading && !hasError"
}
.panel.panel-default
.panel-heading
Pipeline Health
.content-block
.container-fluid
.row
.col-xs-10
%span
{{info.title}}
%br
%span
{{info.desc}}
.col-xs-2
%span
{{info.value}}
.content-block
{{
"v-if"
=>
"notAvailable"
}}
.inner-content
=
custom_icon
(
'icon_cycle_analytics_splash'
)
%h4
Set up your deploys to environment!
%p
Cycle Analytics will give an overview on how much time it takes to go from an idea to production in your project.
=
button_tag
'Set up'
,
class:
'btn btn-create btn-block'
%template
{
"v-for"
=>
"item in summary"
}
.col-xs-3.column
%span
.header
{{item.value}}
%br
%span
.text
{{item.title}}
.col-xs-3.column
.dropdown.inline.js-ca-dropdown
%button
.dropdown-menu-toggle
{
"data-toggle"
=>
"dropdown"
,
:type
=>
"button"
}
%span
.dropdown-label
Last 30 days
%i
.fa.fa-chevron-down
%ul
.dropdown-menu.dropdown-menu-align-right
%li
%a
{
'href'
=>
"#"
,
'data-value'
=>
'30'
}
Last 30 days
%li
%a
{
'href'
=>
"#"
,
'data-value'
=>
'90'
}
Last 90 days
.bordered-box
%ul
.content-list
%li
{
"v-for"
=>
"item in stats"
}
.container-fluid
.row
.col-xs-10.title-col
%span
{{item.title}}
%br
%span
{{item.description}}
.col-xs-2.value-col
%span
{{item.value}}
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