summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/static
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster/toastergui/static')
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/layerBtn.js3
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js103
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/recipedetails.js3
3 files changed, 96 insertions, 13 deletions
diff --git a/bitbake/lib/toaster/toastergui/static/js/layerBtn.js b/bitbake/lib/toaster/toastergui/static/js/layerBtn.js
index aa43284396..259271df33 100644
--- a/bitbake/lib/toaster/toastergui/static/js/layerBtn.js
+++ b/bitbake/lib/toaster/toastergui/static/js/layerBtn.js
@@ -76,7 +76,8 @@ function layerBtnsInit() {
76 if (imgCustomModal.length == 0) 76 if (imgCustomModal.length == 0)
77 throw("Modal new-custom-image not found"); 77 throw("Modal new-custom-image not found");
78 78
79 imgCustomModal.data('recipe', $(this).data('recipe')); 79 var recipe = {id: $(this).data('recipe'), name: null}
80 newCustomImageModalSetRecipes([recipe]);
80 imgCustomModal.modal('show'); 81 imgCustomModal.modal('show');
81 }); 82 });
82} 83}
diff --git a/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js b/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
index 98e87f4a6b..1ae0d34e90 100644
--- a/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
+++ b/bitbake/lib/toaster/toastergui/static/js/newcustomimage_modal.js
@@ -1,33 +1,59 @@
1"use strict"; 1"use strict";
2 2
3/* Used for the newcustomimage_modal actions */ 3/*
4Used for the newcustomimage_modal actions
5
6The .data('recipe') value on the outer element determines which
7recipe ID is used as the basis for the new custom image recipe created via
8this modal.
9
10Use newCustomImageModalSetRecipes() to set the recipes available as a base
11for the new custom image. This will manage the addition of radio buttons
12to select the base image (or remove the radio buttons, if there is only a
13single base image available).
14*/
4function newCustomImageModalInit(){ 15function newCustomImageModalInit(){
5 16
6 var newCustomImgBtn = $("#create-new-custom-image-btn"); 17 var newCustomImgBtn = $("#create-new-custom-image-btn");
7 var imgCustomModal = $("#new-custom-image-modal"); 18 var imgCustomModal = $("#new-custom-image-modal");
8 var invalidNameHelp = $("#invalid-name-help"); 19 var invalidNameHelp = $("#invalid-name-help");
20 var invalidRecipeHelp = $("#invalid-recipe-help");
9 var nameInput = imgCustomModal.find('input'); 21 var nameInput = imgCustomModal.find('input');
10 22
11 var invalidMsg = "Image names cannot contain spaces or capital letters. The only allowed special character is dash (-)."; 23 var invalidNameMsg = "Image names cannot contain spaces or capital letters. The only allowed special character is dash (-).";
12 var duplicateImageMsg = "An image with this name already exists in this project."; 24 var duplicateNameMsg = "An image with this name already exists. Image names must be unique.";
13 var duplicateRecipeMsg = "A non-image recipe with this name already exists."; 25 var invalidBaseRecipeIdMsg = "Please select an image to customise.";
26
27 // capture clicks on radio buttons inside the modal; when one is selected,
28 // set the recipe on the modal
29 imgCustomModal.on("click", "[name='select-image']", function (e) {
30 clearRecipeError();
31
32 var recipeId = $(e.target).attr('data-recipe');
33 imgCustomModal.data('recipe', recipeId);
34 });
14 35
15 newCustomImgBtn.click(function(e){ 36 newCustomImgBtn.click(function(e){
16 e.preventDefault(); 37 e.preventDefault();
17 38
18 var baseRecipeId = imgCustomModal.data('recipe'); 39 var baseRecipeId = imgCustomModal.data('recipe');
19 40
41 if (!baseRecipeId) {
42 showRecipeError(invalidBaseRecipeIdMsg);
43 return;
44 }
45
20 if (nameInput.val().length > 0) { 46 if (nameInput.val().length > 0) {
21 libtoaster.createCustomRecipe(nameInput.val(), baseRecipeId, 47 libtoaster.createCustomRecipe(nameInput.val(), baseRecipeId,
22 function(ret) { 48 function(ret) {
23 if (ret.error !== "ok") { 49 if (ret.error !== "ok") {
24 console.warn(ret.error); 50 console.warn(ret.error);
25 if (ret.error === "invalid-name") { 51 if (ret.error === "invalid-name") {
26 showError(invalidMsg); 52 showNameError(invalidNameMsg);
27 } else if (ret.error === "image-already-exists") { 53 return;
28 showError(duplicateImageMsg); 54 } else if (ret.error === "already-exists") {
29 } else if (ret.error === "recipe-already-exists") { 55 showNameError(duplicateNameMsg);
30 showError(duplicateRecipeMsg); 56 return;
31 } 57 }
32 } else { 58 } else {
33 imgCustomModal.modal('hide'); 59 imgCustomModal.modal('hide');
@@ -37,12 +63,21 @@ function newCustomImageModalInit(){
37 } 63 }
38 }); 64 });
39 65
40 function showError(text){ 66 function showNameError(text){
41 invalidNameHelp.text(text); 67 invalidNameHelp.text(text);
42 invalidNameHelp.show(); 68 invalidNameHelp.show();
43 nameInput.parent().addClass('error'); 69 nameInput.parent().addClass('error');
44 } 70 }
45 71
72 function showRecipeError(text){
73 invalidRecipeHelp.text(text);
74 invalidRecipeHelp.show();
75 }
76
77 function clearRecipeError(){
78 invalidRecipeHelp.hide();
79 }
80
46 nameInput.on('keyup', function(){ 81 nameInput.on('keyup', function(){
47 if (nameInput.val().length === 0){ 82 if (nameInput.val().length === 0){
48 newCustomImgBtn.prop("disabled", true); 83 newCustomImgBtn.prop("disabled", true);
@@ -50,7 +85,7 @@ function newCustomImageModalInit(){
50 } 85 }
51 86
52 if (nameInput.val().search(/[^a-z|0-9|-]/) != -1){ 87 if (nameInput.val().search(/[^a-z|0-9|-]/) != -1){
53 showError(invalidMsg); 88 showNameError(invalidNameMsg);
54 newCustomImgBtn.prop("disabled", true); 89 newCustomImgBtn.prop("disabled", true);
55 nameInput.parent().addClass('error'); 90 nameInput.parent().addClass('error');
56 } else { 91 } else {
@@ -60,3 +95,49 @@ function newCustomImageModalInit(){
60 } 95 }
61 }); 96 });
62} 97}
98
99// Set the image recipes which can used as the basis for the custom
100// image recipe the user is creating
101//
102// baseRecipes: a list of one or more recipes which can be
103// used as the base for the new custom image recipe in the format:
104// [{'id': <recipe ID>, 'name': <recipe name>'}, ...]
105//
106// if recipes is a single recipe, just show the text box to set the
107// name for the new custom image; if recipes contains multiple recipe objects,
108// show a set of radio buttons so the user can decide which to use as the
109// basis for the new custom image
110function newCustomImageModalSetRecipes(baseRecipes) {
111 var imgCustomModal = $("#new-custom-image-modal");
112 var imageSelector = $('#new-custom-image-modal [data-role="image-selector"]');
113 var imageSelectRadiosContainer = $('#new-custom-image-modal [data-role="image-selector-radios"]');
114
115 if (baseRecipes.length === 1) {
116 // hide the radio button container
117 imageSelector.hide();
118
119 // remove any radio buttons + labels
120 imageSelector.remove('[data-role="image-radio"]');
121
122 // set the single recipe ID on the modal as it's the only one
123 // we can build from
124 imgCustomModal.data('recipe', baseRecipes[0].id);
125 }
126 else {
127 // add radio buttons; note that the handlers for the radio buttons
128 // are set in newCustomImageModalInit via event delegation
129 for (var i = 0; i < baseRecipes.length; i++) {
130 var recipe = baseRecipes[i];
131 imageSelectRadiosContainer.append(
132 '<label class="radio" data-role="image-radio">' +
133 recipe.name +
134 '<input type="radio" class="form-control" name="select-image" ' +
135 'data-recipe="' + recipe.id + '">' +
136 '</label>'
137 );
138 }
139
140 // show the radio button container
141 imageSelector.show();
142 }
143}
diff --git a/bitbake/lib/toaster/toastergui/static/js/recipedetails.js b/bitbake/lib/toaster/toastergui/static/js/recipedetails.js
index d5f9eacdce..604db5f037 100644
--- a/bitbake/lib/toaster/toastergui/static/js/recipedetails.js
+++ b/bitbake/lib/toaster/toastergui/static/js/recipedetails.js
@@ -9,7 +9,8 @@ function recipeDetailsPageInit(ctx){
9 if (imgCustomModal.length === 0) 9 if (imgCustomModal.length === 0)
10 throw("Modal new-custom-image not found"); 10 throw("Modal new-custom-image not found");
11 11
12 imgCustomModal.data('recipe', $(this).data('recipe')); 12 var recipe = {id: $(this).data('recipe'), name: null}
13 newCustomImageModalSetRecipes([recipe]);
13 imgCustomModal.modal('show'); 14 imgCustomModal.modal('show');
14 }); 15 });
15 16