diff --git a/bitbake/lib/toaster/toastergui/static/css/default.css b/bitbake/lib/toaster/toastergui/static/css/default.css index fb20fc9241..da9697c408 100644 --- a/bitbake/lib/toaster/toastergui/static/css/default.css +++ b/bitbake/lib/toaster/toastergui/static/css/default.css @@ -113,6 +113,9 @@ select { width: auto; } .top-air { margin-top: 40px;} .progress { margin-bottom: 0px; } .lead .badge { font-size: 18px; font-weight: normal; border-radius: 15px; padding: 9px; } +.lead ol > li, .lead ul > li { + line-height: 35px; +} .well > .lead, .alert .lead { margin-bottom: 0px; } .well-transparent { background-color: transparent; } .no-results { margin: 10px 0; } @@ -191,3 +194,27 @@ dd > span { line-height: 20px; } .new-build form { margin: 5px 0 0; } .new-build .input-append { margin-bottom: 0; } #build-selected { margin-top: 15px; } + + +.animate-repeat { + list-style:none; + box-sizing:border-box; +} + +.animate-repeat.ng-move, +.animate-repeat.ng-enter, +.animate-repeat.ng-leave { + -webkit-transition:all linear 0.5s; + transition:all linear 0.5s; +} + +.animate-repeat.ng-leave.ng-leave-active, +.animate-repeat.ng-move, +.animate-repeat.ng-enter { + opacity:0; +} + +.animate-repeat.ng-leave, +.animate-repeat.ng-enter.ng-enter-active { + opacity:1; +} diff --git a/bitbake/lib/toaster/toastergui/static/js/projectapp.js b/bitbake/lib/toaster/toastergui/static/js/projectapp.js index b347451e88..356b92fc5a 100644 --- a/bitbake/lib/toaster/toastergui/static/js/projectapp.js +++ b/bitbake/lib/toaster/toastergui/static/js/projectapp.js @@ -74,17 +74,34 @@ angular_formpost = function($httpProvider) { * * no return */ -function _diffArrays(oldArray, newArray, compareElements, onAdded, onDeleted ) { - if (onDeleted !== undefined) { - oldArray.filter(function (e) { var found = 0; newArray.map(function (f) { if (compareElements(e, f)) {found = 1};}); return !found;}).map(onDeleted); +function _diffArrays(existingArray, newArray, compareElements, onAdded, onDeleted ) { + var added = []; + var removed = []; + newArray.forEach( function( newElement, newIndex, _newArray) { + var existingIndex = existingArray.findIndex(function ( existingElement, _existingIndex, _existingArray ) { + return compareElements(newElement, existingElement); + }); + if (existingIndex < 0 && onAdded) { added.push(newElement); } + }); + existingArray.forEach( function( existingElement, existingIndex, _existingArray) { + var newIndex = newArray.findIndex(function ( newElement, _newIndex, _newArray ) { + return compareElements(newElement, existingElement); + }); + if (newIndex < 0 && onDeleted) { removed.push(existingElement); } + }); + + if (onAdded) { + added.map(onAdded); } - if (onAdded !== undefined) { - newArray.filter(function (e) { var found = 0; oldArray.map(function (f) { if (compareElements(e, f)) {found = 1};}); return !found;}).map(onAdded); + + if (onDeleted) { + removed.map(onDeleted); } + } -var projectApp = angular.module('project', ['ui.bootstrap', 'ngCookies'], angular_formpost); +var projectApp = angular.module('project', ['ngCookies', 'ngAnimate', 'ui.bootstrap' ], angular_formpost); // modify the template tag markers to prevent conflicts with Django projectApp.config(function($interpolateProvider) { @@ -111,7 +128,7 @@ projectApp.filter('timediff', function() { // main controller for the project page -projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $location, $cookies, $q, $sce) { +projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $location, $cookies, $q, $sce, $anchorScroll, $animate) { $scope.getSuggestions = function(type, currentValue) { var deffered = $q.defer(); @@ -159,40 +176,65 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc deffered.reject(_data.error); } else { - // TODO: update screen data if we have fields here if (_data.builds !== undefined) { - - var oldbuilds = $scope.builds; - $scope.builds = _data.builds; - - // identify canceled builds here, so we can display them. - _diffArrays(oldbuilds, $scope.builds, - function (e,f) { return e.id == f.id }, // compare - undefined, // added - function (e) { // deleted - if (e.status == "deleted") return; - e.status = "deleted"; - for (var i = 0; i < $scope.builds.length; i++) { - if ($scope.builds[i].status == "queued" && $scope.builds[i].id > e.id) - continue; - $scope.builds.splice(i, 0, e); - break; - } - }); + var toDelete = []; + // step 1 - delete entries not found + $scope.builds.forEach(function (elem) { + if (-1 == _data.builds.findIndex(function (elemX) { return elemX.id == elem.id && elemX.status == elem.status; })) { + toDelete.push(elem); + } + }); + toDelete.forEach(function (elem) { + $scope.builds.splice($scope.builds.indexOf(elem),1); + }); + // step 2 - merge new entries + _data.builds.forEach(function (elem) { + var found = false; + var i = 0; + for (i = 0 ; i < $scope.builds.length; i ++) { + if ($scope.builds[i].id > 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 oldlayers = $scope.layers; - $scope.layers = _data.layers; - // show added/deleted layer notifications var addedLayers = []; var deletedLayers = []; - _diffArrays( oldlayers, $scope.layers, function (e, f) { return e.id == f.id }, - function (e) { console.log("new layer", e);addedLayers.push(e); }, - function (e) { console.log("del layer", e);deletedLayers.push(e); }); + // 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"); } @@ -253,7 +295,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc } $scope.targetNamedBuild = function(target) { - if ($scope.targetName === undefined){ + if ($scope.targetName === undefined && $scope.targetName1 === undefined){ alert("No target defined, please type in a target name"); return; } @@ -263,17 +305,26 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_build, data : { - targets: $scope.targetName + 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() { - if (undefined === $scope.targetName) return; - $scope.targetName = $scope.targetName.replace(/\[.*\]/, '').trim(); + $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) { @@ -285,6 +336,16 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc }); } + $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; } @@ -413,6 +474,7 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc 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 + ""; @@ -428,25 +490,61 @@ projectApp.controller('prjCtrl', function($scope, $modal, $http, $interval, $loc 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; } - console.log("calling edit with ", data); $scope._makeXHRCall({ method: "POST", url: $scope.urls.xhr_edit, data: data, - }).then( function () { + }).then( function (_data) { $scope.toggle(elementid); if (data['projectVersion'] != undefined) { - alertText += "" + $scope.project.release.name + ""; + 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:
{[e.msg]}
+ Error type {[e.type]}: {[e.msg]}
View all layers | Import layer