Implemented base for KPI reports
Added report that checks position in the top Change-Id: Id9e8a81518f71de75937be1d1ab3c2aa4ab37377
This commit is contained in:
parent
d95f2d560a
commit
9a39255091
28
dashboard/kpi.py
Normal file
28
dashboard/kpi.py
Normal file
@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2013 Mirantis Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import flask
|
||||
|
||||
from dashboard import decorators
|
||||
|
||||
|
||||
blueprint = flask.Blueprint('kpi', __name__, url_prefix='/kpi')
|
||||
|
||||
|
||||
@blueprint.route('/group')
|
||||
@decorators.templated()
|
||||
@decorators.exception_handler()
|
||||
def kpi():
|
||||
return
|
@ -336,6 +336,41 @@ a[href^="https://launchpad"]:after {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.kpi_block {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.kpi_title_block {
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.kpi_title {
|
||||
font-size: 16pt;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.kpi_marker {
|
||||
font-size: 19pt;
|
||||
font-weight: bold;
|
||||
text-align: center; vertical-align: middle;
|
||||
background-color: lightgray; color: white;
|
||||
float: left; width: 32px; height: 32px;
|
||||
}
|
||||
|
||||
.kpi_good {
|
||||
background-color: #008000;
|
||||
}
|
||||
|
||||
.kpi_bad {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.kpi_note {
|
||||
font-size: 11pt;
|
||||
color: #606060;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select2-results {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
55
dashboard/templates/kpi/base_kpi.html
Normal file
55
dashboard/templates/kpi/base_kpi.html
Normal file
@ -0,0 +1,55 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block head %}
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
|
||||
<meta name="keywords" content="openstack, contribution, statistics, community, review, commit, report, havana, grizzly, icehouse"/>
|
||||
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/style.css') }}">
|
||||
|
||||
<link href='http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic&subset=latin,cyrillic' rel='stylesheet' type='text/css' />
|
||||
<link href='http://fonts.googleapis.com/css?family=PT+Sans+Caption&subset=latin,cyrillic' rel='stylesheet' type='text/css' />
|
||||
<link href='http://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700&subset=latin,cyrillic' rel='stylesheet' type='text/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/select2.css') }}">
|
||||
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='css/style.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.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]-->
|
||||
<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.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.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>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery.tmpl.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/stackalytics-ui.js') }}"></script>
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div style="margin: 2em;">
|
||||
<div id="analytics_header" style="padding-bottom: 1em; border-bottom: 1px solid darkgrey;">
|
||||
<span id="logo"><a href="/">Stackalytics</a></span>
|
||||
<span id="slogan">| community heartbeat</span>
|
||||
</div>
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
72
dashboard/templates/kpi/kpi.html
Normal file
72
dashboard/templates/kpi/kpi.html
Normal file
@ -0,0 +1,72 @@
|
||||
{% extends "kpi/base_kpi.html" %}
|
||||
|
||||
{% block title %}
|
||||
Group KPI
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
|
||||
function load_position_target_data(id, url, target_id, target_value) {
|
||||
$.ajax({
|
||||
url: make_uri(url),
|
||||
dataType: "jsonp",
|
||||
success: function (data) {
|
||||
data = data["stats"];
|
||||
var position = -1;
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].id == target_id) {
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var isOk = false;
|
||||
var message = "";
|
||||
if (position >= 0) {
|
||||
if (position <= target_value) {
|
||||
isOk = true;
|
||||
message = "Target position is " + target_value;
|
||||
} else {
|
||||
message = "Position " + position + " is worse than target " + target_value;
|
||||
}
|
||||
} else {
|
||||
message = "Target " + target_id + " is not found";
|
||||
}
|
||||
|
||||
$("#position_target_marker_" + id).addClass(isOk? "kpi_good": "kpi_bad").text(i);
|
||||
$("#position_target_note_" + id).show().text(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% macro position_target(record_filter, target_id, target_value, title) -%}
|
||||
|
||||
{% set id=title.replace(' ', '_') %}
|
||||
|
||||
<script type="application/javascript">
|
||||
$(document).ready(function () {
|
||||
load_position_target_data("{{ id }}", "{{ record_filter|make_url('/api/1.0/stats/companies')|safe }}", "{{ target_id }}", "{{ target_value }}");
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="position_target" class="kpi_block">
|
||||
<div id="position_target_marker_{{ id }}" class="kpi_marker"></div>
|
||||
<div class="kpi_title_block">
|
||||
<div class="kpi_title">{{ title }}</div>
|
||||
<div class="kpi_note" id="position_target_note_{{ id }}"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{%- endmacro %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Metrics</h1>
|
||||
|
||||
{{ position_target({'release': 'icehouse', 'project_type': 'openstack', 'metric': 'commits'}, 'Mirantis', 5, 'Position by commits') }}
|
||||
{{ position_target({'release': 'icehouse', 'project_type': 'openstack', 'metric': 'marks'}, 'Mirantis', 5, 'Position by reviews') }}
|
||||
|
||||
{% endblock %}
|
@ -23,6 +23,7 @@ from oslo.config import cfg
|
||||
|
||||
from dashboard import decorators
|
||||
from dashboard import helpers
|
||||
from dashboard import kpi
|
||||
from dashboard import parameters
|
||||
from dashboard import reports
|
||||
from dashboard import vault
|
||||
@ -37,6 +38,7 @@ app = flask.Flask(__name__)
|
||||
app.config.from_object(__name__)
|
||||
app.config.from_envvar('DASHBOARD_CONF', silent=True)
|
||||
app.register_blueprint(reports.blueprint)
|
||||
app.register_blueprint(kpi.blueprint)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -434,6 +436,12 @@ def timeline(records, **kwargs):
|
||||
gravatar = gravatar_ext.Gravatar(app, size=64, rating='g', default='wavatar')
|
||||
|
||||
|
||||
@app.template_filter('make_url')
|
||||
def to_url_params(dict_params, base_url):
|
||||
return base_url + '?' + '&'.join(
|
||||
['%s=%s' % (k, v) for k, v in dict_params.iteritems()])
|
||||
|
||||
|
||||
def main():
|
||||
app.run(cfg.CONF.listen_host, cfg.CONF.listen_port)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user