Merge "add cncf and redesign"
@ -30,10 +30,10 @@ INFINITY_HTML = '∞'
|
||||
|
||||
def _extend_author_fields(record):
|
||||
record['author_link'] = make_link(
|
||||
record['author_name'], '/',
|
||||
record['author_name'], '',
|
||||
{'user_id': record['user_id'], 'company': ''})
|
||||
record['company_link'] = make_link(
|
||||
record['company_name'], '/',
|
||||
record['company_name'], '',
|
||||
{'company': record['company_name'], 'user_id': ''})
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ def _extend_record_common_fields(record):
|
||||
_extend_author_fields(record)
|
||||
record['date_str'] = format_datetime(record['date'])
|
||||
record['module_link'] = make_link(
|
||||
record['module'], '/',
|
||||
record['module'], '',
|
||||
{'module': record['module'], 'company': '', 'user_id': ''})
|
||||
record['blueprint_id_count'] = len(record.get('blueprint_id', []))
|
||||
record['bug_id_count'] = len(record.get('bug_id', []))
|
||||
@ -124,7 +124,7 @@ def extend_user(user):
|
||||
if user['companies']:
|
||||
company_name = get_current_company(user)
|
||||
user['company_link'] = make_link(
|
||||
company_name, '/', {'company': company_name, 'user_id': ''})
|
||||
company_name, '', {'company': company_name, 'user_id': ''})
|
||||
else:
|
||||
user['company_link'] = ''
|
||||
|
||||
@ -286,7 +286,7 @@ def make_link(title, uri=None, options=None):
|
||||
if param_values:
|
||||
uri += '?' + '&'.join(['%s=%s' % (n, utils.safe_encode(v))
|
||||
for n, v in six.iteritems(param_values)])
|
||||
return '<a href="%(uri)s">%(title)s</a>' % {'uri': uri, 'title': title}
|
||||
return {'uri': uri, 'title': title}
|
||||
|
||||
|
||||
def make_blueprint_link(module, name):
|
||||
|
@ -1,9 +1,10 @@
|
||||
html, body {
|
||||
font-family: 'PT Sans', arial, sans-serif;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 14px;
|
||||
height: 100%;
|
||||
color: #41454d;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
@ -22,13 +23,9 @@ p {
|
||||
margin: 6px 0px 15px 0px;
|
||||
}
|
||||
|
||||
div.page {
|
||||
width: 960px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: 'PT Sans Narrow', 'Arial Narrow', arial, sans-serif;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 23px;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
@ -38,7 +35,7 @@ h2 {
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-family: 'PT Sans Narrow', 'Arial Narrow', arial, sans-serif;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 19px;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
@ -47,7 +44,7 @@ h3 {
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-family: 'PT Sans Narrow', 'Arial Narrow', arial, sans-serif;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
@ -88,26 +85,15 @@ input[type="submit"] {
|
||||
}
|
||||
|
||||
div.drops {
|
||||
height: 60px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
div.drop label {
|
||||
color: #909cb5;
|
||||
}
|
||||
|
||||
.drop {
|
||||
height: 30px;
|
||||
float: left;
|
||||
margin-right: 23px;
|
||||
}
|
||||
|
||||
.drop:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.drop label {
|
||||
display: block;
|
||||
.drops label {
|
||||
color: #90a4b7;
|
||||
font-weight: 300;
|
||||
text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div.aheader {
|
||||
@ -130,12 +116,10 @@ div.aheader h1 a {
|
||||
}
|
||||
|
||||
div.page div.navigation {
|
||||
text-shadow: 1px 1px 0 #fff;
|
||||
padding: 4px 10px;
|
||||
border-top: 1px dashed #e9eaef;
|
||||
border-bottom: 1px dashed #e9eaef;
|
||||
color: #909cb5;
|
||||
font-size: 10pt;
|
||||
padding: 10px;
|
||||
margin: 35px 0 5px;
|
||||
background: #fff;
|
||||
box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
div.page div.navigation a {
|
||||
@ -215,8 +199,17 @@ a[target]:not([target='']):after, .ext_link:after {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
#analytics_header a:after {
|
||||
content: "";
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#analytics_header {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#analytics_header #logo {
|
||||
font-family: 'PT Sans', 'Arial Narrow', arial, sans-serif;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
font-weight: bolder;
|
||||
font-style: normal;
|
||||
font-size: 30px;
|
||||
@ -226,6 +219,14 @@ a[target]:not([target='']):after, .ext_link:after {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#analytics_header #logo {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
#analytics_header #logo a img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#analytics_header #slogan {
|
||||
font-family: georgia, serif;
|
||||
font-weight: lighter;
|
||||
@ -406,75 +407,180 @@ body .ui-tooltip {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* new top menu */
|
||||
ul#menu-stackamenu {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style-image: none;
|
||||
list-style-type: none;
|
||||
font-family: 'PT Sans Narrow', arial, sans-serif;
|
||||
div#company_container,
|
||||
div#engineer_container,
|
||||
div#module_container,
|
||||
div#module_details_container,
|
||||
div#contribution_container,
|
||||
div#user_profile_container,
|
||||
div#activity_container,
|
||||
div#users_table_wrapper,
|
||||
div#companies_container,
|
||||
div#individuals_container,
|
||||
div#new_compaines_container,
|
||||
div#affiliation_container,
|
||||
div#members_container {
|
||||
background: #fff;
|
||||
margin: 25px 0;
|
||||
border: 1px solid #d9d9e2;
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
ul#menu-stackamenu li {
|
||||
/*
|
||||
div#company_container table.dataTable.display tbody td,
|
||||
div#engineer_container table.dataTable.display tbody td,
|
||||
div#module_container table.dataTable.display tbody td,
|
||||
div#module_details_container table.dataTable.display tbody td,
|
||||
div#contribution_container table.dataTable.display tbody td,
|
||||
div#user_profile_container table.dataTable.display tbody td,
|
||||
div#activity_container table.dataTable.display tbody td,
|
||||
div#users_table_wrapper table.dataTable.display tbody td,
|
||||
div#companies_container table.dataTable.display tbody td,
|
||||
div#individuals_container table.dataTable.display tbody td,
|
||||
div#new_compaines_container table.dataTable.display tbody td,
|
||||
div#affiliation_container table.dataTable.display tbody td,
|
||||
div#members_container table.dataTable.display tbody td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
*/
|
||||
|
||||
div#company_container .pad,
|
||||
div#engineer_container .pad,
|
||||
div#module_container .pad,
|
||||
div#module_details_container .pad,
|
||||
div#contribution_container .pad,
|
||||
div#user_profile_container .pad,
|
||||
div#activity_container .pad,
|
||||
div#users_table_wrapper .pad,
|
||||
div#companies_container .pad,
|
||||
div#individuals_container .pad,
|
||||
div#new_compaines_container .pad,
|
||||
div#affiliation_container .pad,
|
||||
div#members_container .pad {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
div#affiliation_container > div#users_table_wrapper {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
div#company_container h2,
|
||||
div#engineer_container h2,
|
||||
div#module_container h2,
|
||||
div#module_details_container h2,
|
||||
div#contribution_container h2,
|
||||
div#user_profile_container h2,
|
||||
div#activity_container h2,
|
||||
div#companies_container h2,
|
||||
div#individuals_container h2,
|
||||
div#new_compaines_container h2,
|
||||
div#members_container h2 {
|
||||
color: #1c1c1c;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
#company_chart, #module_chart {
|
||||
padding-top: 0;
|
||||
width:100%;
|
||||
min-height: 450px;
|
||||
}
|
||||
|
||||
@media (max-width: 1199px) {
|
||||
#company_chart, #module_chart {
|
||||
padding-top: 0;
|
||||
}
|
||||
div#company_container h2,
|
||||
div#engineer_container h2,
|
||||
div#module_container h2,
|
||||
div#module_details_container h2,
|
||||
div#contribution_container h2,
|
||||
div#user_profile_container h2,
|
||||
div#activity_container h2,
|
||||
div#companies_container h2,
|
||||
div#individuals_container h2,
|
||||
div#new_compaines_container h2,
|
||||
div#members_container h2 {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
div#affiliation_container h1 {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
div#footer_container {
|
||||
background: #fff;
|
||||
margin: 25px 0;
|
||||
padding: 15px;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
/* new top menu */
|
||||
#menu-stackamenu {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: inline-block;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
}
|
||||
|
||||
div.stackamenu {
|
||||
text-align: left;
|
||||
padding-bottom: 10px;
|
||||
margin-left: 240px;
|
||||
margin: 15px 0 30px;
|
||||
}
|
||||
|
||||
div.stackamenu a {
|
||||
#menu-stackamenu li a {
|
||||
display: inline-block;
|
||||
color: #972D24;
|
||||
border-radius: 0;
|
||||
color: #55575c;
|
||||
font-size: 18px;
|
||||
/*text-transform: uppercase;*/
|
||||
margin: 5px 0;
|
||||
padding: 5px 20px;
|
||||
background: #eceef3;
|
||||
/*box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.7);*/
|
||||
padding: 10px;
|
||||
font-weight: 300;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
div.stackamenu a span {
|
||||
color: #943a3a;
|
||||
#menu-stackamenu li a span {
|
||||
color: #55575c;
|
||||
font-size: 110%;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
div.stackamenu a:hover {
|
||||
background: #c8e7ed;
|
||||
/*color: white;*/
|
||||
#menu-stackamenu li a:hover, #menu-stackamenu li a:active, #menu-stackamenu li a:focus {
|
||||
text-decoration: none;
|
||||
border-bottom: 2px solid #ed1944;
|
||||
}
|
||||
|
||||
div.stackamenu a:hover span {
|
||||
#menu-stackamenu li a:hover span {
|
||||
/*background: #c8e7ed;*/
|
||||
/*color: white;*/
|
||||
/*text-shadow: 0 -1px 0 #2c96c5;*/
|
||||
}
|
||||
|
||||
div.stackamenu li.current-menu-item a {
|
||||
background: #4bb2c5;
|
||||
color: white;
|
||||
/*box-shadow: 0 3px 0 #436281;*/
|
||||
a.about {
|
||||
color: #16c3de;
|
||||
text-transform: lowercase;
|
||||
border: 2px solid white;
|
||||
border-radius: 20px;
|
||||
padding: 2px 10px;
|
||||
font-size: smaller;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
}
|
||||
|
||||
div.stackamenu li.current-menu-item a:hover {
|
||||
a.about:hover, a.about:active, a.about:focus {
|
||||
background: #16c3de;
|
||||
color: #fff;
|
||||
border-color: #16c3de;
|
||||
}
|
||||
|
||||
#menu-stackamenu .current-menu-item a {
|
||||
border-bottom: 2px solid #ed1944;
|
||||
}
|
||||
|
||||
#menu-stackamenu li .current-menu-item a:hover, #menu-stackamenu li .current-menu-item a:active, #menu-stackamenu li .current-menu-item a:focus {
|
||||
background: #4bb2c5;
|
||||
text-decoration: none;
|
||||
/*color: white;*/
|
||||
/*box-shadow: 0 3px 0 #2b99ca;*/
|
||||
}
|
||||
|
||||
div.stackamenu li.current-menu-item a span {
|
||||
color: white;
|
||||
/*text-shadow: 0 -1px 0 #436281;*/
|
||||
}
|
||||
|
||||
.select2-loading {
|
||||
font-style: italic;
|
||||
color: dimgray;
|
||||
@ -506,4 +612,512 @@ div.stackamenu li.current-menu-item a span {
|
||||
|
||||
.disabled {
|
||||
color: grey;
|
||||
}
|
||||
}
|
||||
|
||||
table.dataTable tbody tr {
|
||||
background-color: #f6fafd;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
table.dataTable tbody tr a {
|
||||
color: #727272;
|
||||
}
|
||||
|
||||
table.dataTable.display tbody tr.even>.sorting_1, table.dataTable.order-column.stripe tbody tr.even>.sorting_1 {
|
||||
background-color: #edf4fc;
|
||||
}
|
||||
|
||||
table.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
table.dataTable.display tbody tr.odd>.sorting_1, table.dataTable.order-column.stripe tbody tr.odd>.sorting_1 {
|
||||
background-color: #f5fafe;
|
||||
}
|
||||
|
||||
table.dataTable.display tbody tr td:first-child {
|
||||
color: #c2d3dc;
|
||||
}
|
||||
|
||||
table.dataTable.display tbody tr td:last-child {
|
||||
color: #9da2a6;
|
||||
}
|
||||
|
||||
table.dataTable.no-footer {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
table.dataTable thead th, table.dataTable thead td {
|
||||
padding: 10px 18px;
|
||||
border-bottom: 3px solid #e7f3fe;
|
||||
}
|
||||
|
||||
.dataTables_filter, .dataTables_length, .dataTables_paginate {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.dataTables_paginate .paginate_button {
|
||||
/* border: none;
|
||||
border-radius: 50%; */
|
||||
}
|
||||
|
||||
.dataTables_paginate .paginate_button:hover {
|
||||
/* color: #000 !important;
|
||||
border: none;
|
||||
background-color: #fff;
|
||||
background: #fff;
|
||||
box-shadow: 0px 1px 1px 1px rgba(0,0,0,.3) inset; */
|
||||
}
|
||||
|
||||
.dataTables_paginate .paginate_button:active {
|
||||
/* outline: none;
|
||||
background-color: #16c3de;
|
||||
background: #16c3de;
|
||||
box-shadow: none; */
|
||||
}
|
||||
|
||||
.dataTables_paginate .paginate_button.current, .dataTables_paginate .paginate_button.current:hover {
|
||||
/* color: #fff !important;
|
||||
border: none;
|
||||
background-color: #14c3de;
|
||||
background: #14c3de;
|
||||
border-radius: 50%;
|
||||
transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-delay: 0.2s;
|
||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26); */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.select2-container--material {
|
||||
width: 100% !important;
|
||||
/**
|
||||
* Textbox
|
||||
*/
|
||||
/**
|
||||
* Dropdown
|
||||
*/
|
||||
/**
|
||||
* Options
|
||||
*/
|
||||
/**
|
||||
* Focused textbox
|
||||
*/
|
||||
/**
|
||||
* Disabled textbox
|
||||
*/
|
||||
}
|
||||
.select2-container--material ::-webkit-input-placeholder {
|
||||
color: inherit;
|
||||
}
|
||||
.select2-container--material :-ms-input-placeholder {
|
||||
color: inherit;
|
||||
}
|
||||
.select2-container--material :-ms-input-placeholder {
|
||||
color: inherit;
|
||||
}
|
||||
.select2-container--material ::placeholder {
|
||||
color: inherit;
|
||||
}
|
||||
.select2-container--material .select2-selection {
|
||||
/* @extend input */
|
||||
overflow: visible;
|
||||
font: inherit;
|
||||
touch-action: manipulation;
|
||||
margin: 0;
|
||||
line-height: inherit;
|
||||
border-radius: 0;
|
||||
box-sizing: inherit;
|
||||
/* @extend .form-control */
|
||||
display: block;
|
||||
width: 100%;
|
||||
color: #55595c;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
padding: .5rem 0 .6rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border-radius: 0;
|
||||
margin-top: .2rem;
|
||||
margin-bottom: 1rem;
|
||||
/* @extend input[type=text] */
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-radius: 0;
|
||||
outline: 0;
|
||||
width: 100%;
|
||||
font-size: 1rem;
|
||||
box-shadow: none;
|
||||
transition: all .3s;
|
||||
min-height: 2.1rem;
|
||||
}
|
||||
.select2-container--material .select2-selection .select2-selection__rendered {
|
||||
padding-left: 0;
|
||||
}
|
||||
.select2-container--material .select2-selection--single .select2-selection__rendered {
|
||||
float: left;
|
||||
}
|
||||
.select2-container--material .select2-selection--single .select2-selection__arrow {
|
||||
float: right;
|
||||
}
|
||||
.select2-container--material .select2-selection--multiple {
|
||||
/**
|
||||
* Multiple selected options
|
||||
*/
|
||||
/**
|
||||
* Multiple selected option clear button
|
||||
*/
|
||||
}
|
||||
.select2-container--material .select2-selection--multiple .select2-selection__rendered {
|
||||
width: 100%;
|
||||
}
|
||||
.select2-container--material .select2-selection--multiple .select2-selection__rendered li {
|
||||
list-style: none;
|
||||
}
|
||||
.select2-container--material .select2-selection--multiple .select2-selection__choice {
|
||||
/* @extend .mdl-chip */
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0 12px;
|
||||
border: 0;
|
||||
border-radius: 16px;
|
||||
background-color: #dedede;
|
||||
display: inline-block;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
margin: 2px 0;
|
||||
font-size: 0;
|
||||
white-space: nowrap;
|
||||
/* @extend .mdl-chip__text */
|
||||
font-size: 13px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.select2-container--material .select2-selection--multiple .select2-selection__choice__remove {
|
||||
/* Hide default content */
|
||||
font-size: 0;
|
||||
opacity: 0.38;
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
margin-top: 4px;
|
||||
margin-right: -6px;
|
||||
margin-left: 6px;
|
||||
transition: opacity;
|
||||
}
|
||||
.select2-container--material .select2-selection--multiple .select2-selection__choice__remove::before {
|
||||
content: "cancel";
|
||||
/* @extend .material-icons */
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-feature-settings: 'liga';
|
||||
-webkit-font-smoothing: antialiased;
|
||||
color: #000;
|
||||
}
|
||||
.select2-container--material .select2-selection--multiple .select2-selection__choice__remove:hover {
|
||||
opacity: 0.54;
|
||||
}
|
||||
.select2-container--material .select2-search--inline .select2-search__field {
|
||||
width: 100%;
|
||||
margin-top: 0;
|
||||
/* Match input[type=text] */
|
||||
height: 34px;
|
||||
line-height: 1;
|
||||
}
|
||||
.select2-container--material .select2-dropdown {
|
||||
border: 0;
|
||||
}
|
||||
.select2-container--material .select2-dropdown .select2-search__field {
|
||||
min-height: 2.1rem;
|
||||
margin-bottom: 16px;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
transition: all .3s;
|
||||
}
|
||||
.select2-container--material .select2-dropdown .select2-search__field:focus {
|
||||
border-bottom: 1px solid #4285f4;
|
||||
box-shadow: 0 1px 0 0 #4585f4;
|
||||
}
|
||||
.select2-container--material .select2-results__options {
|
||||
/* @extend .zf-shadow-depth* */
|
||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
|
||||
/* @extend .dropdown-content */
|
||||
background-color: #fff;
|
||||
margin: 0;
|
||||
min-width: 100px;
|
||||
max-height: 650px;
|
||||
overflow-y: auto;
|
||||
z-index: 999;
|
||||
will-change: width,height;
|
||||
/* @extend .dropdown-content inline styles */
|
||||
}
|
||||
.select2-container--material .select2-results__option {
|
||||
/* @extend .dropdown-content li */
|
||||
cursor: pointer;
|
||||
clear: both;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
line-height: 1.5rem;
|
||||
text-align: left;
|
||||
text-transform: none;
|
||||
/* @extend .dropdown-content li>a, .dropdown-content li>span */
|
||||
font-size: 1.2rem;
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
/**
|
||||
* Disabled options
|
||||
*/
|
||||
/**
|
||||
* Selected option
|
||||
*/
|
||||
/**
|
||||
* Active/hovered option
|
||||
*/
|
||||
}
|
||||
.select2-container--material .select2-results__option[aria-disabled=true] {
|
||||
/* @extend .select-dropdown li.disabled */
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
background-color: transparent !important;
|
||||
cursor: context-menu;
|
||||
/* @extend .disabled */
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.select2-container--material .select2-results__option[aria-selected=true] {
|
||||
/* @extend .dropdown-content li:active, .dropdow-content li:hover */
|
||||
color: #4285f4;
|
||||
background-color: #eee;
|
||||
}
|
||||
.select2-container--material .select2-results__option--highlighted[aria-selected] {
|
||||
background-color: #ddd;
|
||||
}
|
||||
.select2-container--material.select2-container--focus .select2-selection {
|
||||
/* @extend input[type=text]:focus */
|
||||
border-bottom: 1px solid #4285f4;
|
||||
box-shadow: 0 1px 0 0 #4585f4;
|
||||
}
|
||||
.select2-container--material.select2-container--disabled .select2-selection {
|
||||
/* @extend .select-wrapper input.select-dropdown:disabled */
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
cursor: default;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.select2-container--material.select2-container--disabled.select2-container--focus .select2-selection {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
span.chartColor {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.dataTables_filter, .dataTables_length, .dataTables_paginate {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.container_footer {
|
||||
/* background: #f2f3f7;
|
||||
background: -moz-linear-gradient(top, #f2f3f7 0%, #f4f2f6 100%);
|
||||
background: -webkit-linear-gradient(top, #f2f3f7 0%,#f4f2f6 100%);
|
||||
background: linear-gradient(to bottom, #f2f3f7 0%,#f4f2f6 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f2f3f7', endColorstr='#f4f2f6',GradientType=0 );
|
||||
*/
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 576px) {
|
||||
.container-fluid {
|
||||
max-width: 540px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.container-fluid {
|
||||
max-width: 720px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.container-fluid {
|
||||
max-width: 960px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1260px) {
|
||||
.container-fluid {
|
||||
max-width: 1140px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1480px) {
|
||||
.container-fluid {
|
||||
max-width: 100%;
|
||||
}
|
||||
.container-fluid-padding { padding: 0 60px; }
|
||||
}
|
||||
|
||||
.dataTables_length label {
|
||||
/* color: #bacbd6; */
|
||||
}
|
||||
|
||||
.dataTables_length label select {
|
||||
/* background: #fff;
|
||||
padding: 5px;
|
||||
color: #4abed5;
|
||||
border: none;
|
||||
margin-left: 5px; */
|
||||
}
|
||||
|
||||
#engineer_table tbody tr td:nth-child(3) {
|
||||
color: #c97b7a;
|
||||
}
|
||||
#engineer_table tbody tr td:nth-child(4) {
|
||||
color: #d1c17d;
|
||||
}
|
||||
#engineer_table tbody tr td:nth-child(5) {
|
||||
color: #b1c361;
|
||||
}
|
||||
#engineer_table tbody tr td:nth-child(6) {
|
||||
color: #9dd493;
|
||||
}
|
||||
#engineer_table tbody tr td:nth-child(7) {
|
||||
color: #195d15;
|
||||
}
|
||||
#engineer_table tbody tr td:nth-child(8) {
|
||||
color: #940e0d;
|
||||
}
|
||||
#engineer_table tbody tr td:nth-child(9) span {
|
||||
color: #fff;
|
||||
background: #05b175;
|
||||
border-radius: 50%;
|
||||
padding: 8px 4px;
|
||||
font-size: smaller;
|
||||
display: inline-block;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#engineer_table tbody tr td:nth-child(9) span.red {
|
||||
background: red;
|
||||
}
|
||||
.dataTables_filter input[type="search"] {
|
||||
padding: 5px;
|
||||
border: 1px solid #ccc;
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.dataTables_filter input[type="search"]::placeholder {
|
||||
/* color: #c5d9e4; */
|
||||
}
|
||||
|
||||
.dataTables_paginate .paginate_button {
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
padding: 3px 10px;
|
||||
cursor: pointer;
|
||||
margin: 0 2px;
|
||||
color: #aec4d0;
|
||||
}
|
||||
|
||||
.dataTables_paginate .paginate_button:hover, .dataTables_paginate .paginate_button:active .dataTables_paginate .paginate_button:focus {
|
||||
text-decoration: none;
|
||||
color: #aec4d0;
|
||||
}
|
||||
|
||||
.dataTables_paginate {
|
||||
/* text-align: right; */
|
||||
}
|
||||
|
||||
table.dataTable tbody th, table.dataTable tbody td {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
table.dataTable tbody tr td:nth-child(1) {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
table.dataTable thead .sorting {
|
||||
background: none;
|
||||
padding: 4px 2px 4px 10px;
|
||||
background: #00c3e0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
table.dataTable thead .sorting_desc, table.dataTable thead .sorting_asc {
|
||||
background: none;
|
||||
padding: 4px 2px 4px 4px;
|
||||
background: #00c3e0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
table.dataTable thead .sorting:nth-of-type(1) {
|
||||
padding: 4px 2px 4px 5px;
|
||||
}
|
||||
|
||||
|
||||
.select2-drop, .select2-container .select2-choice {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.select2-container .select2-choice {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
background: #fff;
|
||||
background-image: none;
|
||||
border: 1px solid #c6c2c2;
|
||||
}
|
||||
|
||||
.select2-container .select2-dropdown-open .select2-choice {
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));
|
||||
background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%);
|
||||
background-image: -ms-linear-gradient(top, #ffffff 0%,#eeeeee 50%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff',GradientType=0 );
|
||||
background-image: linear-gradient(top, #ffffff 0%,#eeeeee 50%);
|
||||
}
|
||||
|
||||
.select2-container .select2-choice .select2-arrow {
|
||||
background: #f5f5f5;
|
||||
background-image: none;
|
||||
border-radius: 0;
|
||||
border-left: 1px solid #c6c2c2;
|
||||
width: 23px;
|
||||
}
|
||||
|
||||
.select2-container.select2-dropdown-open .select2-choice .select2-arrow {
|
||||
background: transparent;
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
|
||||
.select2-container .select2-choice .select2-arrow b {
|
||||
background-position-x: 3px;
|
||||
}
|
||||
|
||||
.select2-drop-active, .select2-container-active .select2-choice, .select2-container-active .select2-choices {
|
||||
border-color: #00c3e0;
|
||||
}
|
||||
|
||||
|
BIN
stackalytics/dashboard/static/images/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
stackalytics/dashboard/static/images/android-chrome-256x256.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
stackalytics/dashboard/static/images/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
9
stackalytics/dashboard/static/images/browserconfig.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#603cba</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
BIN
stackalytics/dashboard/static/images/favicon-16x16.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
stackalytics/dashboard/static/images/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
stackalytics/dashboard/static/images/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
stackalytics/dashboard/static/images/mstile-150x150.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
24
stackalytics/dashboard/static/images/safari-pinned-tab.svg
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="300.000000pt" height="300.000000pt" viewBox="0 0 300.000000 300.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,300.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M815 2649 c-253 -149 -522 -307 -597 -352 l-138 -82 0 -105 c-2 -844
|
||||
1 -1324 7 -1330 4 -4 201 -121 438 -260 384 -226 641 -378 731 -431 l30 -18
|
||||
425 250 c233 138 437 258 453 268 16 9 36 21 45 26 9 6 76 45 149 88 72 43
|
||||
132 81 132 85 -1 4 -87 57 -193 119 -106 61 -277 162 -382 224 -104 62 -284
|
||||
168 -400 236 -115 68 -211 127 -213 131 -2 6 87 61 242 150 23 13 61 36 86 51
|
||||
25 16 101 61 170 101 69 40 179 105 245 145 66 39 193 113 282 165 90 52 163
|
||||
98 163 101 0 4 -33 26 -72 49 -40 24 -158 94 -263 155 -732 433 -857 505 -868
|
||||
505 -7 0 -220 -122 -472 -271z"/>
|
||||
<path d="M2735 2101 c-99 -59 -308 -183 -465 -276 -157 -92 -345 -203 -418
|
||||
-247 l-133 -80 213 -125 c280 -165 548 -323 790 -467 108 -64 199 -116 202
|
||||
-116 3 0 6 320 6 710 0 391 -3 710 -7 709 -5 0 -89 -49 -188 -108z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 613 B After Width: | Height: | Size: 1.9 KiB |
BIN
stackalytics/dashboard/static/images/select2old.png
Normal file
After Width: | Height: | Size: 613 B |
19
stackalytics/dashboard/static/images/site.webmanifest
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "",
|
||||
"short_name": "",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 6.4 KiB |
@ -15,14 +15,18 @@
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
String.prototype.trunc =
|
||||
function (n) {
|
||||
if (this.length <= n) return this;
|
||||
return this.substr(0, this.substr(0, n).lastIndexOf(' ')) + "…";
|
||||
};
|
||||
|
||||
function stringTrunc(string, length) {
|
||||
|
||||
if (string.length <= length) {
|
||||
return string;
|
||||
}
|
||||
|
||||
return string.substr(0, string.substr(0, length).lastIndexOf(' ')) + "...";
|
||||
}
|
||||
|
||||
function _createTimeline(data) {
|
||||
var plot_attrs = {
|
||||
var plot = $.jqplot('timeline', data, {
|
||||
gridPadding: {
|
||||
right: 35
|
||||
},
|
||||
@ -47,6 +51,10 @@ function _createTimeline(data) {
|
||||
yaxis: {
|
||||
min: 0,
|
||||
label: ''
|
||||
},
|
||||
y2axis: {
|
||||
min: 0,
|
||||
label: ''
|
||||
}
|
||||
},
|
||||
series: [
|
||||
@ -61,30 +69,21 @@ function _createTimeline(data) {
|
||||
fill: true,
|
||||
color: '#4bb2c5',
|
||||
fillColor: '#4bb2c5'
|
||||
}
|
||||
]
|
||||
}
|
||||
/* add the secondary line only if it is has positive values */
|
||||
var has_2 = false;
|
||||
for (var i=0; i<data[2].length; i++) {
|
||||
if (data[2][i][1] > 0) {
|
||||
has_2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_2) {
|
||||
plot_attrs.axes.y2axis = {min: 0, label: ''};
|
||||
plot_attrs.series.push({
|
||||
},
|
||||
{
|
||||
shadow: false,
|
||||
lineWidth: 1.5,
|
||||
showMarker: true,
|
||||
markerOptions: { size: 5 },
|
||||
markerOptions: {size: 5},
|
||||
yaxis: 'y2axis'
|
||||
});
|
||||
} else {
|
||||
data.pop();
|
||||
}
|
||||
$.jqplot('timeline', data, plot_attrs);
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
$('.navigation').resize(function () {
|
||||
plot.replot({resetAxes: true});
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function renderTimeline(options) {
|
||||
@ -109,6 +108,8 @@ function renderTableAndChart(url, container_id, table_id, chart_id, link_param,
|
||||
success: function (data) {
|
||||
|
||||
var tableData = [];
|
||||
//var chartData = [['name', 'metric']];
|
||||
|
||||
var chartData = [];
|
||||
|
||||
const limit = 10;
|
||||
@ -124,14 +125,14 @@ function renderTableAndChart(url, container_id, table_id, chart_id, link_param,
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (i < limit - 1) {
|
||||
chartData.push([data[i].name.trunc(36), data[i].metric]);
|
||||
chartData.push([stringTrunc(data[i].name, 36), data[i].metric]);
|
||||
} else {
|
||||
aggregate += data[i].metric;
|
||||
}
|
||||
|
||||
if (!data[i].link) {
|
||||
if (data[i].id) {
|
||||
data[i].link = makeLink(data[i].id, data[i].name, link_param);
|
||||
data[i].link = makeLink(data[i].id, data[i].name, link_param, true);
|
||||
} else {
|
||||
data[i].link = data[i].name
|
||||
}
|
||||
@ -147,7 +148,7 @@ function renderTableAndChart(url, container_id, table_id, chart_id, link_param,
|
||||
}
|
||||
|
||||
if (i == limit) {
|
||||
chartData.push([data[i - 1].name.trunc(36), data[i - 1].metric]);
|
||||
chartData.push([stringTrunc(data[i - 1].name, 36), data[i - 1].metric]);
|
||||
} else if (i > limit) {
|
||||
chartData.push(["others", aggregate]);
|
||||
}
|
||||
@ -166,30 +167,131 @@ function renderTableAndChart(url, container_id, table_id, chart_id, link_param,
|
||||
|
||||
if (table_id) {
|
||||
$("#" + table_id).dataTable({
|
||||
"oLanguage": {
|
||||
"sLengthMenu": "Show _MENU_ entries",
|
||||
"sSearch": "",
|
||||
//"oPaginate": {
|
||||
// "sPrevious": "<",
|
||||
// "sNext": ">"
|
||||
//}
|
||||
},
|
||||
"aLengthMenu": [
|
||||
[10, 25, 50, -1],
|
||||
[10, 25, 50, "All"]
|
||||
],
|
||||
"aaSorting": [
|
||||
[ sort_by_column, "desc" ]
|
||||
[sort_by_column, "desc"]
|
||||
],
|
||||
"sPaginationType": "full_numbers",
|
||||
"iDisplayLength": 10,
|
||||
"sPaginationType": "simple",
|
||||
"iDisplayLength": chart_id == 10,
|
||||
"aaData": tableData,
|
||||
"aoColumns": tableColumns
|
||||
"aoColumns": tableColumns,
|
||||
"autoWidth": false,
|
||||
//"sDom": '<"H"r><"clear">t<"F"pfl>',
|
||||
"fnCreatedRow": function (row, data, dataIndex) {
|
||||
|
||||
var colors = [
|
||||
"#754998",
|
||||
"#d32473",
|
||||
"#0090cd",
|
||||
"#d12148",
|
||||
"#f68121",
|
||||
"#faef01",
|
||||
"#b7cd44",
|
||||
"#764a99",
|
||||
"#d12148",
|
||||
"#43cd6e"
|
||||
]
|
||||
|
||||
if (dataIndex < 9 && table_id != 'engineer_table') {
|
||||
var span = $('<span>', {
|
||||
class: 'chartColor',
|
||||
style: 'background-color: ' + colors[dataIndex]
|
||||
});
|
||||
|
||||
$(row).children("td:nth-child(2)").prepend(span);
|
||||
}
|
||||
|
||||
if (table_id == 'engineer_table') {
|
||||
var value = Number($(row).children("td:nth-child(9)").text().replace('%', ''));
|
||||
var color = 'green';
|
||||
if (value < 60) {
|
||||
color = 'red';
|
||||
}
|
||||
$(row).children("td:nth-child(9)").html('<span class="' + color + '">' + $(row).children("td:nth-child(9)").text().replace('%', '') + '</span>');
|
||||
}
|
||||
},
|
||||
"fnDrawCallback": function () {
|
||||
//$('#' + table_id + ' thead .sorting:first-child, #'+ table_id + ' thead .sorting:nth-child(2)').text('').removeClass('sorting');
|
||||
//$('#' + table_id).parent().find('div:last-child').prependTo($('#' + table_id).parent().parent().parent().parent().parent().find('.container_footer'));
|
||||
$(".dataTables_filter input").attr("placeholder", "Search");
|
||||
if (table_id != 'engineer_table') {
|
||||
|
||||
$('#' + table_id + ' tbody tr td:nth-child(2) a').hover(function () {
|
||||
if (chart.data($(this).text()).length != 0) {
|
||||
chart.focus($(this).text());
|
||||
}
|
||||
}, function () {
|
||||
if (chart.data($(this).text()).length != 0) {
|
||||
chart.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (chart_id) {
|
||||
var plot = $.jqplot(chart_id, [chartData], {
|
||||
seriesDefaults: {
|
||||
renderer: jQuery.jqplot.PieRenderer,
|
||||
rendererOptions: {
|
||||
showDataLabels: true
|
||||
if (chart_id && chart_id != 'engineer_chart') {
|
||||
var colors = [
|
||||
"#754998",
|
||||
"#d32473",
|
||||
"#0090cd",
|
||||
"#d12148",
|
||||
"#f68121",
|
||||
"#faef01",
|
||||
"#b7cd44",
|
||||
"#764a99",
|
||||
"#d12148",
|
||||
"#43cd6e"
|
||||
];
|
||||
var chartColors = {};
|
||||
for (var i = 0; i < chartData.length; i++) {
|
||||
chartColors[chartData[i][0]] = colors[i];
|
||||
}
|
||||
|
||||
var chart = c3.generate({
|
||||
bindto: d3.select("#" + chart_id),
|
||||
legend: {
|
||||
hide: true
|
||||
},
|
||||
tooltip: {
|
||||
format: {
|
||||
value: function (value, ratio, id, index) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: { show: true, location: 'e' }
|
||||
pie: {
|
||||
expand: false
|
||||
},
|
||||
data: {
|
||||
selection: {
|
||||
enabled: true
|
||||
},
|
||||
columns: chartData,
|
||||
type: "pie",
|
||||
colors: chartColors,
|
||||
onclick: function (d, i) {
|
||||
var link = $('a[data-chart="' + d.name + '"]');
|
||||
var href = $(link).attr('href');
|
||||
|
||||
if (link.length > 0 && href !== undefined) {
|
||||
window.location.href = href;
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -220,7 +322,7 @@ function renderBarChart(chart_id, chart_data) {
|
||||
|
||||
function renderPunchCard(chart_id, chart_data) {
|
||||
$.jqplot(chart_id, chart_data, {
|
||||
seriesDefaults:{
|
||||
seriesDefaults: {
|
||||
renderer: $.jqplot.BubbleRenderer,
|
||||
rendererOptions: {
|
||||
varyBubbleColors: false,
|
||||
@ -240,7 +342,9 @@ function renderPunchCard(chart_id, chart_data) {
|
||||
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
|
||||
tickOptions: {
|
||||
formatter: function (format, val) {
|
||||
if (val < 0 || val > 23) { return "" }
|
||||
if (val < 0 || val > 23) {
|
||||
return ""
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
@ -250,7 +354,9 @@ function renderPunchCard(chart_id, chart_data) {
|
||||
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
|
||||
tickOptions: {
|
||||
formatter: function (format, val) {
|
||||
if (val < 0 || val > 6) { return "" }
|
||||
if (val < 0 || val > 6) {
|
||||
return ""
|
||||
}
|
||||
var labels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].reverse();
|
||||
return labels[val];
|
||||
}
|
||||
@ -272,7 +378,7 @@ function extendWithGravatar(record, image_size) {
|
||||
record.gravatar = $.gravatarImageURI(gravatar, {
|
||||
"image": "wavatar",
|
||||
"rating": "g",
|
||||
"size": image_size? image_size: 64
|
||||
"size": image_size ? image_size : 64
|
||||
});
|
||||
}
|
||||
|
||||
@ -292,7 +398,7 @@ function extendWithTweet(record) {
|
||||
tweet = record.author_name + " abandoned patch in " + record.module;
|
||||
} else {
|
||||
var smile = [";(", ":(", "", ":)", ":D"][record.value + 2];
|
||||
tweet = "Got " + ((record.value > 0)? "+": "") + record.value + " from " + record.author_name + " on patch in " + record.module + smile;
|
||||
tweet = "Got " + ((record.value > 0) ? "+" : "") + record.value + " from " + record.author_name + " on patch in " + record.module + smile;
|
||||
}
|
||||
} else if (record.record_type == "review") {
|
||||
tweet = record.status + " change request by " + record.author_name + " in " + record.module;
|
||||
@ -326,26 +432,58 @@ function getUrlVars() {
|
||||
return vars;
|
||||
}
|
||||
|
||||
function makeLink(id, title, param_name) {
|
||||
function makeLink(id, title, param_name, data_attr) {
|
||||
var options = {};
|
||||
var data = "";
|
||||
if (data_attr) {
|
||||
data = ' data-chart="' + title + '" ';
|
||||
}
|
||||
options[param_name] = id.toLowerCase();
|
||||
var link = makeURI("/", options);
|
||||
return "<a href=\"" + link + "\">" + title + "</a>"
|
||||
var link = makeURI("/" + window.location.pathname.split('/')[1], options);
|
||||
return "<a " + data + " href=\"" + link + "\">" + title + "</a>"
|
||||
}
|
||||
|
||||
function makeURI(uri, options) {
|
||||
var ops = {};
|
||||
|
||||
if (window.location.pathname.split('/')[1] == 'cncf') {
|
||||
ops = makeDate({project_type: "cncf-group", release: "all", metric: "commits"});
|
||||
}
|
||||
|
||||
if (window.location.pathname.split('/')[1] == 'unaffiliated') {
|
||||
ops = makeDate({project_type: "unaffiliated", release: "all", metric: "commits"});
|
||||
}
|
||||
|
||||
$.extend(ops, getUrlVars());
|
||||
if (options != null) {
|
||||
$.extend(ops, options);
|
||||
}
|
||||
var str = $.map(ops,function (val, index) {
|
||||
var str = $.map(ops, function (val, index) {
|
||||
return index + "=" + encodeURI(("" + val).replace("&", "")).toLowerCase();
|
||||
}).join("&");
|
||||
|
||||
return (str == "") ? uri : uri + "?" + str;
|
||||
}
|
||||
|
||||
function makeDate(ops) {
|
||||
var date = getUrlVars()['date'];
|
||||
|
||||
var result = {};
|
||||
|
||||
if (!date || date == 'all') {
|
||||
return ops;
|
||||
}
|
||||
|
||||
var end_date = new Date();
|
||||
var start_date = new Date().setDate(end_date.getDate() - Number(date));
|
||||
return $.extend(ops, {start_date: toTimestamp(new Date(start_date)), end_date: toTimestamp(new Date())});
|
||||
}
|
||||
|
||||
function toTimestamp(strDate) {
|
||||
var datum = Date.parse(strDate);
|
||||
return datum / 1000;
|
||||
}
|
||||
|
||||
function getPageState() {
|
||||
return {
|
||||
release: $('#release').val(),
|
||||
@ -353,13 +491,14 @@ function getPageState() {
|
||||
module: $('#module').val(),
|
||||
company: $('#company').val(),
|
||||
user_id: $('#user').val(),
|
||||
metric: $('#metric').val()
|
||||
metric: $('#metric').val(),
|
||||
date: $('#date').val()
|
||||
};
|
||||
}
|
||||
|
||||
function reload(extra) {
|
||||
window.location.search = $.map($.extend(getUrlVars(), extra), function (val, index) {
|
||||
return val? (index + "=" + val) : null;
|
||||
return val ? (index + "=" + val) : null;
|
||||
}).join("&")
|
||||
}
|
||||
|
||||
@ -368,44 +507,114 @@ function initSingleSelector(name, api_url, select2_extra_options, change_handler
|
||||
|
||||
$(selectorId).val(0).select2({
|
||||
data: [
|
||||
{id: 0, text: "Loading..." }
|
||||
{id: 0, text: "Loading..."}
|
||||
],
|
||||
formatSelection: function (item) {
|
||||
return "<div class=\"select2-loading\">" + item.text + "</div>"
|
||||
}
|
||||
}).select2("enable", false);
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: api_url,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
var initial_value = getUrlVars()[name];
|
||||
if (initial_value) {
|
||||
initial_value = (initial_value).toLocaleLowerCase();
|
||||
} else if (data["default"]) {
|
||||
initial_value = data["default"];
|
||||
if (name == 'date') {
|
||||
var initial_value = getUrlVars()[name];
|
||||
if (initial_value) {
|
||||
initial_value = (initial_value).toLocaleLowerCase();
|
||||
} else {
|
||||
initial_value = 'all';
|
||||
}
|
||||
$(selectorId).val(initial_value).select2($.extend({
|
||||
data: [{"text": "All", "id": "all"}, {"text": "7 days", "id": "7"}, {
|
||||
"text": "30 days",
|
||||
"id": "30"
|
||||
}, {"text": "60 days", "id": "60"}, {"text": "90 days", "id": "90"}, {
|
||||
"text": "180 days",
|
||||
"id": "180"
|
||||
}]
|
||||
}, select2_extra_options)).on("select2-selecting", function (e) {
|
||||
var options = {};
|
||||
options[name] = e.val;
|
||||
if (change_handler) {
|
||||
change_handler(options);
|
||||
}
|
||||
$(selectorId).
|
||||
val(initial_value).
|
||||
select2($.extend({
|
||||
data: data["data"]
|
||||
}, select2_extra_options)).
|
||||
on("select2-selecting",function (e) { /* don't use 'change' event, because it changes value and only after refreshes the page */
|
||||
reload(options);
|
||||
}).on("select2-removed", function (e) {
|
||||
console.log('select2-removed');
|
||||
var options = {};
|
||||
options[name] = '';
|
||||
reload(options);
|
||||
}).select2("enable", true);
|
||||
} else {
|
||||
$.ajax({
|
||||
url: api_url,
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
var initial_value = getUrlVars()[name];
|
||||
if (initial_value) {
|
||||
initial_value = (initial_value).toLocaleLowerCase();
|
||||
} else if (window.location.pathname.split('/')[1] == 'cncf') {
|
||||
|
||||
switch (name) {
|
||||
case "release":
|
||||
initial_value = "all";
|
||||
break;
|
||||
case "metric":
|
||||
initial_value = "commits";
|
||||
break;
|
||||
case "project_type":
|
||||
initial_value = "cncf-group";
|
||||
break;
|
||||
default:
|
||||
initial_value = data["default"];
|
||||
break;
|
||||
}
|
||||
} else if (window.location.pathname.split('/')[1] == 'unaffiliated') {
|
||||
switch (name) {
|
||||
case "release":
|
||||
initial_value = "all";
|
||||
break;
|
||||
case "metric":
|
||||
initial_value = "commits";
|
||||
break;
|
||||
case "project_type":
|
||||
initial_value = "unaffiliated";
|
||||
break;
|
||||
default:
|
||||
initial_value = data["default"];
|
||||
break;
|
||||
}
|
||||
} else if (data["default"]) {
|
||||
initial_value = data["default"];
|
||||
}
|
||||
|
||||
|
||||
var selectData = data["data"];
|
||||
|
||||
if (name == 'project_type') {
|
||||
selectData = processProjects(data["data"]);
|
||||
}
|
||||
|
||||
if (name == 'release') {
|
||||
var filter = "openstack";
|
||||
}
|
||||
|
||||
|
||||
$(selectorId).val(initial_value).select2($.extend({
|
||||
data: selectData
|
||||
}, select2_extra_options)).on("select2-selecting", function (e) {
|
||||
var options = {};
|
||||
options[name] = e.val;
|
||||
if (change_handler) {
|
||||
change_handler(options);
|
||||
}
|
||||
reload(options);
|
||||
}).
|
||||
on("select2-removed",function (e) {
|
||||
}).on("select2-removed", function (e) {
|
||||
console.log('select2-removed');
|
||||
var options = {};
|
||||
options[name] = '';
|
||||
reload(options);
|
||||
}).
|
||||
select2("enable", true);
|
||||
}
|
||||
});
|
||||
}).select2("enable", true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initSelectors(base_url) {
|
||||
@ -419,11 +628,40 @@ function initSelectors(base_url) {
|
||||
});
|
||||
initSingleSelector("module", makeURI(base_url + "/api/1.0/modules", {tags: "module,program,group"}), {
|
||||
formatResultCssClass: function (item) {
|
||||
return (item.tag)? ("select_module_" + item.tag): "";
|
||||
return (item.tag) ? ("select_module_" + item.tag) : "";
|
||||
},
|
||||
allowClear: true
|
||||
});
|
||||
initSingleSelector("company", makeURI(base_url + "/api/1.0/companies"), {allowClear: true});
|
||||
initSingleSelector("user_id", makeURI(base_url + "/api/1.0/users"), {allowClear: true});
|
||||
initSingleSelector("metric", makeURI(base_url + "/api/1.0/metrics"));
|
||||
initSingleSelector("date", "", {allowClear: false});
|
||||
}
|
||||
|
||||
function processProjects(data) {
|
||||
|
||||
var result = {};
|
||||
var parent = "";
|
||||
for (i = 0; i < data.length; i++) {
|
||||
if (!data[i].child) {
|
||||
//create new array
|
||||
parent = data[i].id;
|
||||
result[parent] = [data[i]]
|
||||
} else {
|
||||
result[parent].push(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var url = window.location.pathname.split('/')[1];
|
||||
|
||||
var projects = result["all"];
|
||||
|
||||
if (url == "cncf") {
|
||||
projects = result["cncf-group"];
|
||||
}
|
||||
if (url == "unaffiliated") {
|
||||
projects = result["unaffiliated"];
|
||||
}
|
||||
|
||||
return projects;
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
show_record_type=True, show_user_gravatar=True, gravatar_size=32, show_all=True,
|
||||
show_twitter=False) -%}
|
||||
|
||||
{% set page_url = request.base_url %}
|
||||
|
||||
{% if show_twitter %}
|
||||
<script>window.twttr = (function(d, s, id) {
|
||||
var js, fjs = d.getElementsByTagName(s)[0],
|
||||
@ -40,13 +42,14 @@ show_twitter=False) -%}
|
||||
{% endif %}
|
||||
|
||||
function load_activity(extra_options) {
|
||||
var options = {page_size: page_size, start_record: start_record};
|
||||
var options = {page_size: page_size, start_record: start_record, };
|
||||
$.extend(options, extra_options);
|
||||
|
||||
$.ajax({
|
||||
url: makeURI("/api/1.0/activity", options),
|
||||
dataType: "json",
|
||||
success: function (data) {
|
||||
|
||||
if (data["activity"].length < page_size) {
|
||||
$('#activity_more').hide();
|
||||
}
|
||||
@ -55,11 +58,12 @@ show_twitter=False) -%}
|
||||
}
|
||||
$.each(data["activity"], function() {
|
||||
extendWithGravatar(this, {{ gravatar_size }});
|
||||
$.extend(this, {page_url: document.location.pathname});
|
||||
{% if show_twitter %}
|
||||
extendWithTweet(this);
|
||||
{% endif %}
|
||||
});
|
||||
$("#activity_template").tmpl(data["activity"]).appendTo("#activity_container");
|
||||
$("#activity_template").tmpl(data["activity"]).insertBefore('#more_button');
|
||||
$('.ext_link').click(function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
@ -103,12 +107,12 @@ show_twitter=False) -%}
|
||||
{% raw %}
|
||||
{%if coauthor %}
|
||||
<div class="header">
|
||||
{%each(index,value) coauthor %}{%if index>0 %}, {%/if%}{%html value.author_link %} ({%html value.company_link %}){%/each%}
|
||||
{%each(index,value) coauthor %}{%if index>0 %}, {%/if%} <a href="{%html + value.author_link.uri %}">{%html value.author_link.title%}</a> (<a href="{%html page_url + value.company_link.uri %}">{%html value.company_link.title %}</a>){%/each%}
|
||||
</div>
|
||||
{%else%}
|
||||
<div class="header">{%html author_link %} ({%html company_link %})</div>
|
||||
<div class="header"><a href="{%html page_url + author_link.uri %}">{%html author_link.title %}</a> (<a href="{%html page_url + company_link.uri %}">{%html company_link.title %}</a>)</div>
|
||||
{%/if%}
|
||||
<div class="header">${date_str} in {%html module_link%}
|
||||
<div class="header">${date_str} in {%html module_link.title%}
|
||||
{%if record_type == "mark" || record_type == "review" || record_type == "patch" || record_type == "tr" %}
|
||||
{%if branch != "master" %}(${branch}){%/if%}
|
||||
{%/if%}
|
||||
@ -131,9 +135,9 @@ show_twitter=False) -%}
|
||||
<span style="color: blue">- <span>${lines_deleted}</span></span></div>
|
||||
{%elif record_type == "mark" %}
|
||||
<div class="header">Review “${parent_subject}”</div>
|
||||
<div>Change request by: {%html parent_author_link %} ({%html parent_company_link %})</div>
|
||||
<div>Change request by: <a href="{%html page_url + parent_author_link.uri %}">{%html parent_author_link.title %}</a> (<a href="{%html parent_company_link.uri %}">{%html parent_company_link.title %}</a>)</div>
|
||||
{%if patch_author_link != parent_author_link %}
|
||||
<div>Patch by: {%html patch_author_link %} ({%html patch_company_link %})</div>
|
||||
<div>Patch by: <a href="{%html patch_author_link.uri %}">{%html patch_author_link.title %}</a> (<a href="{%html patch_company_link.uri %}">{%html patch_company_link.title %}</a>)</div>
|
||||
{%/if%}
|
||||
<div>Change Id: <a href="${parent_url}" target="_blank">${review_id}</a></div>
|
||||
<div style="color: {%if value > 0 %} green {%else%} blue {%/if%}">
|
||||
@ -208,13 +212,17 @@ show_twitter=False) -%}
|
||||
{% endraw %}
|
||||
</script>
|
||||
|
||||
<h2 id="activity_header">Activity Log</h2>
|
||||
<div id="activity_container"></div>
|
||||
|
||||
<div style="height: 44px;">
|
||||
<div class="paging_full_numbers" id="activity_paginate" style="margin-left: {{ gravatar_size * 1.4 }}px;">
|
||||
<a class="last paginate_button" tabindex="0" id="activity_more">More...</a>
|
||||
<div id="activity_container">
|
||||
<h2 id="activity_header">Activity Log {% if company %} | {{ company_original }}{% endif %} </h2>
|
||||
|
||||
<div id="more_button" style="height: 44px;">
|
||||
<div class="paging_full_numbers" id="activity_paginate" style="margin-left: {{ gravatar_size * 1.4 }}px;">
|
||||
<a class="last paginate_button" tabindex="0" id="activity_more">More...</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{%- endmacro %}
|
||||
|
@ -52,7 +52,9 @@
|
||||
{% endraw %}
|
||||
</script>
|
||||
|
||||
<h2>Contribution Summary</h2>
|
||||
<div id="contribution_container"></div>
|
||||
|
||||
<div id="contribution_container">
|
||||
<h2>Contribution Summary</h2>
|
||||
</div>
|
||||
|
||||
{%- endmacro %}
|
||||
|
@ -11,7 +11,7 @@
|
||||
var module = data["module"];
|
||||
for (var i=0; i < module.modules.length; i++) {
|
||||
if(!obj.hasOwnProperty(module.modules[i].module_name)){
|
||||
module.modules[i].uri = makeURI('/', {module: module.modules[i].module_name});
|
||||
module.modules[i].uri = makeURI(document.location.pathname, {module: module.modules[i].module_name});
|
||||
unique_array.push(module.modules[i]);
|
||||
}
|
||||
obj[module.modules[i].module_name] = module.modules[i];
|
||||
|
@ -25,7 +25,7 @@
|
||||
<div style="float: left;"><img src="${gravatar}"></div>
|
||||
<div style="margin-left: 90px;">
|
||||
<h2>${user_name}</h2>
|
||||
<div>Company: {%html company_link %}
|
||||
<div>Company: <a href="{%html company_link.uri %}">{%html company_link.title %}</a>
|
||||
[<span style="font-style: italic;"><a
|
||||
href="https://wiki.openstack.org/wiki/Stackalytics#Company_affiliation" style="color: grey" target="_blank">how to change</a></span>]
|
||||
</div>
|
||||
|
@ -2,12 +2,13 @@
|
||||
<html lang="en" prefix="og: http://ogp.me/ns#">
|
||||
<head profile="http://gmpg.org/xfn/11">
|
||||
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
|
||||
|
||||
<title>Stackalytics {% if page_title %}| {{ page_title }} {% endif %}</title>
|
||||
|
||||
{% if not page_title %}
|
||||
<meta name="description" content="OpenStack contribution dashboard collects and processes development activity data such as commits, lines of code changed, code reviews, statistics on bugs, blueprints and emails"/>
|
||||
<meta name="description"
|
||||
content="OpenStack contribution dashboard collects and processes development activity data such as commits, lines of code changed, code reviews, statistics on bugs, blueprints and emails"/>
|
||||
{% else %}
|
||||
<meta name="description" content="{{ page_title }}"/>
|
||||
{% endif %}
|
||||
@ -17,41 +18,61 @@
|
||||
<meta name="runtime_storage_update_time" content="{{ runtime_storage_update_time }}"/>
|
||||
|
||||
{% if page_title %}
|
||||
<meta property="og:site_name" content="Stackalytics" />
|
||||
<meta property="og:title" content="Stackalytics | {{ page_title }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:description" content="{{ page_title }}" />
|
||||
<meta property="og:image" content="http://stackalytics.com/static/images/stackalytics_logo.png" />
|
||||
<meta property="og:site_name" content="Stackalytics"/>
|
||||
<meta property="og:title" content="Stackalytics | {{ page_title }}"/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="og:locale" content="en_US"/>
|
||||
<meta property="og:description" content="{{ page_title }}"/>
|
||||
<meta property="og:image" content="http://stackalytics.com/static/images/stackalytics_logo.png"/>
|
||||
{% endif %}
|
||||
|
||||
<link href='//fonts.googleapis.com/css?family=PT+Sans:400,700,400italic&subset=latin,cyrillic' rel='stylesheet' type='text/css' />
|
||||
<link href='//fonts.googleapis.com/css?family=PT+Sans+Caption&subset=latin,cyrillic' rel='stylesheet' type='text/css' />
|
||||
<link href='//fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700&subset=latin,cyrillic' rel='stylesheet' type='text/css' />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{ url_for('static', filename='images/apple-touch-icon.png') }}"
|
||||
">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="{{ url_for('static', filename='images/favicon-32x32.png') }}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="{{ url_for('static', filename='images/favicon-16x16.png') }}">
|
||||
<link rel="manifest" href="{{ url_for('static', filename='images/site.webmanifest') }}">
|
||||
<link rel="mask-icon" href="{{ url_for('static', filename='images/safari-pinned-tab.svg') }}" color="#14c3de">
|
||||
<meta name="msapplication-TileColor" content="#603cba">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
|
||||
|
||||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/jquery.jqplot.min.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="{{ url_for('static', filename='css/jquery-ui/jquery-ui-1.10.4.custom.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/select2.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/moonfonts.css') }}">
|
||||
|
||||
|
||||
<!-- <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css"> -->
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.8/c3.min.css">
|
||||
|
||||
<link rel="icon" href="{{ url_for('static', filename='images/favicon.png') }}" type="image/png"/>
|
||||
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/jquery.jqplot.min.css') }}">
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/jquery.dataTables.css') }}">
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/jquery-ui/jquery-ui-1.10.4.custom.css') }}">
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/select2.css') }}">
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/style.css') }}">
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/moonfonts.css') }}">
|
||||
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery-1.9.1.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery-ui.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery.dataTables.min.js') }}"></script>
|
||||
<script type="text/javascript" src="//cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery.jqplot.min.js') }}"></script>
|
||||
<!--[if lt IE 9]><script type="text/javascript" src="{{ url_for('static', filename='js/excanvas.min.js') }}"></script><![endif]-->
|
||||
<!--[if lt IE 9]>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/excanvas.min.js') }}"></script><![endif]-->
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.json2.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.pieRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.barRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.bubbleRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.categoryAxisRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript"
|
||||
src="{{ url_for('static', filename='js/jqplot.categoryAxisRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.dateAxisRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.canvasTextRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.canvasAxisLabelRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.canvasAxisTickRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript"
|
||||
src="{{ url_for('static', filename='js/jqplot.canvasTextRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript"
|
||||
src="{{ url_for('static', filename='js/jqplot.canvasAxisLabelRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript"
|
||||
src="{{ url_for('static', filename='js/jqplot.canvasAxisTickRenderer.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.cursor.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jqplot.highlighter.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/select2.min.js') }}"></script>
|
||||
@ -61,6 +82,19 @@
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery.gravatar.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/js-yaml.min.js') }}"></script>
|
||||
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-8933515-9"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-8933515-9');
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
|
||||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.8/c3.min.js"></script>
|
||||
|
||||
{% if active_tab == 'driverlog' %}
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/driverlog-ui.js') }}"></script>
|
||||
{% else %}
|
||||
@ -73,10 +107,8 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="content">
|
||||
|
||||
{% block body %}{% endblock %}
|
||||
|
||||
</div>
|
||||
<div id="content">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
226
stackalytics/dashboard/templates/cncf.html
Normal file
@ -0,0 +1,226 @@
|
||||
{% extends "cncf_layout.html" %}
|
||||
{% import '_macros/activity_log.html' as activity_log %}
|
||||
{% import '_macros/contribution_summary.html' as contribution_summary %}
|
||||
{% import '_macros/user_profile.html' as user_profile %}
|
||||
{% import '_macros/module_details.html' as module_details %}
|
||||
|
||||
{% set show_company_breakdown = (not company) and (not user_id) %}
|
||||
{% set show_engineer_breakdown = (not user_id) %}
|
||||
{% set show_bp_breakdown = (metric in ['bpd', 'bpc']) %}
|
||||
{% set show_module_breakdown = (not module) %}
|
||||
{% set show_languages_breakdown = (metric in ['translations']) %}
|
||||
{% set show_user_activity = (user_id) %}
|
||||
{% set show_module_activity = (module) and (not user_id) %}
|
||||
{% set show_activity = (show_user_activity) or (show_module_activity) %}
|
||||
{% set show_contribution_on_left = (not user_id) and (module) %}
|
||||
{% set show_contribution_on_right = (user_id) or (company and not module) %}
|
||||
{% set show_user_profile = (user_id) %}
|
||||
{% set show_module_details = (module) %}
|
||||
{% set show_review_ratio = (metric in ['marks']) %}
|
||||
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
|
||||
{% if show_module_details %}
|
||||
//renderTimeline();
|
||||
{% endif %}
|
||||
|
||||
{% if show_company_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/companies", "company_container", "company_table", "company_chart", "company");
|
||||
{% endif %}
|
||||
{% if show_engineer_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/engineers", "engineer_container", "engineer_table", "engineer_chart", "user_id");
|
||||
{% endif %}
|
||||
{% if show_bp_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/bp", "bp_container", "bp_table", "bp_chart", "name",
|
||||
["index", "link", "status", "date", "metric"]);
|
||||
{% endif %}
|
||||
{% if show_module_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/modules", "module_container", "module_table", "module_chart", "module");
|
||||
{% endif %}
|
||||
{% if show_languages_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/languages", "language_container", "language_table", "language_chart", "language");
|
||||
{% endif %}
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block left_frame %}
|
||||
|
||||
{% if show_module_details %}
|
||||
{{ module_details.show_module_details(module=module) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_user_profile %}
|
||||
{{ user_profile.show_user_profile(user_id=user_id) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_company_breakdown %}
|
||||
|
||||
<div id="company_container">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<h2>Commits by Company {% if user_id %} <span style="color: #15c3de;">|</span> {{ user_inst.user_name }}{% endif %}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 order-xl-last">
|
||||
<div id="company_chart"></div>
|
||||
</div>
|
||||
<div class="col-xl-6 order-xl-first">
|
||||
|
||||
<table id="company_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Company</th>
|
||||
<th>Commits</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if show_module_breakdown %}
|
||||
<div id="module_container">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<h2>Commits by Project {% if company %} <span style="color: #15c3de;">|</span> {{ company_original }}{% endif %} {% if user_id %} <span style="color: #15c3de;">|</span> {{ user_inst.user_name }}{% endif %}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-6 order-xl-last">
|
||||
<div id="module_chart"></div>
|
||||
</div>
|
||||
<div class="col-xl-6 order-xl-first">
|
||||
|
||||
<table id="module_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Project</th>
|
||||
<th>Commits</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_engineer_breakdown %}
|
||||
<div id="engineer_container">
|
||||
|
||||
<h2>Commits by Contributor {% if company %} <span style="color: #15c3de;">|</span> {{ company_original }}{% endif %} {% if user_id %} <span style="color: #15c3de;">|</span> {{ user_inst.user_name }}{% endif %}</h2>
|
||||
|
||||
<table id="engineer_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Contributor</th>
|
||||
<th>Commits</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if show_contribution_on_left %}
|
||||
{{ contribution_summary.show_contribution_summary(show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_contribution_on_right %}
|
||||
{{ contribution_summary.show_contribution_summary(show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_user_activity %}
|
||||
{{ activity_log.show_activity_log(gravatar_size=32, show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_module_activity %}
|
||||
{{ activity_log.show_activity_log(gravatar_size=32, show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_contribution_on_left %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if show_contribution_on_right %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if show_bp_breakdown %}
|
||||
<div id="bp_container">
|
||||
<h2>Blueprint popularity</h2>
|
||||
|
||||
<div style="font-style: italic;">
|
||||
This metric shows how many times a blueprint was mentioned in emails and commit messages.
|
||||
</div>
|
||||
|
||||
<div id="bp_chart" style="width: 300px;height:285px;" width="300" height="285"></div>
|
||||
|
||||
<table id="bp_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Blueprint</th>
|
||||
<th>Status</th>
|
||||
<th>Date</th>
|
||||
<th>Mentions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_languages_breakdown %}
|
||||
<div id="language_container">
|
||||
<h2>Languages</h2>
|
||||
|
||||
<div id="language_chart" style="width: 300px;height:285px;" width="300" height="285"></div>
|
||||
|
||||
<table id="language_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Language</th>
|
||||
<th>Translations</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block center_frame %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block right_frame %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
172
stackalytics/dashboard/templates/cncf_layout.html
Normal file
@ -0,0 +1,172 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block head %}
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
initSelectors("");
|
||||
$(".select2-selection__arrow")
|
||||
.addClass("material-icons")
|
||||
.html("arrow_drop_down");
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$(document).tooltip();
|
||||
});
|
||||
</script>
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="page">
|
||||
{% if not runtime_storage_update_time %}
|
||||
<div class="banner">The data is being loaded now and is not complete</div>
|
||||
{% set update_time_title = '' %}
|
||||
{% else %}
|
||||
{% if runtime_storage_update_time is too_old %}
|
||||
<div class="banner">The data was last updated on {{ runtime_storage_update_time_str }}</div>
|
||||
{% endif %}
|
||||
{% set update_time_title = 'Last updated on ' + runtime_storage_update_time_str %}
|
||||
{% endif %}
|
||||
<div class="container">
|
||||
<div class="aheader">
|
||||
|
||||
<div id="analytics_header">
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<div id="logo" class="text-center">
|
||||
<a href="{{ url_for('overview') }}">
|
||||
<img
|
||||
src="{{ url_for('static', filename='images/stackalytics_logo.png') }}"
|
||||
class="img-fluid" alt="Stackalytics">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<div class="stackamenu text-center">
|
||||
<ul id="menu-stackamenu" class="list-inline">
|
||||
<li class="list-inline-item"><a href="/"><span class="menu-item">OpenStack Foundation</span></a></li>
|
||||
<li class="list-inline-item current-menu-item"><a href="/cncf"><span class="menu-item">CNCF</span></a></li>
|
||||
<li class="list-inline-item"><a href="/unaffiliated"><span class="menu-item">Other Projects</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-1">
|
||||
<a class="about" href="https://wiki.openstack.org/wiki/Stackalytics" target="_blank"
|
||||
title="{{ update_time_title }}">
|
||||
About
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="drops">
|
||||
<div class="row">
|
||||
<div class="col-md" style="display:none;">
|
||||
<label for="release_selector" title="Official releases of OpenStack">Release</label>
|
||||
<input type="hidden" id="release_selector" style="width: 100%"
|
||||
data-placeholder="Select release"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="date_selector" title="Official releases of OpenStack">Date</label>
|
||||
<input type="hidden" id="date_selector" style="width: 100%"
|
||||
data-placeholder="Select date"/>
|
||||
</div>
|
||||
<div class="col-md" style="display:none;">
|
||||
<label for="project_type_selector" title="Project type groups modules of the same kind. 'OpenStack' are projects defined in the official governance projects.yaml.
|
||||
'OpenStack Others' are projects not included into any program. 'Complementary' are projects related to OpenStack ecosystem">Project
|
||||
Type</label>
|
||||
<input type="hidden" id="project_type_selector" style="width: 100%"
|
||||
data-placeholder="Select project type"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="module_selector"
|
||||
title="CNCF Projects">Project</label>
|
||||
<input type="hidden" id="module_selector" style="width: 100%"
|
||||
data-placeholder="Any project"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="company_selector" title="Company name">Company</label>
|
||||
<input type="hidden" id="company_selector" style="width: 100%"
|
||||
data-placeholder="Any company"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="user_id_selector"
|
||||
title="Name of contributor as configured in Launchpad or default_data.json">Contributor</label>
|
||||
<input type="hidden" id="user_id_selector" style="width: 100%"
|
||||
data-placeholder="Any contributor"/>
|
||||
</div>
|
||||
<div class="col-md" style="display: none;">
|
||||
<label for="metric_selector" title="One of available metrics">Metric</label>
|
||||
<input type="hidden" id="metric_selector" style="width: 100%"
|
||||
data-placeholder="Select metric"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% if show_module_details %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
{% block left_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% block right_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% block center_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div id="footer_container">
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
Stackalytics displays information collected from open sources, including
|
||||
<a href="https://git.openstack.org/cgit" style="color: grey;">git.openstack.org</a>
|
||||
,
|
||||
<a href="https://review.openstack.org/" style="color: grey;">review.openstack.org</a>
|
||||
,
|
||||
<a href="https://launchpad.net/" style="color: grey;">Launchpad</a>
|
||||
,
|
||||
<a href="https://github.com/" style="color: grey;">GitHub</a>
|
||||
,
|
||||
<a href="https://www.openstack.org/" style="color: grey;">OpenStack.org</a>
|
||||
,
|
||||
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo" style="color: grey;">OpenStack
|
||||
mailing lists
|
||||
</a>
|
||||
.
|
||||
{% if update_time_title %}{{ update_time_title }}{% endif %}
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -5,6 +5,9 @@
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
initSelectors("");
|
||||
$(".select2-selection__arrow")
|
||||
.addClass("material-icons")
|
||||
.html("arrow_drop_down");
|
||||
});
|
||||
|
||||
$(function () {
|
||||
@ -18,98 +21,147 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="page">
|
||||
{% if not runtime_storage_update_time %}
|
||||
<div class="banner">The data is being loaded now and is not complete</div>
|
||||
{% set update_time_title = '' %}
|
||||
{% else %}
|
||||
{% if runtime_storage_update_time is too_old %}
|
||||
<div class="banner">The data was last updated on {{ runtime_storage_update_time_str }}</div>
|
||||
{% endif %}
|
||||
{% set update_time_title = 'Last updated on ' + runtime_storage_update_time_str %}
|
||||
{% endif %}
|
||||
<div class="aheader">
|
||||
<div style="float: right; margin-top: 10px; margin-right: 20px;">
|
||||
<a href="https://wiki.openstack.org/wiki/Stackalytics" target="_blank" title="{{ update_time_title }}">About</a>
|
||||
</div>
|
||||
<div id="analytics_header">
|
||||
<div style="float: left;">
|
||||
<span id="logo"><a href="{{ url_for('overview') }}"><img src="{{ url_for('static', filename='images/stackalytics_logo.png') }}" alt="Stackalytics" style="width: 100%; max-width: 190px;"></a></span>
|
||||
</div>
|
||||
<div class="stackamenu" style="margin-left: 240px">
|
||||
<ul id="menu-stackamenu">
|
||||
<li class="menu-item current-menu-item"><a href="/"><span class="icon-pie"></span>Code Contribution</a></li>
|
||||
<li class="menu-item"><a href="/report/driverlog"><span class="icon-cogs"></span>Vendor Drivers <span style="vertical-align: top; font-size: 60%;">β</span></a></li>
|
||||
<li class="menu-item"><a href="/report/members"><span class="icon-users"></span>Member Directory</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page">
|
||||
{% if not runtime_storage_update_time %}
|
||||
<div class="banner">The data is being loaded now and is not complete</div>
|
||||
{% set update_time_title = '' %}
|
||||
{% else %}
|
||||
{% if runtime_storage_update_time is too_old %}
|
||||
<div class="banner">The data was last updated on {{ runtime_storage_update_time_str }}</div>
|
||||
{% endif %}
|
||||
{% set update_time_title = 'Last updated on ' + runtime_storage_update_time_str %}
|
||||
{% endif %}
|
||||
<div class="container">
|
||||
<div class="aheader">
|
||||
|
||||
<div class="drops">
|
||||
|
||||
<div class="drop">
|
||||
<label for="release_selector" title="Official releases of OpenStack">Release</label>
|
||||
<input type="hidden" id="release_selector" style="width: 140px" data-placeholder="Select release"/>
|
||||
</div>
|
||||
|
||||
<div class="drop">
|
||||
<label for="project_type_selector" title="Project type groups modules of the same kind. 'OpenStack' are projects defined in the official governance projects.yaml.
|
||||
'OpenStack Others' are projects not included into any program. 'Complementary' are projects related to OpenStack ecosystem">Project Type</label>
|
||||
<input type="hidden" id="project_type_selector" style="width: 140px" data-placeholder="Select project type"/>
|
||||
</div>
|
||||
|
||||
<div class="drop">
|
||||
<label for="module_selector" title="Module represents a repo (black), official project (violet) or pre-configured group of modules (cyan)">Module</label>
|
||||
<input type="hidden" id="module_selector" style="width: 140px" data-placeholder="Any module"/>
|
||||
</div>
|
||||
|
||||
<div class="drop">
|
||||
<label for="company_selector" title="Company name">Company</label>
|
||||
<input type="hidden" id="company_selector" style="width: 140px" data-placeholder="Any company"/>
|
||||
</div>
|
||||
|
||||
<div class="drop">
|
||||
<label for="user_id_selector" title="Name of contributor as configured in Launchpad or default_data.json">Contributor</label>
|
||||
<input type="hidden" id="user_id_selector" style="width: 140px" data-placeholder="Any contributor"/>
|
||||
</div>
|
||||
|
||||
<div class="drop">
|
||||
<label for="metric_selector" title="One of available metrics">Metric</label>
|
||||
<input type="hidden" id="metric_selector" style="width: 140px" data-placeholder="Select metric"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="navigation">
|
||||
<div id="timeline" style="width: 100%; height: 120px; margin-top: 15px;"></div>
|
||||
</div>
|
||||
|
||||
<table style="width: 100%" cellspacing="0">
|
||||
<tr>
|
||||
<td style="width: 50%; vertical-align: top;">
|
||||
<div class="body" style="margin-right: 1em;">
|
||||
{% block left_frame %}{% endblock %}
|
||||
<div id="analytics_header">
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<div id="logo" class="text-center">
|
||||
<a href="{{ url_for('overview') }}">
|
||||
<img
|
||||
src="{{ url_for('static', filename='images/stackalytics_logo.png') }}"
|
||||
class="img-fluid" alt="Stackalytics">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<div class="stackamenu text-center">
|
||||
<ul id="menu-stackamenu" class="list-inline">
|
||||
<li class="list-inline-item current-menu-item"><a href="/"><span class="menu-item">OpenStack Foundation</span></a></li>
|
||||
<li class="list-inline-item"><a href="/cncf"><span class="menu-item">CNCF</span></a></li>
|
||||
<li class="list-inline-item"><a href="/unaffiliated"><span class="menu-item">Other Projects</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-1">
|
||||
<a class="about" href="https://wiki.openstack.org/wiki/Stackalytics" target="_blank"
|
||||
title="{{ update_time_title }}">
|
||||
About
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width: 50%; vertical-align: top;">
|
||||
<div class="body" style="margin-left: 1em;">
|
||||
{% block right_frame %}{% endblock %}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div style="font-size: 10px; color: grey;">
|
||||
Stackalytics displays information collected from open sources, including
|
||||
<a href="https://git.openstack.org/cgit" style="color: grey;">git.openstack.org</a>,
|
||||
<a href="https://review.openstack.org/" style="color: grey;">review.openstack.org</a>,
|
||||
<a href="https://launchpad.net/" style="color: grey;">Launchpad</a>,
|
||||
<a href="https://github.com/" style="color: grey;">GitHub</a>,
|
||||
<a href="https://www.openstack.org/" style="color: grey;">OpenStack.org</a>,
|
||||
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo" style="color: grey;">OpenStack mailing lists</a>.
|
||||
{% if update_time_title %}{{ update_time_title }}{% endif %}
|
||||
<div class="drops">
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<label for="release_selector" title="Official releases of OpenStack">Release</label>
|
||||
<input type="hidden" id="release_selector" style="width: 100%"
|
||||
data-placeholder="Select release"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="project_type_selector" title="Project type groups modules of the same kind. 'OpenStack' are projects defined in the official governance projects.yaml.
|
||||
'OpenStack Others' are projects not included into any program. 'Complementary' are projects related to OpenStack ecosystem">Project
|
||||
Type</label>
|
||||
<input type="hidden" id="project_type_selector" style="width: 100%"
|
||||
data-placeholder="Select project type"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="module_selector"
|
||||
title="Module represents a repo (black), official project (violet) or pre-configured group of modules (cyan)">Module</label>
|
||||
<input type="hidden" id="module_selector" style="width: 100%"
|
||||
data-placeholder="Any module"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="company_selector" title="Company name">Company</label>
|
||||
<input type="hidden" id="company_selector" style="width: 100%"
|
||||
data-placeholder="Any company"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="user_id_selector"
|
||||
title="Name of contributor as configured in Launchpad or default_data.json">Contributor</label>
|
||||
<input type="hidden" id="user_id_selector" style="width: 100%"
|
||||
data-placeholder="Any contributor"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="metric_selector" title="One of available metrics">Metric</label>
|
||||
<input type="hidden" id="metric_selector" style="width: 100%"
|
||||
data-placeholder="Select metric"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% if show_module_details %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
{% block left_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% block right_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% block center_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div id="footer_container">
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
Stackalytics displays information collected from open sources, including
|
||||
<a href="https://git.openstack.org/cgit" style="color: grey;">git.openstack.org</a>
|
||||
,
|
||||
<a href="https://review.openstack.org/" style="color: grey;">review.openstack.org</a>
|
||||
,
|
||||
<a href="https://launchpad.net/" style="color: grey;">Launchpad</a>
|
||||
,
|
||||
<a href="https://github.com/" style="color: grey;">GitHub</a>
|
||||
,
|
||||
<a href="https://www.openstack.org/" style="color: grey;">OpenStack.org</a>
|
||||
,
|
||||
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo" style="color: grey;">OpenStack
|
||||
mailing lists
|
||||
</a>
|
||||
.
|
||||
{% if update_time_title %}{{ update_time_title }}{% endif %}
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -36,7 +36,9 @@
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
|
||||
renderTimeline();
|
||||
{% if show_module_details %}
|
||||
//renderTimeline();
|
||||
{% endif %}
|
||||
|
||||
{% if show_company_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/companies", "company_container", "company_table", "company_chart", "company");
|
||||
@ -44,7 +46,7 @@
|
||||
{% if show_engineer_breakdown %}
|
||||
{% if show_review_ratio %}
|
||||
renderTableAndChart("/api/1.0/stats/engineers", "engineer_container", "engineer_table", "engineer_chart", "user_id",
|
||||
["index", "link", "mark_ratio", "metric"]);
|
||||
["index", "link", "-2", "-1", "1", "2", "A", "x", "positive_ratio", "metric"]);
|
||||
{% else %}
|
||||
renderTableAndChart("/api/1.0/stats/engineers", "engineer_container", "engineer_table", "engineer_chart", "user_id");
|
||||
{% endif %}
|
||||
@ -66,49 +68,99 @@
|
||||
|
||||
{% block left_frame %}
|
||||
|
||||
{% if show_module_details %}
|
||||
{{ module_details.show_module_details(module=module) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_company_breakdown %}
|
||||
|
||||
<div id="company_container">
|
||||
<h2>Contribution by companies</h2>
|
||||
|
||||
<div id="company_chart" style="width: 100%; height: 350px; margin-bottom: 1em;"></div>
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<h2>{{ metric_label }} by Company</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<table id="company_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Company</th>
|
||||
<th>{{ metric_label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
<div class="col-xl-6 order-xl-last">
|
||||
<div id="company_chart"></div>
|
||||
</div>
|
||||
<div class="col-xl-6 order-xl-first">
|
||||
|
||||
<table id="company_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Company</th>
|
||||
<th>{{ metric_label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if show_module_breakdown %}
|
||||
<div id="module_container">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<h2>{{ metric_label }} by Module</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xl-6 order-xl-last">
|
||||
<div id="module_chart"></div>
|
||||
</div>
|
||||
<div class="col-xl-6 order-xl-first">
|
||||
|
||||
<table id="module_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Module</th>
|
||||
<th>{{ metric_label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_engineer_breakdown %}
|
||||
<div id="engineer_container">
|
||||
<h2>Contribution by contributors</h2>
|
||||
<div id="engineer_container">
|
||||
<h2>{{ metric_label }} by Contributor</h2>
|
||||
<table id="engineer_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Contributor</th>
|
||||
{% if show_review_ratio %}
|
||||
<th>-2</th>
|
||||
<th>-1</th>
|
||||
<th>+1</th>
|
||||
<th>+2</th>
|
||||
<th>A</th>
|
||||
<th>x</th>
|
||||
<th>+ ratio</th>
|
||||
{% endif %}
|
||||
<th>{{ metric_label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="engineer_chart" style="width: 100%; height: 350px; margin-bottom: 1em;"></div>
|
||||
|
||||
<table id="engineer_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Contributor</th>
|
||||
{% if show_review_ratio %}
|
||||
<th>-2|-1|+1|+2|A|x (+ ratio)</th>
|
||||
{% endif %}
|
||||
<th>{{ metric_label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_user_profile %}
|
||||
@ -123,102 +175,73 @@
|
||||
{{ show_report_links(module, company, user_id) }}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
{% if show_bp_breakdown %}
|
||||
<div id="bp_container">
|
||||
<h2>Blueprint popularity</h2>
|
||||
|
||||
{% block right_frame %}
|
||||
<div style="font-style: italic;">
|
||||
This metric shows how many times a blueprint was mentioned in emails and commit messages.
|
||||
</div>
|
||||
|
||||
<div id="bp_chart" style="width: 300px;height:285px;" width="300" height="285"></div>
|
||||
|
||||
<table id="bp_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Blueprint</th>
|
||||
<th>Status</th>
|
||||
<th>Date</th>
|
||||
<th>Mentions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_languages_breakdown %}
|
||||
<div id="language_container">
|
||||
{% if language %}
|
||||
<div class="drop" style="margin-top: 16px;">
|
||||
<label for="language_selector" title="One of available languages">Language</label>
|
||||
<input type="hidden" id="language_selector" style="width: 200px" data-placeholder="Select language"/>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
initSingleSelector("language", makeURI("/api/1.0/languages"), {allowClear: true});
|
||||
});
|
||||
</script>
|
||||
{% else %}
|
||||
<h2>Languages</h2>
|
||||
<h2>Languages</h2>
|
||||
|
||||
<div id="language_chart" style="width: 100%; height: 350px; margin-bottom: 1em;"></div>
|
||||
<div id="language_chart" style="width: 300px;height:285px;" width="300" height="285"></div>
|
||||
|
||||
<table id="language_table" class="display">
|
||||
<thead>
|
||||
<table id="language_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Language</th>
|
||||
<th>Translations</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_module_breakdown %}
|
||||
<div id="module_container">
|
||||
<h2>Contribution by modules</h2>
|
||||
|
||||
<div id="module_chart" style="width: 100%; height: 350px; margin-bottom: 1em;"></div>
|
||||
|
||||
<table id="module_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Module</th>
|
||||
<th>{{ metric_label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_module_details %}
|
||||
{{ module_details.show_module_details(module=module) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_bp_breakdown %}
|
||||
<div id="bp_container">
|
||||
<h2>Blueprint popularity</h2>
|
||||
|
||||
<div style="font-style: italic;">
|
||||
This metric shows how many times a blueprint was mentioned in emails and commit messages.
|
||||
</div>
|
||||
|
||||
<div id="bp_chart" style="width: 100%; height: 350px; margin-bottom: 1em;"></div>
|
||||
|
||||
<table id="bp_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Blueprint</th>
|
||||
<th>Status</th>
|
||||
<th>Date</th>
|
||||
<th>Mentions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_contribution_on_right %}
|
||||
{{ contribution_summary.show_contribution_summary(show_all=False) }}
|
||||
{{ show_report_links(module, company, user_id) }}
|
||||
{{ contribution_summary.show_contribution_summary(show_all=False) }}
|
||||
{{ show_report_links(module, company, user_id) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_module_activity %}
|
||||
{{ activity_log.show_activity_log(gravatar_size=32, show_all=False) }}
|
||||
{{ activity_log.show_activity_log(gravatar_size=32, show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block center_frame %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block right_frame %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
@ -3,7 +3,7 @@
|
||||
{% set page_title = 'Company Affiliation Changes' %}
|
||||
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
<script type="text/javascript">
|
||||
|
||||
function show_users_table(options) {
|
||||
var table_column_names = ["from", "to", "count", "users"];
|
||||
@ -63,7 +63,7 @@
|
||||
if (table_id) {
|
||||
$("#" + table_id).dataTable({
|
||||
"aaSorting": [
|
||||
[ sort_by_column, "desc" ]
|
||||
[sort_by_column, "desc"]
|
||||
],
|
||||
"bFilter": true,
|
||||
"bInfo": true,
|
||||
@ -90,7 +90,7 @@
|
||||
}
|
||||
|
||||
function reload() {
|
||||
window.location.search = $.map(make_options(),function (val, index) {
|
||||
window.location.search = $.map(make_options(), function (val, index) {
|
||||
return index + "=" + val;
|
||||
}).join("&")
|
||||
}
|
||||
@ -111,16 +111,16 @@
|
||||
show_page();
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$( "#start_days_selector" ).datepicker({
|
||||
$(function () {
|
||||
$("#start_days_selector").datepicker({
|
||||
dateFormat: 'yy-M-d',
|
||||
changeMonth: true,
|
||||
changeYear: true
|
||||
});
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$( "#end_days_selector" ).datepicker({
|
||||
$(function () {
|
||||
$("#end_days_selector").datepicker({
|
||||
dateFormat: 'yy-M-d',
|
||||
changeMonth: true,
|
||||
changeYear: true
|
||||
@ -133,28 +133,29 @@
|
||||
show_page();
|
||||
});
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Company Affiliation Changes</h1>
|
||||
|
||||
<div id="affiliation_container">
|
||||
<h1>Company Affiliation Changes</h1>
|
||||
|
||||
<p>Start of the period: <input type="text" id="start_days_selector"/> End of the period: <input type="text" id="end_days_selector"/></p>
|
||||
|
||||
<div class="body" style="margin-right: 1em;">
|
||||
<table id="users_table" style="width: 100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th>Count</th>
|
||||
<th>Users</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<table id="users_table" style="width: 100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th>Count</th>
|
||||
<th>Users</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -7,9 +7,9 @@
|
||||
{% block body %}
|
||||
|
||||
<div style="margin: 2em;">
|
||||
<div id="analytics_header" style="padding-bottom: 1em; border-bottom: 1px solid darkgrey;">
|
||||
<div id="analytics_header" style="padding-bottom: 1em;">
|
||||
<span id="logo"><a href="{{ url_for('overview') }}"><img src="{{ url_for('static', filename='images/stackalytics_logo.png') }}" alt="Stackalytics" style="width: 100%; max-width: 190px;"></a></span>
|
||||
<span id="slogan" style="position: relative; top: -15px;">| community heartbeat</span>
|
||||
<span id="slogan">| community heartbeat</span>
|
||||
</div>
|
||||
|
||||
{% block content %}
|
||||
|
@ -20,40 +20,52 @@
|
||||
<div class="page">
|
||||
<div class="banner">Information on drivers is in beta and may contain some inaccuracies. If you see an error, <br/> please help us make the service better by
|
||||
<a href="https://wiki.openstack.org/wiki/DriverLog#How_To:_Add_a_new_driver_to_DriverLog" target="_blank">filing a bug or an update request</a></div>
|
||||
<div class="aheader">
|
||||
<div style="float: right; margin-top: 10px; margin-right: 20px;">
|
||||
<a href="https://wiki.openstack.org/wiki/DriverLog#How_To:_Add_a_new_driver_to_DriverLog" target="_blank">Add / Edit Driver</a>
|
||||
</div>
|
||||
<div id="analytics_header">
|
||||
<div style="float: left;">
|
||||
<span id="logo"><a href="{{ url_for('overview') }}"><img src="{{ url_for('static', filename='images/stackalytics_logo.png') }}" alt="Stackalytics" style="width: 100%; max-width: 190px;"></a></span>
|
||||
<div class="container">
|
||||
<div class="aheader">
|
||||
<div id="analytics_header">
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<div id="logo" class="text-center">
|
||||
<a href="{{ url_for('overview') }}">
|
||||
<img
|
||||
src="{{ url_for('static', filename='images/stackalytics_logo.png') }}"
|
||||
class="img-fluid" alt="Stackalytics">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stackamenu" style="margin-left: 240px">
|
||||
<ul id="menu-stackamenu">
|
||||
<li class="menu-item"><a href="/"><span class="icon-pie"></span>Code Contribution</a></li>
|
||||
<li class="menu-item current-menu-item"><a href="/report/driverlog"><span class="icon-cogs"></span>Vendor Drivers <span style="vertical-align: top; font-size: 60%;">β</span></a></li>
|
||||
<li class="menu-item"><a href="/report/members"><span class="icon-users"></span>Member Directory</a></li>
|
||||
</ul>
|
||||
<div class="col-lg-8">
|
||||
<div class="stackamenu text-center">
|
||||
<ul id="menu-stackamenu" class="list-inline">
|
||||
<li class="list-inline-item current-menu-item"><a href="/"><span class="menu-item">OpenStack Foundation</span></a></li>
|
||||
<li class="list-inline-item"><a href="/?project_type=cncf-group&release=all&metric=commits"><span class="menu-item">CNCF</span></a></li>
|
||||
<li class="list-inline-item"><a href="/unaffiliated"><span class="menu-item">Unaffiliated Projects</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-1">
|
||||
<a class="about" href="https://wiki.openstack.org/wiki/DriverLog#How_To:_Add_a_new_driver_to_DriverLog" target="_blank" title="{{ update_time_title }}">
|
||||
Add / Edit Driver
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drops">
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<label for="project_id" title="OpenStack Project">Project</label>
|
||||
<input type="hidden" id="project_id" style="width:240px" data-placeholder="Any project"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="vendor" title="Vendor">Vendor</label>
|
||||
<input type="hidden" id="vendor" style="width:240px" data-placeholder="Any vendor"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="release" title="OpenStack Release">Release</label>
|
||||
<input type="hidden" id="release" style="width:240px" data-placeholder="Any release"/>
|
||||
</div>
|
||||
|
||||
<div class="drops">
|
||||
</div>
|
||||
|
||||
<div class="drop">
|
||||
<label for="project_id" title="OpenStack Project">Project</label>
|
||||
<input type="hidden" id="project_id" style="width:240px" data-placeholder="Any project"/>
|
||||
</div>
|
||||
|
||||
<div class="drop">
|
||||
<label for="vendor" title="Vendor">Vendor</label>
|
||||
<input type="hidden" id="vendor" style="width:240px" data-placeholder="Any vendor"/>
|
||||
</div>
|
||||
|
||||
<div class="drop">
|
||||
<label for="release" title="OpenStack Release">Release</label>
|
||||
<input type="hidden" id="release" style="width:240px" data-placeholder="Any release"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 2em;">
|
||||
@ -145,5 +157,6 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -4,7 +4,7 @@
|
||||
{% set page_title = 'OpenStack Foundation members' %}
|
||||
|
||||
{% block head %}
|
||||
<script type="text/javascript">
|
||||
<script type="text/javascript">
|
||||
|
||||
function get_start_date() {
|
||||
var days = {{ days }};
|
||||
@ -39,7 +39,7 @@
|
||||
if (table_id) {
|
||||
$("#" + table_id).dataTable({
|
||||
"aaSorting": [
|
||||
[ sort_by_column, "desc" ]
|
||||
[sort_by_column, "desc"]
|
||||
],
|
||||
"bFilter": true,
|
||||
"bInfo": true,
|
||||
@ -74,7 +74,7 @@
|
||||
}
|
||||
|
||||
for (i = 0; i < tableData.length; i++) {
|
||||
var company_link = makeURI('/report/members', {company:tableData[i].name});
|
||||
var company_link = makeURI('/report/members', {company: tableData[i].name});
|
||||
tableData[i].link = "<a href=\"" + company_link + "\">" + tableData[i].name + "</a>";
|
||||
tableData[i].date = tableData[i].date_str;
|
||||
}
|
||||
@ -82,7 +82,7 @@
|
||||
if (table_id) {
|
||||
$("#" + table_id).dataTable({
|
||||
"aaSorting": [
|
||||
[ sort_by_column, "desc" ]
|
||||
[sort_by_column, "desc"]
|
||||
],
|
||||
"bFilter": true,
|
||||
"bInfo": true,
|
||||
@ -117,7 +117,7 @@
|
||||
}
|
||||
|
||||
for (i = 0; i < tableData.length; i++) {
|
||||
var company_link = makeURI('/report/members', {company:tableData[i].name});
|
||||
var company_link = makeURI('/report/members', {company: tableData[i].name});
|
||||
tableData[i].link = "<a href=\"" + company_link + "\">" + tableData[i].name + "</a>";
|
||||
tableData[i].count = tableData[i].metric;
|
||||
}
|
||||
@ -125,7 +125,7 @@
|
||||
if (table_id) {
|
||||
$("#" + table_id).dataTable({
|
||||
"aaSorting": [
|
||||
[ sort_by_column, "desc" ]
|
||||
[sort_by_column, "desc"]
|
||||
],
|
||||
"bFilter": true,
|
||||
"bInfo": true,
|
||||
@ -182,7 +182,7 @@
|
||||
showDataLabels: true
|
||||
}
|
||||
},
|
||||
legend: { show: true, location: 'e' }
|
||||
legend: {show: true, location: 'e'}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -211,7 +211,7 @@
|
||||
function show_page() {
|
||||
|
||||
var start_date = get_start_date();
|
||||
var base_options = { metric: 'members', project_type: 'all', release: 'all', start_date: start_date };
|
||||
var base_options = { metric: 'members', project_type: 'all', release: 'all', start_date: start_date};
|
||||
renderTimeline(base_options);
|
||||
|
||||
show_engineers_table(base_options);
|
||||
@ -221,16 +221,16 @@
|
||||
show_new_companies_table(base_options);
|
||||
renderChart("/api/1.0/stats/companies", "members_chart", base_options);
|
||||
{% else %}
|
||||
$('#companies_block').hide();
|
||||
$('#new_companies_table_header').hide();
|
||||
$('#new_companies_table').hide();
|
||||
$('#companies_container').hide();
|
||||
$('#new_compaines_container').hide();
|
||||
$('#members_container').hide();
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
var start_date = get_start_date();
|
||||
var base_options = { metric: 'members', project_type: 'all', release: 'all', start_date: start_date };
|
||||
var base_options = {metric: 'members', project_type: 'all', release: 'all', start_date: start_date};
|
||||
|
||||
initSingleSelector("company", makeURI("/api/1.0/companies", base_options), {allowClear: true});
|
||||
|
||||
@ -241,95 +241,116 @@
|
||||
show_page();
|
||||
});
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
table.dataTable tr.even {
|
||||
background-color: #EEF1F4;
|
||||
}
|
||||
<style type="text/css">
|
||||
table.dataTable tr.even {
|
||||
background-color: #EEF1F4;
|
||||
}
|
||||
|
||||
table.dataTable tr.even:hover, table.dataTable tr.odd:hover {
|
||||
background-color: #F8FFEC;
|
||||
}
|
||||
table.dataTable tr.even:hover, table.dataTable tr.odd:hover {
|
||||
background-color: #F8FFEC;
|
||||
}
|
||||
|
||||
table.dataTable tr.even td.sorting_1 {
|
||||
background-color: #E0E8E8;
|
||||
}
|
||||
</style>
|
||||
table.dataTable tr.even td.sorting_1 {
|
||||
background-color: #E0E8E8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type='text/javascript'>
|
||||
$(document).ready(function () {
|
||||
$('#days_selector').val({{ days }});
|
||||
$("#days_selector").select2();
|
||||
show_page();
|
||||
});
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('#days_selector').val( {{days}} );
|
||||
$("#days_selector").select2();
|
||||
show_page();
|
||||
});
|
||||
|
||||
$(document).on('change', '#days_selector', function (evt) {
|
||||
reload();
|
||||
});
|
||||
$(document).on('change', '#days_selector', function (evt) {
|
||||
reload();
|
||||
});
|
||||
|
||||
$(document).on('change', '#company_selector', function (evt) {
|
||||
reload();
|
||||
});
|
||||
</script>
|
||||
$(document).on('change', '#company_selector', function (evt) {
|
||||
reload();
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="page">
|
||||
<div class="aheader">
|
||||
<div style="float: right; margin-top: 10px; margin-right: 20px;">
|
||||
<a href="https://wiki.openstack.org/wiki/Stackalytics" target="_blank">About</a>
|
||||
</div>
|
||||
<div class="aheader">
|
||||
<div id="analytics_header">
|
||||
<div style="float: left;">
|
||||
<span id="logo"><a href="{{ url_for('overview') }}"><img src="{{ url_for('static', filename='images/stackalytics_logo.png') }}" alt="Stackalytics" style="width: 100%; max-width: 190px;"></a></span>
|
||||
</div>
|
||||
<div class="stackamenu" style="margin-left: 240px;">
|
||||
<ul id="menu-stackamenu">
|
||||
<li class="menu-item"><a href="{{ url_for('overview') }}"><span class="icon-pie"></span>Code Contribution</a></li>
|
||||
<li class="menu-item"><a href="/report/driverlog"><span class="icon-cogs"></span>Vendor Drivers <span style="vertical-align: top; font-size: 60%;">β</span></a></li>
|
||||
<li class="menu-item current-menu-item"><a href="/report/members"><span class="icon-users"></span>Member Directory</a></li>
|
||||
</ul>
|
||||
<div class="row">
|
||||
<div class="col-lg-10 offset-lg-1">
|
||||
<div id="logo" class="text-center">
|
||||
<a href="{{ url_for('overview') }}">
|
||||
<img
|
||||
src="{{ url_for('static', filename='images/stackalytics_logo.png') }}"
|
||||
alt="Stackalytics">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="stackamenu text-center">
|
||||
<a class="about" href="https://wiki.openstack.org/wiki/Stackalytics" target="_blank"
|
||||
title="{{ update_time_title }}">
|
||||
About
|
||||
</a>
|
||||
<ul id="menu-stackamenu">
|
||||
<div class="row">
|
||||
<div class="col-md text-center">
|
||||
<span class="menu-item"><a href="/"><span class="icon-pie"></span>Code Contribution</a></span>
|
||||
</div>
|
||||
<div class="col-md text-center">
|
||||
<span class="menu-item"><a href="/report/driverlog"><span class="icon-cogs"></span>Vendor Drivers <span
|
||||
style="vertical-align: top; font-size: 60%;">β</span></a></span>
|
||||
</div>
|
||||
<div class="col-md text-center">
|
||||
<span class="menu-item current-menu-item"><a href="/report/members"><span
|
||||
class="icon-users"></span>Member Directory</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="drops">
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<label for="days_selector">Joined during period</label>
|
||||
<select id="days_selector" name="days_selector"
|
||||
style="width:100%"
|
||||
data-placeholder="Select period">
|
||||
<option value="7">week</option>
|
||||
<option value="14">two weeks</option>
|
||||
<option value="31">month</option>
|
||||
<option value="93">quarter</option>
|
||||
<option value="183">half year</option>
|
||||
<option value="365">year</option>
|
||||
<option value="{{ all_days }}">all</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="company_selector">Company</label>
|
||||
<input id="company_selector" style="width:100%"
|
||||
data-placeholder="Any company"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="navigation hidden-md-down">
|
||||
<div id="timeline" style="width: 100%; height: 120px; margin-top: 15px;"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="navigation">
|
||||
<div id="timeline"
|
||||
style="width: 100%; height: 120px; margin-top: 15px;"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div id="companies_container">
|
||||
<h2>OpenStack foundation member companies</h2>
|
||||
|
||||
<div class="drops">
|
||||
<div class="drop" style="margin-top: 1em;">
|
||||
<label for="days_selector">Joined during period</label>
|
||||
<select id="days_selector" name="days_selector"
|
||||
style="min-width: 140px;"
|
||||
data-placeholder="Select period">
|
||||
<option value="7">week</option>
|
||||
<option value="14">two weeks</option>
|
||||
<option value="31">month</option>
|
||||
<option value="93">quarter</option>
|
||||
<option value="183">half year</option>
|
||||
<option value="365">year</option>
|
||||
<option value="{{ all_days }}">all</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="drop" style="margin-top: 1em;">
|
||||
<label for="company_selector">Company</label>
|
||||
<input id="company_selector" style="width: 140px"
|
||||
data-placeholder="Any company"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<table style="width: 100%" cellspacing="0" id="companies_block">
|
||||
<tr>
|
||||
<td style="width: 50%; vertical-align: top; padding-right: 3em;">
|
||||
<h2>OpenStack foundation member companies</h2>
|
||||
|
||||
<div class="body" style="margin-right: 1em;">
|
||||
<table id="companies_table">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -342,26 +363,20 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width: 50%; vertical-align: top; padding-left: 3em">
|
||||
<h2>Members by company</h2>
|
||||
<div class="body" style="margin-left: 1em;">
|
||||
<div id="members_container">
|
||||
|
||||
<div id="members_chart"
|
||||
style="width: 100%; height: 350px; margin-bottom: 1em;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div id="members_container">
|
||||
<h2>Members by company</h2>
|
||||
<div id="members_chart"
|
||||
style="width: 100%; height: 350px; margin-bottom: 1em;"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table style="width: 100%" cellspacing="0">
|
||||
<tr>
|
||||
<td style="width: 50%; vertical-align: top; padding-right: 3em;">
|
||||
<h2>Individual Members</h2>
|
||||
|
||||
<div class="body" style="margin-right: 1em;">
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div id="individuals_container">
|
||||
<h2>Individual Members</h2>
|
||||
<table id="members_table">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -375,14 +390,10 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
<td style="width: 50%; vertical-align: top; padding-right: 3em;">
|
||||
<div id="new_companies_table_header">
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div id="new_compaines_container">
|
||||
<h2>New Companies</h2>
|
||||
</div>
|
||||
|
||||
<div class="body" style="margin-right: 1em;">
|
||||
|
||||
<table id="new_companies_table">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -395,11 +406,9 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
218
stackalytics/dashboard/templates/unaffiliated.html
Normal file
@ -0,0 +1,218 @@
|
||||
{% extends "unaffiliated_layout.html" %}
|
||||
{% import '_macros/activity_log.html' as activity_log %}
|
||||
{% import '_macros/contribution_summary.html' as contribution_summary %}
|
||||
{% import '_macros/user_profile.html' as user_profile %}
|
||||
{% import '_macros/module_details.html' as module_details %}
|
||||
|
||||
{% set show_company_breakdown = (not company) and (not user_id) %}
|
||||
{% set show_engineer_breakdown = (not user_id) %}
|
||||
{% set show_bp_breakdown = (metric in ['bpd', 'bpc']) %}
|
||||
{% set show_module_breakdown = (not module) %}
|
||||
{% set show_languages_breakdown = (metric in ['translations']) %}
|
||||
{% set show_user_activity = (user_id) %}
|
||||
{% set show_module_activity = (module) and (not user_id) %}
|
||||
{% set show_activity = (show_user_activity) or (show_module_activity) %}
|
||||
{% set show_contribution_on_left = (not user_id) and (module) %}
|
||||
{% set show_contribution_on_right = (user_id) or (company and not module) %}
|
||||
{% set show_user_profile = (user_id) %}
|
||||
{% set show_module_details = (module) %}
|
||||
{% set show_review_ratio = (metric in ['marks']) %}
|
||||
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
|
||||
{% if show_module_details %}
|
||||
// renderTimeline();
|
||||
{% endif %}
|
||||
|
||||
{% if show_company_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/companies", "company_container", "company_table", "company_chart", "company");
|
||||
{% endif %}
|
||||
{% if show_engineer_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/engineers", "engineer_container", "engineer_table", "engineer_chart", "user_id");
|
||||
{% endif %}
|
||||
{% if show_bp_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/bp", "bp_container", "bp_table", "bp_chart", "name",
|
||||
["index", "link", "status", "date", "metric"]);
|
||||
{% endif %}
|
||||
{% if show_module_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/modules", "module_container", "module_table", "module_chart", "module");
|
||||
{% endif %}
|
||||
{% if show_languages_breakdown %}
|
||||
renderTableAndChart("/api/1.0/stats/languages", "language_container", "language_table", "language_chart", "language");
|
||||
{% endif %}
|
||||
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block left_frame %}
|
||||
|
||||
{% if show_module_details %}
|
||||
{{ module_details.show_module_details(module=module) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_company_breakdown %}
|
||||
|
||||
<div id="company_container">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<h2>Commits by Company</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xl-6 order-xl-last">
|
||||
<div id="company_chart"></div>
|
||||
</div>
|
||||
<div class="col-xl-6 order-xl-first">
|
||||
|
||||
<table id="company_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Company</th>
|
||||
<th>Commits</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if show_module_breakdown %}
|
||||
<div id="module_container">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
<h2>Commits by Module</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xl-6 order-xl-last">
|
||||
<div id="module_chart"></div>
|
||||
</div>
|
||||
<div class="col-xl-6 order-xl-first">
|
||||
|
||||
<table id="module_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Module</th>
|
||||
<th>Commits</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_engineer_breakdown %}
|
||||
<div id="engineer_container">
|
||||
|
||||
<h2>Commits by Contributor</h2>
|
||||
|
||||
<table id="engineer_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Contributor</th>
|
||||
<th>Commits</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% if show_user_profile %}
|
||||
{{ user_profile.show_user_profile(user_id=user_id) }}
|
||||
{% endif %}
|
||||
{% if show_user_activity %}
|
||||
{{ activity_log.show_activity_log(gravatar_size=32, show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_contribution_on_left %}
|
||||
{{ contribution_summary.show_contribution_summary(show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_bp_breakdown %}
|
||||
<div id="bp_container">
|
||||
<h2>Blueprint popularity</h2>
|
||||
|
||||
<div style="font-style: italic;">
|
||||
This metric shows how many times a blueprint was mentioned in emails and commit messages.
|
||||
</div>
|
||||
|
||||
<div id="bp_chart" style="width: 300px;height:285px;" width="300" height="285"></div>
|
||||
|
||||
<table id="bp_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Blueprint</th>
|
||||
<th>Status</th>
|
||||
<th>Date</th>
|
||||
<th>Mentions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_languages_breakdown %}
|
||||
<div id="language_container">
|
||||
<h2>Languages</h2>
|
||||
|
||||
<div id="language_chart" style="width: 300px;height:285px;" width="300" height="285"></div>
|
||||
|
||||
<table id="language_table" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Language</th>
|
||||
<th>Translations</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_contribution_on_right %}
|
||||
{{ contribution_summary.show_contribution_summary(show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% if show_module_activity %}
|
||||
{{ activity_log.show_activity_log(gravatar_size=32, show_all=False) }}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block center_frame %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block right_frame %}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{% endblock %}
|
173
stackalytics/dashboard/templates/unaffiliated_layout.html
Normal file
@ -0,0 +1,173 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block head %}
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
initSelectors("");
|
||||
$(".select2-selection__arrow")
|
||||
.addClass("material-icons")
|
||||
.html("arrow_drop_down");
|
||||
});
|
||||
|
||||
$(function () {
|
||||
$(document).tooltip();
|
||||
});
|
||||
</script>
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="page">
|
||||
{% if not runtime_storage_update_time %}
|
||||
<div class="banner">The data is being loaded now and is not complete</div>
|
||||
{% set update_time_title = '' %}
|
||||
{% else %}
|
||||
{% if runtime_storage_update_time is too_old %}
|
||||
<div class="banner">The data was last updated on {{ runtime_storage_update_time_str }}</div>
|
||||
{% endif %}
|
||||
{% set update_time_title = 'Last updated on ' + runtime_storage_update_time_str %}
|
||||
{% endif %}
|
||||
<div class="container">
|
||||
<div class="aheader">
|
||||
|
||||
<div id="analytics_header">
|
||||
<div class="row">
|
||||
<div class="col-lg-3">
|
||||
<div id="logo" class="text-center">
|
||||
<a href="{{ url_for('overview') }}">
|
||||
<img
|
||||
src="{{ url_for('static', filename='images/stackalytics_logo.png') }}"
|
||||
class="img-fluid" alt="Stackalytics">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-8">
|
||||
<div class="stackamenu text-center">
|
||||
<ul id="menu-stackamenu" class="list-inline">
|
||||
<li class="list-inline-item"><a href="/"><span class="menu-item">OpenStack Foundation</span></a></li>
|
||||
<li class="list-inline-item"><a href="/cncf"><span class="menu-item">CNCF</span></a></li>
|
||||
<li class="list-inline-item current-menu-item"><a href="/unaffiliated"><span class="menu-item">Other Projects</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-1">
|
||||
<a class="about" href="https://wiki.openstack.org/wiki/Stackalytics" target="_blank"
|
||||
title="{{ update_time_title }}">
|
||||
About
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="drops">
|
||||
<div class="row">
|
||||
<div class="col-md" style="display: none;">
|
||||
<label for="release_selector" title="Official releases of OpenStack">Release</label>
|
||||
<input type="hidden" id="release_selector" style="width: 100%"
|
||||
data-placeholder="Select release"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="date_selector" title="Official releases of OpenStack">Date</label>
|
||||
<input type="hidden" id="date_selector" style="width: 100%"
|
||||
data-placeholder="Select date"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="project_type_selector" title="Project type groups modules of the same kind. 'OpenStack' are projects defined in the official governance projects.yaml.
|
||||
'OpenStack Others' are projects not included into any program. 'Complementary' are projects related to OpenStack ecosystem">Project
|
||||
Type</label>
|
||||
<input type="hidden" id="project_type_selector" style="width: 100%"
|
||||
data-placeholder="Select project type"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="module_selector"
|
||||
title="Module represents a repo (black), official project (violet) or pre-configured group of modules (cyan)">Module</label>
|
||||
<input type="hidden" id="module_selector" style="width: 100%"
|
||||
data-placeholder="Any module"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="company_selector" title="Company name">Company</label>
|
||||
<input type="hidden" id="company_selector" style="width: 100%"
|
||||
data-placeholder="Any company"/>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<label for="user_id_selector"
|
||||
title="Name of contributor as configured in Launchpad or default_data.json">Contributor</label>
|
||||
<input type="hidden" id="user_id_selector" style="width: 100%"
|
||||
data-placeholder="Any contributor"/>
|
||||
</div>
|
||||
<div class="col-md" style="display: none;">
|
||||
<label for="metric_selector" title="One of available metrics">Metric</label>
|
||||
<input type="hidden" id="metric_selector" style="width: 100%"
|
||||
data-placeholder="Select metric"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% if show_module_details %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xl-12">
|
||||
{% block left_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% block right_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{% block center_frame %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div id="footer_container">
|
||||
<div class="row">
|
||||
<div class="col-lg-9">
|
||||
Stackalytics displays information collected from open sources, including
|
||||
<a href="https://git.openstack.org/cgit" style="color: grey;">git.openstack.org</a>
|
||||
,
|
||||
<a href="https://review.openstack.org/" style="color: grey;">review.openstack.org</a>
|
||||
,
|
||||
<a href="https://launchpad.net/" style="color: grey;">Launchpad</a>
|
||||
,
|
||||
<a href="https://github.com/" style="color: grey;">GitHub</a>
|
||||
,
|
||||
<a href="https://www.openstack.org/" style="color: grey;">OpenStack.org</a>
|
||||
,
|
||||
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo" style="color: grey;">OpenStack
|
||||
mailing lists
|
||||
</a>
|
||||
.
|
||||
{% if update_time_title %}{{ update_time_title }}{% endif %}
|
||||
</div>
|
||||
<div class="col-lg-3">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -55,6 +55,18 @@ def overview():
|
||||
pass
|
||||
|
||||
|
||||
@app.route('/cncf')
|
||||
@decorators.templated()
|
||||
def cncf():
|
||||
pass
|
||||
|
||||
|
||||
@app.route('/unaffiliated')
|
||||
@decorators.templated()
|
||||
def unaffiliated():
|
||||
pass
|
||||
|
||||
|
||||
@app.route('/widget')
|
||||
def widget():
|
||||
return flask.render_template('widget.html')
|
||||
@ -504,7 +516,8 @@ def get_user(user_id):
|
||||
@decorators.jsonify(root=('data', 'default'))
|
||||
def get_releases_json(**kwargs):
|
||||
releases = [{'id': release['release_name'],
|
||||
'text': release['release_name'].capitalize()}
|
||||
'text': release['release_name'].capitalize(),
|
||||
'project': release.get('project')}
|
||||
for release in vault.get_vault()['releases'].values()]
|
||||
releases.append({'id': 'all', 'text': 'All'})
|
||||
releases.reverse()
|
||||
|
@ -25,8 +25,8 @@ CONNECTION_OPTS = [
|
||||
|
||||
PROCESSOR_OPTS = [
|
||||
cfg.StrOpt('default-data-uri',
|
||||
default='https://git.openstack.org/cgit/'
|
||||
'openstack/stackalytics/plain/etc/default_data.json',
|
||||
default='https://raw.githubusercontent.com/stackalytics/'
|
||||
'default_data/master/default_data.json',
|
||||
help='URI for default data. A local file can be used with the '
|
||||
'prefix "file://". For example, '
|
||||
'default_data_uri = file:///path/to/default_data.json'),
|
||||
|
@ -76,6 +76,9 @@ default_data = {
|
||||
"release_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"project": {
|
||||
"type": "string"
|
||||
},
|
||||
"end_date": {
|
||||
"$ref": "#/definitions/date_format"
|
||||
},
|
||||
|
@ -181,6 +181,7 @@ class Git(Vcs):
|
||||
LOG.debug('Parsing git log for repo uri %s', self.repo['uri'])
|
||||
|
||||
os.chdir(self.folder)
|
||||
|
||||
if not self._checkout(branch):
|
||||
return
|
||||
|
||||
@ -281,6 +282,9 @@ class Git(Vcs):
|
||||
def get_last_id(self, branch):
|
||||
LOG.debug('Get head commit for repo uri: %s', self.repo['uri'])
|
||||
|
||||
if not os.path.exists(self.folder):
|
||||
return None
|
||||
|
||||
os.chdir(self.folder)
|
||||
if not self._checkout(branch):
|
||||
return None
|
||||
|
@ -21,9 +21,12 @@ class TestAPIReleases(test_api.TestAPI):
|
||||
def test_releases(self):
|
||||
with test_api.make_runtime_storage(
|
||||
{'releases': [
|
||||
{'release_name': 'prehistory', 'end_date': 1365033600},
|
||||
{'release_name': 'havana', 'end_date': 1381968000},
|
||||
{'release_name': 'icehouse', 'end_date': 1397692800}],
|
||||
{'release_name': 'prehistory', 'end_date': 1365033600,
|
||||
'project': 'nova'},
|
||||
{'release_name': 'havana', 'end_date': 1381968000,
|
||||
'project': 'glance'},
|
||||
{'release_name': 'icehouse', 'end_date': 1397692800,
|
||||
'project': 'nova-cli'}],
|
||||
'project_types': [
|
||||
{'id': 'all', 'title': 'All',
|
||||
'modules': ['nova', 'glance', 'nova-cli']},
|
||||
@ -32,6 +35,9 @@ class TestAPIReleases(test_api.TestAPI):
|
||||
test_api.make_records(record_type=['commit'])):
|
||||
response = self.app.get('/api/1.0/releases')
|
||||
releases = test_api.load_json(response)['data']
|
||||
print(str(releases))
|
||||
self.assertEqual(3, len(releases))
|
||||
self.assertIn({'id': 'all', 'text': 'All'}, releases)
|
||||
self.assertIn({'id': 'icehouse', 'text': 'Icehouse'}, releases)
|
||||
self.assertIn(
|
||||
{'project': 'nova-cli', 'id': 'icehouse',
|
||||
'text': 'Icehouse'}, releases)
|
||||
|
@ -125,7 +125,8 @@ class TestConfigFiles(testtools.TestCase):
|
||||
def _verify_users_in_alphabetical_order(self, file_name):
|
||||
users = self._read_file(file_name)['users']
|
||||
self._verify_ordering(
|
||||
users, key=lambda x: (x.get('launchpad_id') or x.get('github_id')),
|
||||
users,
|
||||
key=lambda x: (x.get('launchpad_id') or x.get('github_id') or ''),
|
||||
msg='List of users should be ordered by launchpad id or ldap id '
|
||||
'or github id')
|
||||
|
||||
|
@ -68,7 +68,7 @@ class TestHelpers(testtools.TestCase):
|
||||
|
||||
observed = helpers.extend_user(user)
|
||||
self.assertEqual(expected, observed)
|
||||
mock_make_link.assert_called_once_with('TheCompany', '/', mock.ANY)
|
||||
mock_make_link.assert_called_once_with('TheCompany', '', mock.ANY)
|
||||
|
||||
@mock.patch('time.time')
|
||||
@mock.patch('stackalytics.dashboard.helpers.make_link')
|
||||
@ -92,4 +92,4 @@ class TestHelpers(testtools.TestCase):
|
||||
|
||||
helpers.extend_user(user)
|
||||
|
||||
mock_make_link.assert_called_once_with('Current', '/', mock.ANY)
|
||||
mock_make_link.assert_called_once_with('Current', '', mock.ANY)
|
||||
|