This adds some basic package dependency hint modals when you add and
remove a package. It also makes sure that if the CustomImageRecipe has
no current included packages that we go and check this with the server
to see if a relevant build has taken place which will provide this
information.

[YOCTO #8082]

Signed-off-by: Michael Wood <[email protected]>
---
 .../toaster/toastergui/static/js/customrecipe.js   | 148 +++++++++++++++++++--
 .../toaster/toastergui/templates/customrecipe.html |  46 ++++++-
 .../toastergui/templates/pkg_add_rm_btn.html       |  35 ++---
 3 files changed, 196 insertions(+), 33 deletions(-)

diff --git a/bitbake/lib/toaster/toastergui/static/js/customrecipe.js 
b/bitbake/lib/toaster/toastergui/static/js/customrecipe.js
index 4cd9382..2d43ec2 100644
--- a/bitbake/lib/toaster/toastergui/static/js/customrecipe.js
+++ b/bitbake/lib/toaster/toastergui/static/js/customrecipe.js
@@ -4,32 +4,145 @@ function customRecipePageInit(ctx) {
 
   var urlParams = libtoaster.parseUrlParams();
   var customiseTable = $("#selectpackagestable");
+  var addPkgDepsModalBtn = $("#add-package-deps-modal-btn");
+  var rmdPkgReverseDepsModalBtn = $("#rm-package-reverse-deps-modal-btn");
 
-  (function notificationRequest(){
-    if (urlParams.hasOwnProperty('notify') && urlParams.notify === 'new'){
-      $("#image-created-notification").show();
-    }
-  })();
+  if (urlParams.hasOwnProperty('notify') && urlParams.notify === 'new'){
+    $("#image-created-notification").show();
+  }
+
+  /* If the total packages included in this image is 0 we need to
+   * try updating this recipe
+   */
+  if (ctx.recipe.includedPackagesCount === 0){
+    libtoaster.createCustomRecipe(ctx.recipe.name,
+      ctx.recipe.baseRecipeId,
+      function(ret){
+        /* TODO rather than reload the page just show the table and hide err */
+        if (ret.packages > 0){
+          window.location.reload();
+        } else {
+          console.warn("Tried again and no packages found for this recipe");
+        }
+    });
+  }
 
-  customiseTable.on('table-done', function(e, total, tableParams){
+  customiseTable.on('table-done', function(e, total){
     /* Table is done so now setup the click handler for the package buttons */
     $(".add-rm-package-btn").click(function(e){
       e.preventDefault();
-      addRemovePackage($(this), tableParams);
+      var pkgBtnData = $(this).data();
+
+       checkPackageDeps(pkgBtnData, function(pkgData){
+         if (pkgBtnData.directive === 'add'){
+           /* If we're adding a package we may need to show the modal to advise
+            * on dependencies for this package.
+            */
+           if (pkgData.unsatisfied_dependencies.length === 0){
+             addRemovePackage(pkgBtnData);
+           } else {
+             showPackageDepsModal(pkgBtnData, pkgData);
+           }
+         } else if (pkgBtnData.directive === 'remove') {
+           if (pkgData.reverse_dependencies.length === 0){
+             addRemovePackage(pkgBtnData);
+           } else {
+             showPackageReverseDepsModal(pkgBtnData, pkgData);
+           }
+           }
+        });
+    });
+  });
+
+  function checkPackageDeps(pkgBtnData, doneCb){
+    $.ajax({
+        type: 'GET',
+        url: pkgBtnData.packageUrl,
+        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+        success: function(data){
+          if (data.error !== 'ok'){
+            console.warn(data.error);
+            return;
+          }
+          doneCb(data);
+        }
     });
+  }
+
+  function showPackageDepsModal(pkgBtnData, pkgData){
+    var modal = $("#package-deps-modal");
+    var depsList = modal.find("#package-add-dep-list");
+    var deps = pkgData.unsatisfied_dependencies;
+
+    modal.find(".package-to-add-name").text(pkgBtnData.name);
+
+    depsList.text("");
+
+    for (var i in deps){
+      var li = $('<li></li>').text(deps[i].depends_on__name);
+      li.append($('<span></span>').text(" ("+
+            deps[i].depends_on__size_formatted+")"));
+      depsList.append(li);
+    }
+
+    modal.find("#package-deps-total-size").text(
+      pkgData.unsatisfied_dependencies_size_formatted);
+
+    addPkgDepsModalBtn.data(pkgBtnData);
+    modal.modal('show');
+  }
+
+  addPkgDepsModalBtn.click(function(e){
+    e.preventDefault();
+
+    addRemovePackage($(this).data(), null);
+  });
+
+  function showPackageReverseDepsModal(pkgBtnData, pkgData){
+    var modal = $("#package-reverse-deps-modal");
+    var depsList = modal.find("#package-reverse-dep-list");
+    var deps = pkgData.reverse_dependencies;
+
+    modal.find(".package-to-rm-name").text(pkgBtnData.name);
+
+    depsList.text("");
+
+    for (var i in deps){
+      var li = $('<li></li>').text(deps[i].package__name);
+      li.append($('<span></span>').text(" ("+
+            deps[i].package__size_formatted+")"));
+      depsList.append(li);
+    }
+
+    modal.find("#package-reverse-deps-total-size").text(
+      pkgData.reverse_dependencies_size_formatted);
+
+    rmdPkgReverseDepsModalBtn.data(pkgBtnData);
+    modal.modal('show');
+  }
+
+  rmdPkgReverseDepsModalBtn.click(function(e){
+    e.preventDefault();
+
+    addRemovePackage($(this).data(), null);
   });
 
-  function addRemovePackage(pkgBtn, tableParams){
-    var pkgBtnData = pkgBtn.data();
+
+  function addRemovePackage(pkgBtnData, tableParams){
     var method;
     var msg = "You have ";
 
-    if (pkgBtnData.directive == 'add') {
+    var btnCell = $("#package-btn-cell-"+pkgBtnData.package);
+    var inlineNotify = btnCell.children(".inline-notification");
+
+    if (pkgBtnData.directive === 'add') {
       method = 'PUT';
       msg += "added 1 package to "+ctx.recipe.name+":";
-    } else if (pkgBtnData.directive == 'remove') {
+      inlineNotify.text("1 package added");
+    } else if (pkgBtnData.directive === 'remove') {
       method = 'DELETE';
       msg += "removed 1 package from "+ctx.recipe.name+":";
+      inlineNotify.text("1 package removed");
     } else {
       throw("Unknown package directive: should be add or remove");
     }
@@ -45,11 +158,18 @@ function customRecipePageInit(ctx) {
             console.warn(data.error);
             return;
           }
-          /* Reload and Invalidate the Add | Rm package table's current data */
-          tableParams.nocache = true;
-          customiseTable.trigger('reload', [tableParams]);
 
           libtoaster.showChangeNotification(msg);
+
+          /* Also do the in-cell notification */
+          btnCell.children("button").fadeOut().promise().done(function(){
+            inlineNotify.fadeIn().delay(500).fadeOut(function(){
+              if (pkgBtnData.directive === 'add')
+                btnCell.children("button[data-directive=remove]").fadeIn();
+              else
+                btnCell.children("button[data-directive=add]").fadeIn();
+            });
+          });
         }
     });
   }
diff --git a/bitbake/lib/toaster/toastergui/templates/customrecipe.html 
b/bitbake/lib/toaster/toastergui/templates/customrecipe.html
index 743625c..37e0689 100644
--- a/bitbake/lib/toaster/toastergui/templates/customrecipe.html
+++ b/bitbake/lib/toaster/toastergui/templates/customrecipe.html
@@ -26,6 +26,8 @@
       recipe : {
         id: {{recipe.pk}},
         name: "{{recipe.name}}",
+        includedPackagesCount: {{recipe.includes_set.count}},
+        baseRecipeId: {{recipe.base_recipe.pk}},
       }
     };
 
@@ -37,6 +39,44 @@
     }
   });
 </script>
+<!-- package dependencies modal -->
+<div style="display:none" id="package-deps-modal" class="modal hide fade in" 
tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" 
aria-hidden="true">x</button>
+    <h3><span class="package-to-add-name"></span> dependencies</h3>
+  </div>
+  <div class="modal-body">
+    <p>Based on information from a previous build it is likely that adding 
<strong class="package-to-add-name"></strong> will also add the following 
packages to your custom image:</p>
+    <ul id="package-add-dep-list">
+    </ul>
+  </div>
+  <div class="modal-footer">
+    <p class="help-block text-left">Total package size: <strong 
id="package-deps-total-size"></strong></p>
+    <button id="add-package-deps-modal-btn" type="submit" class="btn 
btn-primary" data-dismiss="modal">Add package</button>
+    <button class="btn" data-dismiss="modal">Cancel</button>
+  </div>
+</div>
+<!-- end package dependencies modal -->
+
+<!-- package reverse dependencies modal -->
+<div style="display:none" id="package-reverse-deps-modal" class="modal hide 
fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" 
aria-hidden="false">
+  <div class="modal-header">
+    <button type="button" class="close" data-dismiss="modal" 
aria-hidden="true">x</button>
+    <h3><span class="package-to-rm-name"></span> reverse dependencies</h3>
+  </div>
+  <div class="modal-body">
+    <p>Based on information from a previous build it is likely that <strong 
class="package-to-rm-name"></strong> may be added again as the following 
packages directly depend on it for your custom image:</p>
+    <ul id="package-reverse-dep-list">
+    </ul>
+  </div>
+  <div class="modal-footer">
+    <p class="help-block text-left">Total package size: <strong 
id="package-reverse-deps-total-size"></strong></p>
+    <button id="rm-package-reverse-deps-modal-btn" type="submit" class="btn 
btn-primary" data-dismiss="modal">Remove package</button>
+    <button class="btn" data-dismiss="modal">Cancel</button>
+  </div>
+</div>
+<!-- end package dependencies modal -->
+
 
 <div class="row-fluid span11">
   <div class="alert alert-success lead" id="image-created-notification" 
style="margin-top: 15px; display: none">
@@ -81,11 +121,11 @@
         </div>
       </div>
       <div id="packages-table">
-        {% if recipe.package_set.count == 0 and last_build == None %}
+        {% if recipe.get_all_packages.count == 0 and last_build == None %}
         <h2> Add | Remove packages </h2>
         <div class="alert alert-info air">
           <p class="lead">Toaster has no package information for 
{{recipe.name}}. To generate package information, build {{recipe.name}}</p>
-          <button class="btn btn-info btn-large build-custom-recipe" 
style="margin:20px 0 10px 0;">Build {{recipe.name}}</button>
+          <button class="btn btn-info btn-large build-custom-image" 
style="margin:20px 0 10px 0;">Build {{recipe.name}}</button>
         </div>
         {% else %}
         {# ToasterTable for Adding remove packages #}
@@ -103,7 +143,7 @@
           Approx. packages included
           <i class="icon-question-sign get-help" title="" 
data-original-title="The number of packages included is based on information 
from previous builds and from parsing layers, so we can never be sure it is 
100% accurate"></i>
         </dt>
-        <dd class="no-packages">{{recipe.package_set.all.count}}</dd>
+        <dd class="no-packages">{{recipe.get_all_packages.count}}</dd>
         <dt>
           Approx. package size
           <i class="icon-question-sign get-help" title="" 
data-original-title="Package size is based on information from previous builds, 
so we can never be sure it is 100% accurate"></i>
diff --git a/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html 
b/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html
index 8723d4e..493456f 100644
--- a/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html
+++ b/bitbake/lib/toaster/toastergui/templates/pkg_add_rm_btn.html
@@ -1,16 +1,19 @@
-<button class="btn btn-block btn-danger add-rm-package-btn" 
data-directive="remove" data-package="{{data.pk}}" data-package-url="{% url 
'xhr_customrecipe_packages' extra.recipe_id data.pk %}" 
data-name="{{data.name}}" style="
-  {% if data.pk not in extra.current_packages %}
-    display:none
-  {% endif %}
-  ">
-  <i class="icon-trash no-tooltip"></i>
-  Remove package
-</a>
-<button class="btn btn-block add-rm-package-btn" data-directive="add" 
data-package="{{data.pk}}" data-package-url="{% url 'xhr_customrecipe_packages' 
extra.recipe_id data.pk %}" data-name="{{data.name}}" style="
-  {% if data.pk in extra.current_packages %}
-    display:none
-  {% endif %}
-    ">
-<i class="icon-plus"></i>
- Add package
-</button>
+<div id="package-btn-cell-{{data.pk}}">
+  <div style="display: none; font-size: 11px; line-height: 1.3;" 
class="tooltip-inner inline-notification"></div>
+  <button class="btn btn-block btn-danger add-rm-package-btn" 
data-directive="remove" data-package="{{data.pk}}" data-package-url="{% url 
'xhr_customrecipe_packages' extra.recipe_id data.pk %}" 
data-name="{{data.name}}" style="
+      {% if data.pk not in extra.current_packages %}
+      display:none
+      {% endif %}
+      ">
+    <i class="icon-trash no-tooltip"></i>
+    Remove package
+  </a>
+  <button class="btn btn-block add-rm-package-btn" data-directive="add" 
data-package="{{data.pk}}" data-package-url="{% url 'xhr_customrecipe_packages' 
extra.recipe_id data.pk %}" data-name="{{data.name}}" style="
+      {% if data.pk in extra.current_packages %}
+      display:none
+      {% endif %}
+      ">
+    <i class="icon-plus"></i>
+    Add package
+  </button>
+</div>
-- 
2.1.4

-- 
_______________________________________________
toaster mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/toaster

Reply via email to