summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandru DAMIAN <alexandru.damian@intel.com>2015-06-08 18:33:44 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-06-12 00:01:49 +0100
commit58cd4a14ea81b72dcd9679608e5e2231ec3d3631 (patch)
tree15cea3afb06ad5ae448fbf2fb65bfb4cb7535308
parent27f5137cd6143b523e9aea8eeba406337aa935c4 (diff)
downloadpoky-58cd4a14ea81b72dcd9679608e5e2231ec3d3631.tar.gz
bitbake: toaster: fixes after refactoring
This patch fixes issues brought in by refactoring: * the New Build button is working with pre-set projects * the xhr_datatypeahead is exposed for calls that are not mapable to the REST objects * a new table returing recipes provided by layers currently selected in the project is used to provide recipe suggestions * the field names in json are switched from "list" to "rows" as to maintain consistency with the ToasterTables * the "value" field in xhr_ calls is now named "search" to maintain consistency (Bitbake rev: a5bc29083d4f85a5695f3f62d5badb783c6f7224) Signed-off-by: Alexandru DAMIAN <alexandru.damian@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--bitbake/lib/toaster/orm/models.py5
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/base.js104
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/libtoaster.js2
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/projectapp.js24
-rw-r--r--bitbake/lib/toaster/toastergui/tables.py10
-rw-r--r--bitbake/lib/toaster/toastergui/templates/base.html7
-rw-r--r--bitbake/lib/toaster/toastergui/templates/project.html3
-rw-r--r--bitbake/lib/toaster/toastergui/urls.py8
-rwxr-xr-xbitbake/lib/toaster/toastergui/views.py17
9 files changed, 116 insertions, 64 deletions
diff --git a/bitbake/lib/toaster/orm/models.py b/bitbake/lib/toaster/orm/models.py
index 8e73ee1afd..88194504c5 100644
--- a/bitbake/lib/toaster/orm/models.py
+++ b/bitbake/lib/toaster/orm/models.py
@@ -180,13 +180,12 @@ class Project(models.Model):
180 queryset = queryset.filter(layer__name = layer_name) 180 queryset = queryset.filter(layer__name = layer_name)
181 181
182 # order by layer version priority 182 # order by layer version priority
183 queryset = queryset.filter(Q(layer_source=None) | Q(layer_source__releaselayersourcepriority__release = release)).select_related('layer_source', 'layer', 'up_branch').annotate(prio=Avg("layer_source__releaselayersourcepriority__priority")).order_by("-prio") 183 queryset = queryset.filter(Q(layer_source=None) | Q(layer_source__releaselayersourcepriority__release = release)).select_related('layer_source', 'layer', 'up_branch', "layer_source__releaselayersourcepriority__priority").order_by("-layer_source__releaselayersourcepriority__priority")
184 184
185 return queryset 185 return queryset
186 186
187 # returns a set of layer-equivalent set of layers already in project
188 def projectlayer_equivalent_set(self): 187 def projectlayer_equivalent_set(self):
189 return [j for i in [x.layercommit.get_equivalents_wpriority(self) for x in self.projectlayer_set.all().select_related("up_branch")] for j in i] 188 return self.compatible_layerversions().filter(layer__name__in = [x.layercommit.layer.name for x in self.projectlayer_set.all()]).select_related("up_branch")
190 189
191 def schedule_build(self): 190 def schedule_build(self):
192 from bldcontrol.models import BuildRequest, BRTarget, BRLayer, BRVariable, BRBitbake 191 from bldcontrol.models import BuildRequest, BRTarget, BRLayer, BRVariable, BRBitbake
diff --git a/bitbake/lib/toaster/toastergui/static/js/base.js b/bitbake/lib/toaster/toastergui/static/js/base.js
index 747442cc9e..06d0676cbf 100644
--- a/bitbake/lib/toaster/toastergui/static/js/base.js
+++ b/bitbake/lib/toaster/toastergui/static/js/base.js
@@ -1,100 +1,118 @@
1'use strict';
1 2
2 3function basePageInit(ctx) {
3function basePageInit (ctx) {
4 4
5 var newBuildButton = $("#new-build-button"); 5 var newBuildButton = $("#new-build-button");
6 /* Hide the button if we're on the project,newproject or importlyaer page 6 /* Hide the button if we're on the project,newproject or importlyaer page
7 * or if there are no projects yet defined 7 * or if there are no projects yet defined
8 */ 8 */
9 if (ctx.numProjects == 0 || ctx.currentUrl.search('newproject|project/\\d$|importlayer$') > 0){ 9 if (ctx.numProjects === 0 || ctx.currentUrl.search('newproject|project/\\d$|importlayer$') > 0) {
10 newBuildButton.hide(); 10 newBuildButton.hide();
11 return; 11 return;
12 } 12 }
13 13
14 var currentProjectId = libtoaster.ctx.projectId; 14 var currentProjectId = libtoaster.ctx.projectId;
15 15
16 /* Hide the change project icon when there is only one project */ 16 /* Hide the change project icon when there is only one project */
17 if (ctx.numProjects == 1){ 17 if (ctx.numProjects === 1) {
18 $('#project .icon-pencil').hide(); 18 $('#project .icon-pencil').hide();
19 } 19 }
20 20
21 newBuildButton.show().removeAttr("disabled"); 21 newBuildButton.show().removeAttr("disabled");
22 22
23 23
24 _checkProjectBuildable() 24 var newBuildProjectInput = $("#new-build-button #project-name-input");
25 var newBuildTargetBuildBtn = $("#new-build-button #build-button");
26 var newBuildTargetInput = $("#new-build-button #build-target-input");
27 var newBuildProjectSaveBtn = $("#new-build-button #save-project-button");
28
29
30 var selectedTarget;
31
32 _checkProjectBuildable();
25 _setupNewBuildButton(); 33 _setupNewBuildButton();
26 34
27 35
28 function _checkProjectBuildable(){ 36 function _checkProjectBuildable() {
29 if (libtoaster.ctx.projectId == undefined) 37 if (libtoaster.ctx.projectId === undefined) {
30 return; 38 return;
39 }
31 40
32 libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl, 41 libtoaster.getProjectInfo(libtoaster.ctx.projectPageUrl,
33 function(data){ 42 function (data) {
34 if (data.machine.name == undefined || data.layers.length == 0) { 43 if (data.machine.name === undefined || data.layers.length === 0) {
35 /* we can't build anything with out a machine and some layers */ 44 /* we can't build anything with out a machine and some layers */
36 $("#new-build-button #targets-form").hide(); 45 $("#new-build-button #targets-form").hide();
37 $("#new-build-button .alert").show(); 46 $("#new-build-button .alert").show();
38 } else { 47 } else {
39 $("#new-build-button #targets-form").show(); 48 $("#new-build-button #targets-form").show();
40 $("#new-build-button .alert").hide(); 49 $("#new-build-button .alert").hide();
50
51 /* we can build this project; enable input fields */
52 newBuildTargetInput.prop("disabled", false);
53 newBuildTargetBuildBtn.prop("disabled", false);
54
55 libtoaster.makeTypeahead(newBuildTargetInput, libtoaster.ctx.projectTargetsUrl, { format: "json" }, function (item) {
56 /* successfully selected a target */
57 selectedTarget = item;
58 });
59
41 } 60 }
42 }, null); 61 }, null);
43 } 62 }
44 63
45 function _setupNewBuildButton() { 64 function _setupNewBuildButton() {
46 /* Setup New build button */ 65 /* Setup New build button */
47 var newBuildProjectInput = $("#new-build-button #project-name-input");
48 var newBuildTargetBuildBtn = $("#new-build-button #build-button");
49 var newBuildTargetInput = $("#new-build-button #build-target-input");
50 var newBuildProjectSaveBtn = $("#new-build-button #save-project-button");
51 var selectedTarget;
52 var selectedProject; 66 var selectedProject;
53 67
54 /* If we don't have a current project then present the set project 68 /* If we don't have a current project then present the set project
55 * form. 69 * form.
56 */ 70 */
57 if (libtoaster.ctx.projectId == undefined) { 71 if (libtoaster.ctx.projectId === undefined) {
58 $('#change-project-form').show(); 72 $('#change-project-form').show();
59 $('#project .icon-pencil').hide(); 73 $('#project .icon-pencil').hide();
60 } 74 }
61 75
62 76
63 libtoaster.makeTypeahead(newBuildProjectInput, libtoaster.ctx.projectsUrl, { format : "json" }, function(item){ 77 libtoaster.makeTypeahead(newBuildProjectInput, libtoaster.ctx.projectsUrl, { format : "json" }, function (item) {
64 /* successfully selected a project */ 78 /* successfully selected a project */
65 newBuildProjectSaveBtn.removeAttr("disabled"); 79 newBuildProjectSaveBtn.removeAttr("disabled");
66 selectedProject = item; 80 selectedProject = item;
67 }); 81 });
68 82
69 /* Any typing in the input apart from enter key is going to invalidate 83 /* Any typing in the input apart from enter key is going to invalidate
70 * the value that has been set by selecting a suggestion from the typeahead 84 * the value that has been set by selecting a suggestion from the typeahead
71 */ 85 */
72 newBuildProjectInput.on('input', function(event) { 86 newBuildProjectInput.on('input', function (event) {
73 if (event.keyCode == 13) 87 if (event.keyCode === 13) {
74 return; 88 return;
75 newBuildProjectSaveBtn.attr("disabled", "disabled"); 89 }
90 newBuildProjectSaveBtn.attr("disabled", "disabled");
76 }); 91 });
77 92
78 newBuildTargetInput.on('input', function() { 93 newBuildTargetInput.on('input', function () {
79 if ($(this).val().length == 0) 94 if ($(this).val().length === 0) {
80 newBuildTargetBuildBtn.attr("disabled", "disabled"); 95 newBuildTargetBuildBtn.attr("disabled", "disabled");
81 else 96 } else {
82 newBuildTargetBuildBtn.removeAttr("disabled"); 97 newBuildTargetBuildBtn.removeAttr("disabled");
98 }
83 }); 99 });
84 100
85 newBuildTargetBuildBtn.click(function() { 101 newBuildTargetBuildBtn.click(function () {
86 if (!newBuildTargetInput.val()) 102 if (!newBuildTargetInput.val()) {
87 return; 103 return;
104 }
88 105
89 if (!selectedTarget) 106 if (!selectedTarget) {
90 selectedTarget = { name: newBuildTargetInput.val() }; 107 selectedTarget = { name: newBuildTargetInput.val() };
108 }
91 /* fire and forget */ 109 /* fire and forget */
92 libtoaster.startABuild(ctx.projectBuildsUrl, libtoaster.ctx.projectId, selectedTarget.name, null, null); 110 libtoaster.startABuild(libtoaster.ctx.projectBuildsUrl, libtoaster.ctx.projectId, selectedTarget.name, null, null);
93 window.location.replace(libtoaster.ctx.projectPageUrl); 111 window.location.replace(libtoaster.ctx.projectPageUrl);
94 }); 112 });
95 113
96 newBuildProjectSaveBtn.click(function() { 114 newBuildProjectSaveBtn.click(function () {
97 libtoaster.ctx.projectId = selectedProject.pk 115 libtoaster.ctx.projectId = selectedProject.pk;
98 /* Update the typeahead project_id paramater */ 116 /* Update the typeahead project_id paramater */
99 _checkProjectBuildable(); 117 _checkProjectBuildable();
100 118
@@ -111,10 +129,10 @@ function basePageInit (ctx) {
111 newBuildTargetInput.prop("disabled", false); 129 newBuildTargetInput.prop("disabled", false);
112 newBuildTargetBuildBtn.prop("disabled", false); 130 newBuildTargetBuildBtn.prop("disabled", false);
113 131
114 libtoaster.makeTypeahead(newBuildTargetInput, selectedProject.projectTargetsUrl, { format: "json" }, function(item){ 132 libtoaster.makeTypeahead(newBuildTargetInput, selectedProject.projectTargetsUrl, { format: "json" }, function (item) {
115 /* successfully selected a target */ 133 /* successfully selected a target */
116 selectedTarget = item; 134 selectedTarget = item;
117 }); 135 });
118 136
119 newBuildTargetInput.val(""); 137 newBuildTargetInput.val("");
120 138
@@ -123,12 +141,12 @@ function basePageInit (ctx) {
123 $("#new-build-button .alert a").attr('href', libtoaster.ctx.projectPageUrl); 141 $("#new-build-button .alert a").attr('href', libtoaster.ctx.projectPageUrl);
124 $("#project .icon-pencil").show(); 142 $("#project .icon-pencil").show();
125 143
126 $("#change-project-form").slideUp({ 'complete' : function() { 144 $("#change-project-form").slideUp({ 'complete' : function () {
127 $("#new-build-button #project").show(); 145 $("#new-build-button #project").show();
128 }}); 146 }});
129 }); 147 });
130 148
131 $('#new-build-button #project .icon-pencil').click(function() { 149 $('#new-build-button #project .icon-pencil').click(function () {
132 newBuildProjectSaveBtn.attr("disabled", "disabled"); 150 newBuildProjectSaveBtn.attr("disabled", "disabled");
133 newBuildProjectInput.val($("#new-build-button #project a").text()); 151 newBuildProjectInput.val($("#new-build-button #project a").text());
134 $("#cancel-change-project").show(); 152 $("#cancel-change-project").show();
@@ -136,8 +154,8 @@ function basePageInit (ctx) {
136 $("#change-project-form").slideDown(); 154 $("#change-project-form").slideDown();
137 }); 155 });
138 156
139 $("#new-build-button #cancel-change-project").click(function() { 157 $("#new-build-button #cancel-change-project").click(function () {
140 $("#change-project-form").hide(function(){ 158 $("#change-project-form").hide(function () {
141 $('#new-build-button #project').show(); 159 $('#new-build-button #project').show();
142 }); 160 });
143 161
@@ -146,7 +164,7 @@ function basePageInit (ctx) {
146 }); 164 });
147 165
148 /* Keep the dropdown open even unless we click outside the dropdown area */ 166 /* Keep the dropdown open even unless we click outside the dropdown area */
149 $(".new-build").click (function(event) { 167 $(".new-build").click (function (event) {
150 event.stopPropagation(); 168 event.stopPropagation();
151 }); 169 });
152 }; 170 };
diff --git a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
index b1038cf618..23755a75f2 100644
--- a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
+++ b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
@@ -25,7 +25,7 @@ var libtoaster = (function (){
25 return; 25 return;
26 } 26 }
27 27
28 return process (data.list); 28 return process (data.rows);
29 }); 29 });
30 }, 30 },
31 updater: function(item) { 31 updater: function(item) {
diff --git a/bitbake/lib/toaster/toastergui/static/js/projectapp.js b/bitbake/lib/toaster/toastergui/static/js/projectapp.js
index a915278444..44e244d302 100644
--- a/bitbake/lib/toaster/toastergui/static/js/projectapp.js
+++ b/bitbake/lib/toaster/toastergui/static/js/projectapp.js
@@ -217,13 +217,13 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
217 $scope.getAutocompleteSuggestions = function(type, currentValue) { 217 $scope.getAutocompleteSuggestions = function(type, currentValue) {
218 var deffered = $q.defer(); 218 var deffered = $q.defer();
219 219
220 $http({method:"GET", url: $scope.urls.xhr_datatypeahead, params : { type: type, value: currentValue}}) 220 $http({method:"GET", url: $scope.urls.xhr_datatypeahead, params : { type: type, search: currentValue}})
221 .success(function (_data) { 221 .success(function (_data) {
222 if (_data.error != "ok") { 222 if (_data.error != "ok") {
223 console.warn(_data.error); 223 console.warn(_data.error);
224 deffered.reject(_data.error); 224 deffered.reject(_data.error);
225 } 225 }
226 deffered.resolve(_data.list); 226 deffered.resolve(_data.rows);
227 }); 227 });
228 228
229 return deffered.promise; 229 return deffered.promise;
@@ -534,8 +534,17 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
534 if (_data.error != "ok") { 534 if (_data.error != "ok") {
535 console.warn(_data.error); 535 console.warn(_data.error);
536 } else { 536 } else {
537 console.log("got layer deps", _data.layerdeps.list); 537 /* filter out layers that are already in the project */
538 if (_data.layerdeps.list.length > 0) { 538 var filtered_list = [];
539 var projectlayers_ids = $scope.layers.map(function (e) { return e.id });
540 for (var i = 0; i < _data.layerdeps.list.length; i++) {
541 if (projectlayers_ids.indexOf(_data.layerdeps.list[i].id) == -1) {
542 filtered_list.push( _data.layerdeps.list[i]);
543 }
544 }
545
546 _data.layerdeps.list = filtered_list;
547 if (_data.layerdeps.list.length > 0) {
539 // activate modal 548 // activate modal
540 console.log("listing modals"); 549 console.log("listing modals");
541 var modalInstance = $modal.open({ 550 var modalInstance = $modal.open({
@@ -575,7 +584,6 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
575 console.log("built modal instance", modalInstance); 584 console.log("built modal instance", modalInstance);
576 585
577 modalInstance.result.then(function (selectedArray) { 586 modalInstance.result.then(function (selectedArray) {
578 console.log("layer to add", $scope.layerToAdd)
579 selectedArray.push($scope.layerToAdd.id); 587 selectedArray.push($scope.layerToAdd.id);
580 console.warn("TRC6: selected", selectedArray); 588 console.warn("TRC6: selected", selectedArray);
581 589
@@ -634,13 +642,13 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
634 $scope.testProjectSettingsChange = function(elementid) { 642 $scope.testProjectSettingsChange = function(elementid) {
635 if (elementid != '#change-project-version') throw "Not implemented"; 643 if (elementid != '#change-project-version') throw "Not implemented";
636 644
637 $http({method:"GET", url: $scope.urls.xhr_datatypeahead, params : { type: "versionlayers", value: $scope.projectVersion }}). 645 $http({method:"GET", url: $scope.urls.xhr_datatypeahead, params : { type: "versionlayers", search: $scope.projectVersion }}).
638 success(function (_data) { 646 success(function (_data) {
639 if (_data.error != "ok") { 647 if (_data.error != "ok") {
640 alert (_data.error); 648 alert (_data.error);
641 } 649 }
642 else { 650 else {
643 if (_data.list.length > 0) { 651 if (_data.rows.length > 0) {
644 // activate modal 652 // activate modal
645 var modalInstance = $modal.open({ 653 var modalInstance = $modal.open({
646 templateUrl: 'change_version_modal', 654 templateUrl: 'change_version_modal',
@@ -660,7 +668,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc
660 }, 668 },
661 resolve: { 669 resolve: {
662 items: function () { 670 items: function () {
663 return _data.list; 671 return _data.rows;
664 }, 672 },
665 releaseName: function () { 673 releaseName: function () {
666 return $scope.releases.filter(function (e) { if (e.id == $scope.projectVersion) return e;})[0].name; 674 return $scope.releases.filter(function (e) { if (e.id == $scope.projectVersion) return e;})[0].name;
diff --git a/bitbake/lib/toaster/toastergui/tables.py b/bitbake/lib/toaster/toastergui/tables.py
index 003b924d00..b85527e216 100644
--- a/bitbake/lib/toaster/toastergui/tables.py
+++ b/bitbake/lib/toaster/toastergui/tables.py
@@ -287,7 +287,7 @@ class RecipesTable(ToasterTable):
287 def setup_queryset(self, *args, **kwargs): 287 def setup_queryset(self, *args, **kwargs):
288 prj = Project.objects.get(pk = kwargs['pid']) 288 prj = Project.objects.get(pk = kwargs['pid'])
289 289
290 self.queryset = Recipe.objects.filter(Q(layer_version__up_branch__name= prj.release.name) | Q(layer_version__build__in = prj.build_set.all())).filter(name__regex=r'.{1,}.*') 290 self.queryset = Recipe.objects.filter(layer_version__in = prj.compatible_layerversions())
291 291
292 search_maxids = map(lambda i: i[0], list(self.queryset.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id'))) 292 search_maxids = map(lambda i: i[0], list(self.queryset.values('name').distinct().annotate(max_id=Max('id')).values_list('max_id')))
293 293
@@ -392,3 +392,11 @@ class LayerRecipesTable(RecipesTable):
392 self.add_column(title="Build recipe", 392 self.add_column(title="Build recipe",
393 static_data_name="add-del-layers", 393 static_data_name="add-del-layers",
394 static_data_template=build_recipe_template) 394 static_data_template=build_recipe_template)
395
396class ProjectLayersRecipesTable(RecipesTable):
397 """ Table that lists only recipes available for layers added to the project """
398
399 def setup_queryset(self, *args, **kwargs):
400 super(ProjectLayersRecipesTable, self).setup_queryset(*args, **kwargs)
401 prj = Project.objects.get(pk = kwargs['pid'])
402 self.queryset = self.queryset.filter(layer_version__in = prj.projectlayer_equivalent_set())
diff --git a/bitbake/lib/toaster/toastergui/templates/base.html b/bitbake/lib/toaster/toastergui/templates/base.html
index 7fee26eb42..6cdc5e8110 100644
--- a/bitbake/lib/toaster/toastergui/templates/base.html
+++ b/bitbake/lib/toaster/toastergui/templates/base.html
@@ -1,5 +1,6 @@
1<!DOCTYPE html> 1<!DOCTYPE html>
2{% load static %} 2{% load static %}
3{% load projecttags %}
3<html lang="en"> 4<html lang="en">
4 <head> 5 <head>
5 <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title> 6 <title>{% if objectname %} {{objectname|title}} - {% endif %}Toaster</title>
@@ -33,8 +34,10 @@
33 htmlUrl : "{% static 'html/' %}", 34 htmlUrl : "{% static 'html/' %}",
34 projectsUrl : "{% url 'all-projects' %}", 35 projectsUrl : "{% url 'all-projects' %}",
35 {% if project.id %} 36 {% if project.id %}
36 projectPageUrl : "{% url 'project' project.id %}", 37 projectPageUrl : {% url 'project' project.id as purl%}{{purl|json}},
37 projectName : "{{project.name}}", 38 projectName : {{project.name|json}},
39 projectTargetsUrl: {% url 'projectavailabletargets' project.id as paturl%}{{paturl|json}},
40 projectBuildsUrl: {% url 'projectbuilds' project.id as pburl %}{{pburl|json}},
38 projectId : {{project.id}}, 41 projectId : {{project.id}},
39 {% else %} 42 {% else %}
40 projectPageUrl : undefined, 43 projectPageUrl : undefined,
diff --git a/bitbake/lib/toaster/toastergui/templates/project.html b/bitbake/lib/toaster/toastergui/templates/project.html
index 7225363c01..bca703a162 100644
--- a/bitbake/lib/toaster/toastergui/templates/project.html
+++ b/bitbake/lib/toaster/toastergui/templates/project.html
@@ -452,9 +452,10 @@ angular.element(document).ready(function() {
452 scope.urls.xhr_build = "{% url 'projectbuilds' project.id %}"; 452 scope.urls.xhr_build = "{% url 'projectbuilds' project.id %}";
453 scope.urls.xhr_edit = "{% url 'project' project.id %}?format=json"; 453 scope.urls.xhr_edit = "{% url 'project' project.id %}?format=json";
454 scope.urls.layers = "{% url 'projectlayers' project.id %}"; 454 scope.urls.layers = "{% url 'projectlayers' project.id %}";
455 scope.urls.targets = "{% url 'projecttargets' project.id %}"; 455 scope.urls.targets = "{% url 'projectavailabletargets' project.id %}";
456 scope.urls.machines = "{% url 'projectmachines' project.id %}"; 456 scope.urls.machines = "{% url 'projectmachines' project.id %}";
457 scope.urls.importlayer = "{% url 'importlayer' project.id %}"; 457 scope.urls.importlayer = "{% url 'importlayer' project.id %}";
458 scope.urls.xhr_datatypeahead = {% url 'xhr_datatypeahead' project.id as xhrdta %}{{xhrdta|json}};
458 scope.project = {{prj|json}}; 459 scope.project = {{prj|json}};
459 scope.builds = {{builds|json}}; 460 scope.builds = {{builds|json}};
460 scope.layers = {{layers|json}}; 461 scope.layers = {{layers|json}};
diff --git a/bitbake/lib/toaster/toastergui/urls.py b/bitbake/lib/toaster/toastergui/urls.py
index 5a79f88eb4..bd3eb401de 100644
--- a/bitbake/lib/toaster/toastergui/urls.py
+++ b/bitbake/lib/toaster/toastergui/urls.py
@@ -96,6 +96,12 @@ urlpatterns = patterns('toastergui.views',
96 'title' : 'All compatible recipes' }, 96 'title' : 'All compatible recipes' },
97 name="projecttargets"), 97 name="projecttargets"),
98 98
99 url(r'^project/(?P<pid>\d+)/availablerecipes/$',
100 tables.ProjectLayersRecipesTable.as_view(template_name="generic-toastertable-page.html"),
101 { 'table_name': tables.ProjectLayersRecipesTable.__name__.lower(),
102 'title' : 'Recipes available for layers in the current project' },
103 name="projectavailabletargets"),
104
99 url(r'^project/(?P<pid>\d+)/layers/$', 105 url(r'^project/(?P<pid>\d+)/layers/$',
100 tables.LayersTable.as_view(template_name="generic-toastertable-page.html"), 106 tables.LayersTable.as_view(template_name="generic-toastertable-page.html"),
101 { 'table_name': tables.LayersTable.__name__.lower(), 107 { 'table_name': tables.LayersTable.__name__.lower(),
@@ -118,6 +124,8 @@ urlpatterns = patterns('toastergui.views',
118 'title' : 'All machines in layer' }, 124 'title' : 'All machines in layer' },
119 name=tables.LayerMachinesTable.__name__.lower()), 125 name=tables.LayerMachinesTable.__name__.lower()),
120 126
127
128 url(r'^xhr_datatypeahead/(?P<pid>\d+)$', 'xhr_datatypeahead', name='xhr_datatypeahead'),
121 url(r'^xhr_configvaredit/(?P<pid>\d+)$', 'xhr_configvaredit', name='xhr_configvaredit'), 129 url(r'^xhr_configvaredit/(?P<pid>\d+)$', 'xhr_configvaredit', name='xhr_configvaredit'),
122 130
123 url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'), 131 url(r'^xhr_importlayer/$', 'xhr_importlayer', name='xhr_importlayer'),
diff --git a/bitbake/lib/toaster/toastergui/views.py b/bitbake/lib/toaster/toastergui/views.py
index b2b263b6e0..4dac62c568 100755
--- a/bitbake/lib/toaster/toastergui/views.py
+++ b/bitbake/lib/toaster/toastergui/views.py
@@ -129,9 +129,9 @@ def _template_renderer(template):
129 129
130 if request.GET.get('format', None) == 'json': 130 if request.GET.get('format', None) == 'json':
131 # objects is a special keyword - it's a Page, but we need the actual objects here 131 # objects is a special keyword - it's a Page, but we need the actual objects here
132 # in XHR, the objects come in the "list" property 132 # in XHR, the objects come in the "rows" property
133 if "objects" in context: 133 if "objects" in context:
134 context["list"] = context["objects"].object_list 134 context["rows"] = context["objects"].object_list
135 del context["objects"] 135 del context["objects"]
136 136
137 # we're about to return; to keep up with the XHR API, we set the error to OK 137 # we're about to return; to keep up with the XHR API, we set the error to OK
@@ -2340,7 +2340,7 @@ if toastermain.settings.MANAGED:
2340 retval.append(i) 2340 retval.append(i)
2341 2341
2342 return HttpResponse(jsonfilter( {"error":"ok", 2342 return HttpResponse(jsonfilter( {"error":"ok",
2343 "list" : map( _lv_to_dict(prj), map(lambda x: x.layercommit, retval )) 2343 "rows" : map( _lv_to_dict(prj), map(lambda x: x.layercommit, retval ))
2344 }), content_type = "application/json") 2344 }), content_type = "application/json")
2345 2345
2346 2346
@@ -2358,7 +2358,7 @@ if toastermain.settings.MANAGED:
2358 # and show only the selected layers for this project 2358 # and show only the selected layers for this project
2359 final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset_all]) 2359 final_list = set([x.get_equivalents_wpriority(prj)[0] for x in queryset_all])
2360 2360
2361 return HttpResponse(jsonfilter( { "error":"ok", "list" : map( _lv_to_dict(prj), final_list) }), content_type = "application/json") 2361 return HttpResponse(jsonfilter( { "error":"ok", "rows" : map( _lv_to_dict(prj), final_list) }), content_type = "application/json")
2362 2362
2363 2363
2364 raise Exception("Unknown request! " + request.GET.get('type', "No parameter supplied")) 2364 raise Exception("Unknown request! " + request.GET.get('type', "No parameter supplied"))
@@ -2845,7 +2845,7 @@ if toastermain.settings.MANAGED:
2845 p.projectPageUrl = reverse('project', args=(p.id,)) 2845 p.projectPageUrl = reverse('project', args=(p.id,))
2846 p.projectLayersUrl = reverse('projectlayers', args=(p.id,)) 2846 p.projectLayersUrl = reverse('projectlayers', args=(p.id,))
2847 p.projectBuildsUrl = reverse('projectbuilds', args=(p.id,)) 2847 p.projectBuildsUrl = reverse('projectbuilds', args=(p.id,))
2848 p.projectTargetsUrl = reverse('projecttargets', args=(p.id,)) 2848 p.projectTargetsUrl = reverse('projectavailabletargets', args=(p.id,))
2849 2849
2850 # build view-specific information; this is rendered specifically in the builds page, at the top of the page (i.e. Recent builds) 2850 # build view-specific information; this is rendered specifically in the builds page, at the top of the page (i.e. Recent builds)
2851 build_mru = _managed_get_latest_builds() 2851 build_mru = _managed_get_latest_builds()
@@ -3144,6 +3144,13 @@ else:
3144 def project(request, pid): 3144 def project(request, pid):
3145 return {} 3145 return {}
3146 3146
3147 from django.views.decorators.csrf import csrf_exempt
3148 @csrf_exempt
3149 @_template_renderer('landing_not_managed.html')
3150 def xhr_datatypeahead(request, pid):
3151 return {}
3152
3153
3147 @_template_renderer('landing_not_managed.html') 3154 @_template_renderer('landing_not_managed.html')
3148 def xhr_configvaredit(request, pid): 3155 def xhr_configvaredit(request, pid):
3149 return {} 3156 return {}