diff --git a/panel/static/panel/js/panel.js b/panel/static/panel/js/panel.js index 90b992b..2527a26 100644 --- a/panel/static/panel/js/panel.js +++ b/panel/static/panel/js/panel.js @@ -127,7 +127,9 @@ function set_project_status(project, value) { } function set_uuid_status(project, uuid, job, value) { - var div_uuid = $('#' + project + '-' + uuid); + var id = project + '-' + uuid; + var div_uuid = $('#' + id); + var div_uuid_date = $('#' + id + '-date'); var status = value.result; var _class = get_class_status("panel-", status); var jobs = $.release[project][uuid].jobs.size; @@ -152,7 +154,8 @@ function set_uuid_status(project, uuid, job, value) { } } } - $('.badge', div_uuid).html(jobs); + div_uuid_date.html(new Date(value.date)); + $('#' + id + '-badge').html(jobs); if (uuid == $.release[project].last_uuid) { set_project_status(project); // update badge @@ -224,8 +227,12 @@ function create_new_uuid_panel(project, uuid) { $('.job', div_uuid).attr('id', id + '-job').removeClass('job'); var div_title = $('.panel-heading > .panel-title', div_uuid); - div_title.html('<a name="' + id +'"/">' + uuid + - ' <span class="badge">' + $.release[project][uuid].jobs.size + '</span></a>'); + var div_uuid_name = $('.uuid-name', div_title).attr('id', id + '-name').removeClass('uuid-name'); + div_uuid_name.attr('name', id).html(uuid); + var div_uuid_date = $('.uuid-date', div_title).attr('id', id + '-date').removeClass('uuid-date'); + div_uuid_date.html('date'); + var div_uuid_badge = $('.uuid-badge', div_title).attr('id', id + '-badge').removeClass('uuid-badge'); + div_uuid_badge.html($.release[project][uuid].jobs.size); // put it on the proper place div_uuid.prependTo('#' + project + ' > .panel-body'); @@ -238,8 +245,8 @@ function create_new_project_panel(project) { div_project.removeClass('hidden'); div_project.attr('id', project).removeClass('project-clone').addClass('project'); - var div_title = $('.panel-heading > .panel-title', div_project); - div_title.html('<a name="' + project +'" href="./' + project + '/">' + project + '</a>'); + var div_title = $('.project-name', div_project); + div_title.html('<a name="' + project +'" href="./' + project + '">' + project + '</a>'); $('.error', div_project).attr('id', project + '-error').removeClass('error'); div_project.appendTo('#project-list'); @@ -257,14 +264,15 @@ function create_new_job(release, project, uuid, job) { function clean_uuids(release, project) { if ($.release.max_uuids == 0) { return; } - if ($.release[project].uuids.size >= $.release.max_uuids) { + if ($.release[project].uuids.size > $.release.max_uuids) { var step = $.release[project].uuids.size - $.release.max_uuids; for (var uuid of $.release[project].uuids) { if (step==0) { return; } - console.debug(uuid); if (uuid != $.release[project].last_uuid) { $('#' + project + '-' + uuid).remove(); + $.release[project].uuids.delete(uuid); + $.release[project].removed_uuids.add(uuid); step--; } } @@ -277,7 +285,6 @@ function create_new_uuid(release, project, uuid) { } $.release[project].uuids.add(uuid); - $.release[project].last_uuid = uuid; $.release[project][uuid] = { failed: false, jobs: new Set(),}; clean_uuids(release, project); @@ -291,7 +298,8 @@ function create_new_project(release, project) { return; } $.release.projects.add(project); - $.release[project] = {uuids: new Set(), failed: false, interval: 5000,}; + $.release[project] = {uuids: new Set(), failed: false, + interval: 5000, last_uuid: null, removed_uuids: new Set()}; create_new_project_panel(project); get_uuids_for_project(release, project); @@ -361,12 +369,48 @@ function update_uuid_info(release, project, uuid) { } } +function get_latest_uuid_for_project(release, project) { + + function showLatest(project, uuid) { + var div_project = $('#' + project); + $('.uuid-latest', project).addClass('hidden'); + var div_uuid_name = $('#' + project + '-' + uuid); + $('.uuid-latest', div_uuid_name).removeClass('hidden'); + } + + function successFunc(data, textStatus, jqXHR ) { + $(data).each(function() { + if ($.release[project].last_uuid != this.tag) { + $.release[project].last_uuid = this.tag; + console.debug(project + ".latest_uuid:" + $.release[project].last_uuid); + showLatest(project, this.tag); + } + }); + } + + function errorFunc(jqXHR, status, error) { + $('#' + project + '-error').html(error); + } + + $.ajax({ + url: '/release/' + release +'/' + project + '/latest/?format=json', + method: 'GET', + contentType: "application/json; charset=utf-8", + dataType: "json", + success: successFunc, + error: errorFunc + }); +} + function get_uuids_for_project(release, project) { function successFunc(data, textStatus, jqXHR ) { $(data).each(function() { if (!$.release[project].uuids.has(this.tag)) { - create_new_uuid(release, project, this.tag); + if(!$.release[project].removed_uuids.has(this.tag)) { + create_new_uuid(release, project, this.tag); + get_latest_uuid_for_project(release, project); + } } else if (!$.release[project][this.tag].failed) { update_uuid_info(release, project, this.tag); diff --git a/panel/templates/panel/base_project.html b/panel/templates/panel/base_project.html new file mode 100644 index 0000000..c9445b1 --- /dev/null +++ b/panel/templates/panel/base_project.html @@ -0,0 +1,27 @@ +<div class="panel-heading"> + <h3 class="panel-title project-name"></h3> +</div> +<div class="panel-body"> + <div class="panel panel-default hidden uuid-clone"> + <div class="panel-heading"> + <h3 class="panel-title"> + <div class="row"> + <div class="col-md-4"> + <a class="uuid-name">uuid</a> + <span class="label label-primary uuid-latest hidden">Latest</span> + </div> + <div class="col-md-4 text-info uuid-date">date</div> + <div class="col-md-4 test-info"> + <span class="badge uuid-badge"></span> + </div> + </div> + </h3> + </div> + <div class="panel-body"> + <ul class="list-group list-inline uuid-list"> + <li class="list-group-item hidden job"></li> + </ul> + </div> + </div> +</div> +<div class="panel-footer error"></div> diff --git a/panel/templates/panel/project.html b/panel/templates/panel/project.html index 2176b93..c97fcb2 100644 --- a/panel/templates/panel/project.html +++ b/panel/templates/panel/project.html @@ -1,28 +1,14 @@ {% extends "panel/base.html" %} {% block title %}{{ project }}{% endblock %} -{% block navlist%} +{% block navlist %} + <!-- hello --> <li><a href="{% url 'panel:release-view' release %}">{{ release }}</a></li> <li class="active"><a href="#">{{ project }}</a></li> {% endblock %} {% block content %} <div class="container"> <div class="panel panel-default project-clone hidden"> - <div class="panel-heading"> - <h3 class="panel-title"></h3> - </div> - <div class="panel-body"> - <div class="panel panel-default hidden uuid-clone"> - <div class="panel-heading"> - <h3 class="panel-title"></h3> - </div> - <div class="panel-body"> - <ul class="list-group list-inline uuid-list"> - <li class="list-group-item hidden job"></li> - </ul> - </div> - </div> - </div> - <div class="panel-footer error"></div> + {% include "panel/base_project.html" %} </div> <div id="project-list"></div> </div> @@ -31,7 +17,7 @@ {% block extrajs %} <script type="text/javascript"> $( document ).ready(function() { - $.release.max_uuids = 0; + $.release.max_uuids = 2; $.release.timer = setInterval(function(){ get_uuids_for_project('{{release}}', '{{ project }}'); }, $.release.interval); diff --git a/panel/templates/panel/release.html b/panel/templates/panel/release.html index 1b250ef..ed41a73 100644 --- a/panel/templates/panel/release.html +++ b/panel/templates/panel/release.html @@ -1,86 +1,15 @@ {% extends "panel/base.html" %} {% block title %}{{ release }}{% endblock %} -{% block navlist%} +{% block navlist %} <li class="active"><a href="#">{{ release }}</a></li> {% endblock %} {% block content %} <div class="container"> <div class="panel panel-default" id="stats"> - <div class="panel-heading"> - <h3 class="panel-title">statistics</h3> - </div> - <div class="panel-body"> - <div> - Total projects: <span id="stats-total">0</span> - </div> - <div> - Failed: <span id="stats-danger">0</span> - </div> - <div class="progress"> - <div class="progress-bar progress-bar-danger" - role="progressbar" aria-valuenow="0" aria-valuemin="0" - aria-valuemax="100" style="min-width: 2em; width: 0%"> - <span id="stats-label-danger">0% Failed</span> - </div> - </div> - <ul class='list-group list-inline list-stat' id='stats-list-danger'> - <li class='list-group-item hidden list-group-item-danger stats-project-danger-clone'></li> - </ul> - <div> - Building: <span id="stats-created">0</span> - </div> - <div class="progress"> - <div class="progress-bar progress-bar-created" - role="progressbar" aria-valuenow="0" aria-valuemin="0" - aria-valuemax="100" style="min-width: 2em; width: 0%"> - <span id="stats-label-danger">0% Building</span> - </div> - </div> - <ul class='list-group list-inline list-stat' id='stats-list-created'> - <li class='list-group-item hidden stats-project-created-clone'></li> - </ul> - <div> - Success: <span id="stats-success">0</span> - </div> - <div class="progress"> - <div class="progress-bar progress-bar-success" - role="progressbar" aria-valuenow="0" aria-valuemin="0" - aria-valuemax="100" style="min-width: 2em; width: 0%"> - <span id="stats-label-success">0% Success</span> - </div> - </div> - <div> - Warning: <span id="stats-warning">0</span> - </div> - <div class="progress"> - <div class="progress-bar progress-bar-warning" - role="progressbar" aria-valuenow="0" aria-valuemin="0" - aria-valuemax="100" style="min-width: 2em; width: 0%"> - <span id="stats-label-warning">0% Warning</span> - </div> - </div> - <ul class='list-group list-inline list-stat' id='stats-list-warning'> - <li class='list-group-item hidden list-group-item-warning stats-project-warning-clone'></li> - </ul> - </div> + {% include "panel/release_stats.html" %} </div> <div class="panel panel-default project-clone hidden"> - <div class="panel-heading"> - <h3 class="panel-title"></h3> - </div> - <div class="panel-body"> - <div class="panel panel-default hidden uuid-clone"> - <div class="panel-heading"> - <h3 class="panel-title"></h3> - </div> - <div class="panel-body"> - <ul class="list-group list-inline uuid-list"> - <li class="list-group-item hidden job"></li> - </ul> - </div> - </div> - </div> - <div class="panel-footer error"></div> + {% include "panel/base_project.html" %} </div> <div id="project-list"></div> </div> @@ -89,7 +18,7 @@ {% block extrajs %} <script type="text/javascript"> $( document ).ready(function() { - $.release.max_uuids = 2; + $.release.max_uuids = 1; get_projects('{{release}}'); }); </script> diff --git a/panel/templates/panel/release_stats.html b/panel/templates/panel/release_stats.html new file mode 100644 index 0000000..affd18b --- /dev/null +++ b/panel/templates/panel/release_stats.html @@ -0,0 +1,57 @@ +<div class="panel-heading"> + <h3 class="panel-title">statistics</h3> +</div> +<div class="panel-body"> + <div> + Total projects: <span id="stats-total">0</span> + </div> + <div> + Failed: <span id="stats-danger">0</span> + </div> + <div class="progress"> + <div class="progress-bar progress-bar-danger" + role="progressbar" aria-valuenow="0" aria-valuemin="0" + aria-valuemax="100" style="min-width: 2em; width: 0%"> + <span id="stats-label-danger">0% Failed</span> + </div> + </div> + <ul class='list-group list-inline list-stat' id='stats-list-danger'> + <li class='list-group-item hidden list-group-item-danger stats-project-danger-clone'></li> + </ul> + <div> + Building: <span id="stats-created">0</span> + </div> + <div class="progress"> + <div class="progress-bar progress-bar-created" + role="progressbar" aria-valuenow="0" aria-valuemin="0" + aria-valuemax="100" style="min-width: 2em; width: 0%"> + <span id="stats-label-danger">0% Building</span> + </div> + </div> + <ul class='list-group list-inline list-stat' id='stats-list-created'> + <li class='list-group-item hidden stats-project-created-clone'></li> + </ul> + <div> + Success: <span id="stats-success">0</span> + </div> + <div class="progress"> + <div class="progress-bar progress-bar-success" + role="progressbar" aria-valuenow="0" aria-valuemin="0" + aria-valuemax="100" style="min-width: 2em; width: 0%"> + <span id="stats-label-success">0% Success</span> + </div> + </div> + <div> + Warning: <span id="stats-warning">0</span> + </div> + <div class="progress"> + <div class="progress-bar progress-bar-warning" + role="progressbar" aria-valuenow="0" aria-valuemin="0" + aria-valuemax="100" style="min-width: 2em; width: 0%"> + <span id="stats-label-warning">0% Warning</span> + </div> + </div> + <ul class='list-group list-inline list-stat' id='stats-list-warning'> + <li class='list-group-item hidden list-group-item-warning stats-project-warning-clone'></li> + </ul> +</div> diff --git a/repoapi/models.py b/repoapi/models.py index edf3d2d..f936955 100644 --- a/repoapi/models.py +++ b/repoapi/models.py @@ -54,6 +54,12 @@ class JenkinsBuildInfoManager(models.Manager): else: return res.values('jobname') + def latest_uuid(self, release, project): + qs = self.get_queryset() + latest_uuid = qs.filter( + param_release=release, projectname=project).latest('date') + return {'tag': latest_uuid.tag, 'date': latest_uuid.date} + class JenkinsBuildInfo(models.Model): tag = models.CharField(max_length=64, null=True) diff --git a/repoapi/test/test_model_queries.py b/repoapi/test/test_model_queries.py index 54ba60a..2a4dddc 100644 --- a/repoapi/test/test_model_queries.py +++ b/repoapi/test/test_model_queries.py @@ -15,7 +15,7 @@ from django.test import TestCase from repoapi.models import JenkinsBuildInfo - +from django.utils.dateparse import parse_datetime class JBIQueriesTestCase(TestCase): fixtures = ['test_model_queries.json'] @@ -48,3 +48,7 @@ class JBIQueriesTestCase(TestCase): 'mr3.1-fake', 'fake', 'UUID1') self.assertItemsEqual( ['fake-get-code', 'fake-source-tests', 'fake-source'], jobs) + + def test_latest_uuid(self): + date = parse_datetime("2015-05-04T17:04:57.802Z") + self.assertEquals(JenkinsBuildInfo.objects.latest_uuid('mr3.1-fake', 'fake'), {'tag': 'UUID1', 'date': date}) diff --git a/repoapi/urls.py b/repoapi/urls.py index bd899bc..7016891 100644 --- a/repoapi/urls.py +++ b/repoapi/urls.py @@ -32,6 +32,9 @@ api_patterns = [ url(r'^release/(?P<release>[^/]+)/$', views.ProjectList.as_view(), name='project-list'), + url(r'^release/(?P<release>[^/]+)/(?P<project>[^/]+)/latest/$', + views.LatestUUID.as_view(), + name='latestuuid-list'), url(r'^release/(?P<release>[^/]+)/(?P<project>[^/]+)/$', views.ProjectUUIDList.as_view(), name='projectuuid-list'), diff --git a/repoapi/views.py b/repoapi/views.py index 050d865..bdd18c3 100644 --- a/repoapi/views.py +++ b/repoapi/views.py @@ -96,3 +96,9 @@ class UUIDInfoList(APIView): res = jbi.objects.jobs_by_uuid( release, project, uuid, flat=False) return Response(res) + +class LatestUUID(APIView): + + def get(self, request, release, project, format=None): + res = jbi.objects.latest_uuid(release, project) + return Response(res)