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
798b17a3
Commit
798b17a3
authored
Sep 15, 2016
by
Fatih Acet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement Cycle Analytics frontend.
parent
74626106
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
256 additions
and
52 deletions
+256
-52
cycle-analytics.js.es6
app/assets/javascripts/cycle-analytics.js.es6
+70
-0
dispatcher.js
app/assets/javascripts/dispatcher.js
+3
-0
cycle_analytics.scss
app/assets/stylesheets/pages/cycle_analytics.scss
+115
-0
gitlab_routing_helper.rb
app/helpers/gitlab_routing_helper.rb
+4
-0
_project.html.haml
app/views/layouts/nav/_project.html.haml
+1
-1
show.html.haml
app/views/projects/cycle_analytics/show.html.haml
+56
-51
_head.html.haml
app/views/projects/pipelines/_head.html.haml
+5
-0
_icon_cycle_analytics_splash.svg
app/views/shared/icons/_icon_cycle_analytics_splash.svg
+2
-0
No files found.
app/assets/javascripts/cycle-analytics.js.es6
0 → 100644
View file @
798b17a3
((global) => {
gl.CycleAnalytics = class CycleAnalytics {
constructor() {
this.vue = new Vue({
el: '#cycle-analytics',
name: 'CycleAnalytics',
created: this.fetchData(),
data: this.getData({ isLoading: true })
});
}
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;
})
}
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 || '-' }
]
}
}
}
handleError(data) {
// TODO: Make sure that this is the proper error handling
new Flash('There was an error while fetching cycyle analytics data.', 'alert');
}
initDropdown() {
const $dropdown = $('.js-ca-dropdown');
const $label = $dropdown.find('.dropdown-label');
$dropdown.find('li a').on('click', (e) => {
e.preventDefault();
const $target = $(e.currentTarget);
$label.text($target.text().trim());
value = $target.data('value');
this.vue.isLoading = true;
})
}
}
})(window.gl || (window.gl = {}));
app/assets/javascripts/dispatcher.js
View file @
798b17a3
...
...
@@ -186,6 +186,9 @@
new
gl
.
ProtectedBranchCreate
();
new
gl
.
ProtectedBranchEditList
();
break
;
case
'projects:cycle_analytics:show'
:
window
.
ca
=
new
gl
.
CycleAnalytics
();
break
;
}
switch
(
path
.
first
())
{
case
'admin'
:
...
...
app/assets/stylesheets/pages/cycle_analytics.scss
0 → 100644
View file @
798b17a3
#cycle-analytics
{
margin-top
:
24px
;
.panel
{
.content-block
{
padding
:
24px
0
;
border-bottom
:
none
;
position
:
relative
;
}
.column
{
text-align
:
center
;
.header
{
font-size
:
30px
;
line-height
:
38px
;
font-weight
:
normal
;
margin
:
0
;
}
.text
{
color
:
$layout-link-gray
;
}
}
.dropdown
{
position
:
relative
;
top
:
10px
;
}
}
.bordered-box
{
border
:
1px
solid
$border-color
;
@include
border-radius
(
$border-radius-default
);
position
:
relative
;
}
.content-list
{
li
{
padding
:
18px
$gl-padding
$gl-padding
;
}
.col-md-10
{
span
{
&
:first-child
{
line-height
:
19px
;
font-size
:
15px
;
font-weight
:
600
;
}
&
:last-child
{
color
:
#8C8C8C
;
}
}
}
.col-md-2
span
{
line-height
:
42px
;
}
}
.inner-content
{
width
:
450px
;
text-align
:
center
;
margin
:
0
auto
;
padding
:
62px
0
;
.btn-block
{
max-width
:
130px
;
margin
:
0
auto
;
}
h4
{
color
:
$gl-text-color
;
font-size
:
17px
;
}
p
{
color
:
#8C8C8C
;
margin-bottom
:
$gl-padding
;
}
}
&
.waiting
{
.panel
.header
{
width
:
35px
;
height
:
35px
;
margin-bottom
:
3px
;
}
span
{
background-color
:
#F8F8F8
;
color
:
#F8F8F8
!
important
;
display
:
inline-block
;
line-height
:
13px
!
important
;
}
.dropdown
{
opacity
:
.33
;
}
.col-md-2
span
{
position
:
relative
;
top
:
11px
;
}
.fa-spinner
{
font-size
:
32px
;
position
:
absolute
;
left
:
50%
;
top
:
50%
;
margin
:
-16px
0
0
-16px
;
}
}
}
app/helpers/gitlab_routing_helper.rb
View file @
798b17a3
...
...
@@ -46,6 +46,10 @@ module GitlabRoutingHelper
namespace_project_environments_path
(
project
.
namespace
,
project
,
*
args
)
end
def
project_cycle_analytics_path
(
project
,
*
args
)
namespace_project_cycle_analytics_path
(
project
.
namespace
,
project
,
*
args
)
end
def
project_builds_path
(
project
,
*
args
)
namespace_project_builds_path
(
project
.
namespace
,
project
,
*
args
)
end
...
...
app/views/layouts/nav/_project.html.haml
View file @
798b17a3
...
...
@@ -47,7 +47,7 @@
Repository
-
if
project_nav_tab?
:pipelines
=
nav_link
(
controller:
[
:pipelines
,
:builds
,
:environments
])
do
=
nav_link
(
controller:
[
:pipelines
,
:builds
,
:environments
,
:cycle_analytics
])
do
=
link_to
project_pipelines_path
(
@project
),
title:
'Pipelines'
,
class:
'shortcuts-pipelines'
do
%span
Pipelines
...
...
app/views/projects/cycle_analytics/show.html.haml
View file @
798b17a3
%h2
Cycle Analytics from
#{
@cycle_analytics
.
from
}
to Today
%ul
.list-group
%li
.list-group-item
Issue:
-
if
issue
=
@cycle_analytics
.
issue
=
distance_of_time_in_words
issue
-
else
=
"<Not enough data>"
%li
.list-group-item
Plan:
-
if
plan
=
@cycle_analytics
.
plan
=
distance_of_time_in_words
plan
-
else
=
"<Not enough data>"
%li
.list-group-item
Code:
-
if
code
=
@cycle_analytics
.
code
.
presence
=
distance_of_time_in_words
code
-
else
=
"<Not enough data>"
%li
.list-group-item
Test:
-
if
test
=
@cycle_analytics
.
test
.
presence
=
distance_of_time_in_words
test
-
else
=
"<Not enough data>"
%li
.list-group-item
Review:
-
if
review
=
@cycle_analytics
.
review
.
presence
=
distance_of_time_in_words
review
-
else
=
"<Not enough data>"
%li
.list-group-item
Staging:
-
if
staging
=
@cycle_analytics
.
staging
.
presence
=
distance_of_time_in_words
staging
-
else
=
"<Not enough data>"
%li
.list-group-item
Production:
-
if
production
=
@cycle_analytics
.
production
.
presence
=
distance_of_time_in_words
production
-
else
=
"<Not enough data>"
=
render
'projects/pipelines/head'
#cycle-analytics
{
"v-cloak"
=>
"true"
,
":class"
=>
"{ 'waiting': isLoading }"
}
.panel.panel-default
.panel-heading
Pipeline Health
.content-block
=
icon
(
"spinner spin"
,
"v-if"
=>
"isLoading"
)
.row
%template
{
"v-for"
=>
"info in analytics.summary"
}
.col-md-3.column
%span
.header
{{info.value}}
%br
%span
.text
{{info.desc}}
.col-md-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"
}
.row
.col-md-10
%span
{{info.title}}
%br
%span
{{info.desc}}
.col-md-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'
app/views/projects/pipelines/_head.html.haml
View file @
798b17a3
...
...
@@ -19,3 +19,8 @@
=
link_to
project_environments_path
(
@project
),
title:
'Environments'
,
class:
'shortcuts-environments'
do
%span
Environments
=
nav_link
(
controller:
%w(cycle_analytics)
)
do
=
link_to
project_cycle_analytics_path
(
@project
),
title:
'Cycle Analytics'
do
%span
Cycle Analytics
app/views/shared/icons/_icon_cycle_analytics_splash.svg
0 → 100644
View file @
798b17a3
<svg
width=
"167"
height=
"166"
viewBox=
"261 77 167 166"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
><defs><path
id=
"a"
d=
"M18 84h34v9H18z"
/><mask
id=
"h"
x=
"0"
y=
"0"
width=
"34"
height=
"9"
fill=
"#fff"
><use
xlink:href=
"#a"
/></mask><path
d=
"M26 95c0 4.97 4.03 9 9 9s9-4.03 9-9"
id=
"b"
/><mask
id=
"i"
x=
"0"
y=
"0"
width=
"18"
height=
"9"
fill=
"#fff"
><use
xlink:href=
"#b"
/></mask><path
d=
"M42 48l25.564 18.26C68.91 67.22 70 69.34 70 70.994v22.004c0 2.21-1.456 2.962-3.253 1.678L42 77V48z"
id=
"c"
/><mask
id=
"j"
x=
"0"
y=
"0"
width=
"28"
height=
"47.303"
fill=
"#fff"
><use
xlink:href=
"#c"
/></mask><path
d=
"M0 48l25.564 18.26C26.91 67.22 28 69.34 28 70.994v22.004c0 2.21-1.456 2.962-3.253 1.678L0 77V48z"
id=
"d"
/><mask
id=
"k"
x=
"0"
y=
"0"
width=
"28"
height=
"47.303"
fill=
"#fff"
><use
xlink:href=
"#d"
/></mask><path
d=
"M52.994 86C59.156 79.382 62 67.656 62 49.725 62 19.235 38.032 1.18 38.032 1.18c-1.675-1.434-4.408-1.466-6.064 0C31.968 1.18 8 19.234 8 49.724 8 67.655 10.844 79.382 17.006 86h35.988z"
id=
"e"
/><mask
id=
"l"
x=
"0"
y=
"0"
width=
"54"
height=
"85.908"
fill=
"#fff"
><use
xlink:href=
"#e"
/></mask><circle
id=
"f"
cx=
"35"
cy=
"43"
r=
"13"
/><mask
id=
"m"
x=
"0"
y=
"0"
width=
"26"
height=
"26"
fill=
"#fff"
><use
xlink:href=
"#f"
/></mask><circle
id=
"g"
cx=
"35"
cy=
"43"
r=
"8"
/><mask
id=
"n"
x=
"0"
y=
"0"
width=
"16"
height=
"16"
fill=
"#fff"
><use
xlink:href=
"#g"
/></mask></defs><g
fill=
"none"
fill-rule=
"evenodd"
transform=
"translate(262 77)"
><g
transform=
"translate(47 6)"
><path
d=
"M51 132c0 2.21 1.79 4 4 4s4-1.79 4-4M11 122c0 2.21 1.79 4 4 4s4-1.79 4-4"
stroke=
"#E5E5E5"
stroke-width=
"2"
stroke-linecap=
"round"
/><rect
fill=
"#E5E5E5"
x=
"50"
y=
"107"
width=
"2"
height=
"6"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"50"
y=
"117"
width=
"2"
height=
"6"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"34"
y=
"107"
width=
"2"
height=
"6"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"42"
y=
"107"
width=
"2"
height=
"6"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"34"
y=
"117"
width=
"2"
height=
"6"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"34"
y=
"127"
width=
"2"
height=
"6"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"42"
y=
"117"
width=
"2"
height=
"30"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"26"
y=
"107"
width=
"2"
height=
"27"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"50"
y=
"127"
width=
"2"
height=
"6"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"18"
y=
"107"
width=
"2"
height=
"6"
rx=
"1"
/><rect
fill=
"#E5E5E5"
x=
"18"
y=
"117"
width=
"2"
height=
"6"
rx=
"1"
/><use
stroke=
"#E5E5E5"
mask=
"url(#h)"
stroke-width=
"4"
xlink:href=
"#a"
/><use
stroke=
"#E5E5E5"
mask=
"url(#i)"
stroke-width=
"4"
xlink:href=
"#b"
/><use
stroke=
"#E5E5E5"
mask=
"url(#j)"
stroke-width=
"4"
xlink:href=
"#c"
/><use
stroke=
"#E5E5E5"
mask=
"url(#k)"
stroke-width=
"4"
transform=
"matrix(-1 0 0 1 28 0)"
xlink:href=
"#d"
/><use
stroke=
"#E5E5E5"
mask=
"url(#l)"
stroke-width=
"4"
fill=
"#FFF"
xlink:href=
"#e"
/><use
stroke=
"#E5E5E5"
mask=
"url(#m)"
stroke-width=
"4"
xlink:href=
"#f"
/><use
stroke=
"#E5E5E5"
mask=
"url(#n)"
stroke-width=
"4"
xlink:href=
"#g"
/><path
d=
"M43 146c0 3.59 2.91 6.5 6.5 6.5s6.5-2.91 6.5-6.5M14 133c0 3.59 2.91 6.5 6.5 6.5s6.5-2.91 6.5-6.5"
stroke=
"#E5E5E5"
stroke-width=
"2"
stroke-linecap=
"round"
/></g><circle
stroke=
"#E5E5E5"
stroke-width=
"2"
cx=
"138.5"
cy=
"115.5"
r=
"6.5"
/><circle
stroke=
"#E5E5E5"
stroke-width=
"2"
cx=
"33.5"
cy=
"28.5"
r=
"6.5"
/><circle
stroke=
"#E5E5E5"
stroke-width=
"2"
cx=
"142"
cy=
"52"
r=
"4"
/><circle
stroke=
"#E5E5E5"
stroke-width=
"2"
cx=
"4"
cy=
"83"
r=
"4"
/></g></svg>
\ No newline at end of file
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