// vim: set tabstop=4 expandtab ai: // BitBake Toaster Implementation // // Copyright (C) 2013 Intel Corporation // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. angular_formpost = function($httpProvider) { // Use x-www-form-urlencoded Content-Type // By Ezekiel Victor, http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/, no license, with attribution $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'; /** * The workhorse; converts an object to x-www-form-urlencoded serialization. * @param {Object} obj * @return {String} */ var param = function(obj) { var query = '', name, value, fullSubName, subName, subValue, innerObj, i; for(name in obj) { value = obj[name]; if(value instanceof Array) { for(i=0; i elem.id) continue; if ($scope.builds[i].id == elem.id) { found=true; break;} if ($scope.builds[i].id < elem.id) break; } if (!found) { $scope.builds.splice(i, 0, elem); } }); } if (_data.layers !== undefined) { var addedLayers = []; var deletedLayers = []; // step 1 - delete entries not found $scope.layers.forEach(function (elem) { if (-1 == _data.layers.findIndex(function (elemX) { return elemX.id == elem.id && elemX.name == elem.name; })) { deletedLayers.push(elem); } }); deletedLayers.forEach(function (elem) { $scope.layers.splice($scope.layers.indexOf(elem),1); }); // step 2 - merge new entries _data.layers.forEach(function (elem) { var found = false; var i; for (i = 0 ; i < $scope.layers.length; i ++) { if ($scope.layers[i].orderid < elem.orderid) continue; if ($scope.layers[i].orderid == elem.orderid) { found = true; break; } if ($scope.layers[i].orderid > elem.orderid) break; } if (!found) { $scope.layers.splice(i, 0, elem); addedLayers.push(elem); } }); // step 3 - display alerts. if (addedLayers.length > 0) { $scope.displayAlert($scope.zone2alerts, "You have added "+addedLayers.length+" layer" + ((addedLayers.length>1)?"s: ":": ") + addedLayers.map(function (e) { return ""+e.name+"" }).join(", "), "alert-info"); } if (deletedLayers.length > 0) { $scope.displayAlert($scope.zone2alerts, "You have deleted "+deletedLayers.length+" layer" + ((deletedLayers.length>1)?"s: ":": ") + deletedLayers.map(function (e) { return ""+e.name+"" }).join(", "), "alert-info"); } } if (_data.targets !== undefined) { $scope.targets = _data.targets; } if (_data.machine !== undefined) { $scope.machine = _data.machine; } if (_data.user !== undefined) { $scope.user = _data.user; } if (_data.prj !== undefined) { $scope.project = _data.prj; // update breadcrumb, outside the controller $('#project_name').text($scope.project.name); } $scope.validateData(); inXHRcall = false; deffered.resolve(_data); } }).error(function(_data, _status, _headers, _config) { alert("Failed HTTP XHR request (" + _status + ")" + _data); console.error("Failed HTTP XHR request: ", _data, _status, _headers, _config); inXHRcall = false; deffered.reject(_data.error); }); return deffered.promise; } $scope.layeralert = undefined; // shows user alerts on invalid project data $scope.validateData = function () { if ($scope.layers.length == 0) { $scope.layeralert = $scope.displayAlert($scope.zone1alerts, "You need to add some layers to this project. View all layers available in Toaster or import a layer"); } else { if ($scope.layeralert != undefined) { $scope.layeralert.close(); $scope.layeralert = undefined; } } } $scope.targetExistingBuild = function(targets) { var oldTargetName = $scope.targetName; $scope.targetName = targets.map(function(v,i,a){return v.target}).join(' '); $scope.targetNamedBuild(); $scope.targetName = oldTargetName; } $scope.targetNamedBuild = function(target) { if ($scope.targetName === undefined && $scope.targetName1 === undefined){ alert("No target defined, please type in a target name"); return; } $scope.sanitizeTargetName(); $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_build, data : { targets: $scope.safeTargetName, } }).then(function (data) { console.log("received ", data); $scope.targetName = undefined; $scope.targetName1 = undefined; $location.hash('buildslist'); // call $anchorScroll() $anchorScroll(); }); } $scope.sanitizeTargetName = function() { $scope.safeTargetName = undefined; if (undefined === $scope.targetName) $scope.safeTargetName = $scope.targetName1; if (undefined === $scope.targetName1) $scope.safeTargetName = $scope.targetName; if (undefined === $scope.safeTargetName) return; $scope.safeTargetName = $scope.safeTargetName.replace(/\[.*\]/, '').trim(); } $scope.buildCancel = function(id) { $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_build, data: { buildCancel: id, } }); } $scope.buildDelete = function(id) { $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_build, data: { buildDelete: id, } }); } $scope.onLayerSelect = function (item, model, label) { $scope.layerAddId = item.id; } $scope.layerAdd = function() { $http({method:"GET", url: $scope.urls.xhr_datatypeahead, params : { type: "layerdeps", value: $scope.layerAddId }}) .success(function (_data) { if (_data.error != "ok") { alert(_data.error); } else { if (_data.list.length > 0) { // activate modal var modalInstance = $modal.open({ templateUrl: 'dependencies_modal', controller: function ($scope, $modalInstance, items, layerAddName) { $scope.items = items; $scope.layerAddName = layerAddName; $scope.selectedItems = (function () { s = {}; for (var i = 0; i < items.length; i++) { s[items[i].id] = true; };return s; })(); $scope.ok = function() { console.log("scope selected is ", $scope.selectedItems); $modalInstance.close(Object.keys($scope.selectedItems).filter(function (e) { return $scope.selectedItems[e];})); }; $scope.cancel = function() { $modalInstance.dismiss('cancel'); }; $scope.update = function() { console.log("updated ", $scope.selectedItems); }; }, resolve: { items: function () { return _data.list; }, layerAddName: function () { return $scope.layerAddName; }, } }); modalInstance.result.then(function (selectedArray) { selectedArray.push($scope.layerAddId); console.log("selected", selectedArray); $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_edit, data: { layerAdd: selectedArray.join(","), } }).then(function () { $scope.layerAddName = undefined; }); }); } else { $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_edit, data: { layerAdd: $scope.layerAddId, } }).then(function () { $scope.layerAddName = undefined; }); } } }); } $scope.layerDel = function(id) { $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_edit, data: { layerDel: id, } }); } $scope.test = function(elementid) { $http({method:"GET", url: $scope.urls.xhr_datatypeahead, params : { type: "versionlayers", value: $scope.projectVersion }}). success(function (_data) { if (_data.error != "ok") { alert (_data.error); } else { if (_data.list.length > 0) { // activate modal var modalInstance = $modal.open({ templateUrl: 'change_version_modal', controller: function ($scope, $modalInstance, items, releaseName) { $scope.items = items; $scope.releaseName = releaseName; $scope.ok = function() { $modalInstance.close(); }; $scope.cancel = function() { $modalInstance.dismiss('cancel'); }; }, resolve: { items: function () { return _data.list; }, releaseName: function () { return $scope.releases.filter(function (e) { if (e.id == $scope.projectVersion) return e;})[0].name; }, } }); modalInstance.result.then(function () { $scope.edit(elementid)}); } else { $scope.edit(elementid); } } }); } $scope.edit = function(elementid) { var data = {}; console.log("edit with ", elementid); var alertText = undefined; var alertZone = undefined; var oldLayers = []; switch(elementid) { case '#select-machine': alertText = "You have changed the machine to: " + $scope.machineName + ""; alertZone = $scope.zone2alerts; data['machineName'] = $scope.machineName; break; case '#change-project-name': data['projectName'] = $scope.projectName; alertText = "You have changed the project name to: " + $scope.projectName + ""; alertZone = $scope.zone3alerts; break; case '#change-project-version': data['projectVersion'] = $scope.projectVersion; alertText = "You have changed the release to: "; alertZone = $scope.zone3alerts; // save old layers oldLayers = $scope.layers.slice(0); break; default: throw "FIXME: implement conversion for element " + elementid; } $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_edit, data: data, }).then( function (_data) { $scope.toggle(elementid); if (data['projectVersion'] != undefined) { alertText += "" + $scope.project.release.desc + ". "; } if (elementid == '#change-project-version') { // requirement https://bugzilla.yoctoproject.org/attachment.cgi?id=2229, notification for changed version to include layers $scope.zone2alerts.forEach(function (e) { e.close() }); alertText += "This has caused the following changes in your project layers:"; } $scope.displayAlert(alertZone, alertText, "alert-info"); }); } $scope.updateDisplayWithCommands = function() { cmd = $location.path(); function _cmdExecuteWithParam(param, f) { if (cmd.indexOf(param)==0) { if (cmd.indexOf("=") > -1) { var parameter = cmd.split("=", 2)[1]; if (parameter != undefined && parameter.length > 0) { f(parameter); } } else { f(); }; } } _cmdExecuteWithParam("/newproject", function () { $scope.displayAlert($scope.zone1alerts, "Your project " + $scope.project.name + " has been created. You can now add layers and select targets you want to build.", "alert-success"); }); _cmdExecuteWithParam("/targetbuild=", function (targets) { var oldTargetName = $scope.targetName; $scope.targetName = targets.split(",").join(" "); $scope.targetNamedBuild(); $scope.targetName = oldTargetName; }); _cmdExecuteWithParam("/machineselect=", function (machine) { $scope.machineName = machine; $scope.toggle('#select-machine'); }); _cmdExecuteWithParam("/layeradd=", function (layer) { angular.forEach(layer.split(","), function (l) { $scope.layerAddId = l; $scope.layerAdd(); }); }); } $scope.displayAlert = function(zone, text, type) { if (zone.maxid === undefined) { zone.maxid = 0; } var crtid = zone.maxid ++; angular.forEach(zone, function (o) { o.close() }); o = { id: crtid, text: text, type: type, close: function() { zone.splice((function(id){ for (var i = 0; i < zone.length; i++) if (id == zone[i].id) { return i}; return undefined;})(crtid), 1); }, } zone.push(o); return o; } $scope.toggle = function(id) { $scope.projectName = $scope.project.name; $scope.projectVersion = $scope.project.release.id; $scope.machineName = $scope.machine.name; angular.element(id).toggle(); angular.element(id+"-opposite").toggle(); } $scope.selectedMostBuildTargets = function () { keys = Object.keys($scope.mostBuiltTargets); keys = keys.filter(function (e) { if ($scope.mostBuiltTargets[e]) return e }); return keys.length == 0; } // init code // $scope.init = function() { $scope.pollHandle = $interval(function () { $scope._makeXHRCall({method: "GET", url: $scope.urls.xhr_edit, data: undefined});}, 2000, 0); } $scope.init(); }); /** TESTING CODE */ function test_diff_arrays() { _diffArrays([1,2,3], [2,3,4], function(e,f) { return e==f; }, function(e) {console.log("added", e)}, function(e) {console.log("deleted", e);}) } // test_diff_arrays(); var s = undefined; function test_set_alert(text) { s = angular.element("div#main").scope(); s.displayAlert(s.zone3alerts, text); console.log(s.zone3alerts); s.$digest(); }