diff options
Diffstat (limited to 'bitbake/lib/toaster/toastergui/static/js/importlayer.js')
-rw-r--r-- | bitbake/lib/toaster/toastergui/static/js/importlayer.js | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/bitbake/lib/toaster/toastergui/static/js/importlayer.js b/bitbake/lib/toaster/toastergui/static/js/importlayer.js new file mode 100644 index 0000000000..e2bc1ab607 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/static/js/importlayer.js | |||
@@ -0,0 +1,277 @@ | |||
1 | "use strict" | ||
2 | |||
3 | function importLayerPageInit (ctx) { | ||
4 | |||
5 | var layerDepBtn = $("#add-layer-dependency-btn"); | ||
6 | var importAndAddBtn = $("#import-and-add-btn"); | ||
7 | var layerNameInput = $("#layer-name"); | ||
8 | var vcsURLInput = $("#layer-git-repo-url"); | ||
9 | var gitRefInput = $("#layer-git-ref"); | ||
10 | var layerDepInput = $("#layer-dependency"); | ||
11 | var layerNameCtrl = $("#layer-name-ctrl"); | ||
12 | var duplicatedLayerName = $("#duplicated-layer-name-hint"); | ||
13 | |||
14 | var layerDeps = {}; | ||
15 | var layerDepsDeps = {}; | ||
16 | var currentLayerDepSelection; | ||
17 | var validLayerName = /^(\w|-)+$/; | ||
18 | |||
19 | $("#new-project-button").hide(); | ||
20 | |||
21 | libtoaster.makeTypeahead(layerDepInput, ctx.xhrDataTypeaheadUrl, { type : "layers", project_id: ctx.projectId, include_added: "true" }, function(item){ | ||
22 | currentLayerDepSelection = item; | ||
23 | |||
24 | layerDepBtn.removeAttr("disabled"); | ||
25 | }); | ||
26 | |||
27 | |||
28 | /* We automatically add "openembedded-core" layer for convenience as a | ||
29 | * dependency as pretty much all layers depend on this one | ||
30 | */ | ||
31 | $.getJSON(ctx.xhrDataTypeaheadUrl, { type : "layers", project_id: ctx.projectId, include_added: "true" , value: "openembedded-core" }, function(layer) { | ||
32 | if (layer.list.length == 1) { | ||
33 | currentLayerDepSelection = layer.list[0]; | ||
34 | layerDepBtn.click(); | ||
35 | } | ||
36 | }); | ||
37 | |||
38 | layerDepBtn.click(function(){ | ||
39 | if (currentLayerDepSelection == undefined) | ||
40 | return; | ||
41 | |||
42 | layerDeps[currentLayerDepSelection.id] = currentLayerDepSelection; | ||
43 | |||
44 | /* Make a list item for the new layer dependency */ | ||
45 | var newLayerDep = $("<li><a></a><span class=\"icon-trash\" data-toggle=\"tooltip\" title=\"Delete\"></span></li>"); | ||
46 | |||
47 | newLayerDep.data('layer-id', currentLayerDepSelection.id); | ||
48 | newLayerDep.children("span").tooltip(); | ||
49 | |||
50 | var link = newLayerDep.children("a"); | ||
51 | link.attr("href", ctx.layerDetailsUrl+String(currentLayerDepSelection.id)); | ||
52 | link.text(currentLayerDepSelection.name); | ||
53 | link.tooltip({title: currentLayerDepSelection.tooltip, placement: "right"}); | ||
54 | |||
55 | var trashItem = newLayerDep.children("span"); | ||
56 | trashItem.click(function () { | ||
57 | var toRemove = $(this).parent().data('layer-id'); | ||
58 | delete layerDeps[toRemove]; | ||
59 | $(this).parent().fadeOut(function (){ | ||
60 | $(this).remove(); | ||
61 | }); | ||
62 | }); | ||
63 | |||
64 | $("#layer-deps-list").append(newLayerDep); | ||
65 | |||
66 | libtoaster.getLayerDepsForProject(ctx.xhrDataTypeaheadUrl, ctx.projectId, currentLayerDepSelection.id, function (data){ | ||
67 | /* These are the dependencies of the layer added as a dependency */ | ||
68 | if (data.list.length > 0) { | ||
69 | currentLayerDepSelection.url = ctx.layerDetailsUrl+currentLayerDepSelection.id; | ||
70 | layerDeps[currentLayerDepSelection.id].deps = data.list | ||
71 | } | ||
72 | |||
73 | /* Clear the current selection */ | ||
74 | layerDepInput.val(""); | ||
75 | currentLayerDepSelection = undefined; | ||
76 | layerDepBtn.attr("disabled","disabled"); | ||
77 | }, null); | ||
78 | }); | ||
79 | |||
80 | importAndAddBtn.click(function(){ | ||
81 | /* arrray of all layer dep ids includes parent and child deps */ | ||
82 | var allDeps = []; | ||
83 | /* temporary object to use to do a reduce on the dependencies for each | ||
84 | * layer dependency added | ||
85 | */ | ||
86 | var depDeps = {}; | ||
87 | |||
88 | /* the layers that have dependencies have an extra property "deps" | ||
89 | * look in this for each layer and reduce this to a unquie object | ||
90 | * of deps. | ||
91 | */ | ||
92 | for (var key in layerDeps){ | ||
93 | if (layerDeps[key].hasOwnProperty('deps')){ | ||
94 | for (var dep in layerDeps[key].deps){ | ||
95 | var layer = layerDeps[key].deps[dep]; | ||
96 | depDeps[layer.id] = layer; | ||
97 | } | ||
98 | } | ||
99 | allDeps.push(layerDeps[key].id); | ||
100 | } | ||
101 | |||
102 | /* we actually want it as an array so convert it now */ | ||
103 | var depDepsArray = []; | ||
104 | for (var key in depDeps) | ||
105 | depDepsArray.push (depDeps[key]); | ||
106 | |||
107 | if (depDepsArray.length > 0) { | ||
108 | var layer = { name: layerNameInput.val(), url: "#", id: -1 }; | ||
109 | show_layer_deps_modal(ctx.projectId, layer, depDepsArray, function(selected){ | ||
110 | /* Add the accepted dependencies to the allDeps array */ | ||
111 | if (selected.length > 0){ | ||
112 | allDeps.concat (selected); | ||
113 | } | ||
114 | import_and_add (); | ||
115 | }); | ||
116 | } else { | ||
117 | import_and_add (); | ||
118 | } | ||
119 | |||
120 | function import_and_add () { | ||
121 | /* convert to a csv of all the deps to be added */ | ||
122 | var layerDepsCsv = allDeps.join(","); | ||
123 | |||
124 | var layerData = { | ||
125 | name: layerNameInput.val(), | ||
126 | vcs_url: vcsURLInput.val(), | ||
127 | git_ref: gitRefInput.val(), | ||
128 | summary: $("#layer-summary").val(), | ||
129 | dir_path: $("#layer-subdir").val(), | ||
130 | project_id: ctx.projectId, | ||
131 | layer_deps: layerDepsCsv, | ||
132 | }; | ||
133 | |||
134 | $.ajax({ | ||
135 | type: "POST", | ||
136 | url: ctx.xhrImportLayerUrl, | ||
137 | data: layerData, | ||
138 | headers: { 'X-CSRFToken' : $.cookie('csrftoken')}, | ||
139 | success: function (data) { | ||
140 | if (data.error != "ok") { | ||
141 | show_error_message(data, layerData); | ||
142 | console.log(data.error); | ||
143 | } else { | ||
144 | /* Success layer import now go to the project page */ | ||
145 | window.location.replace(ctx.projectPageUrl+'#/layerimported='+layerData.name); | ||
146 | } | ||
147 | }, | ||
148 | error: function (data) { | ||
149 | console.log("Call failed"); | ||
150 | console.log(data); | ||
151 | } | ||
152 | }); | ||
153 | } | ||
154 | }); | ||
155 | |||
156 | function show_error_message(error, layerData) { | ||
157 | |||
158 | var errorMsg = $("#import-error").fadeIn(); | ||
159 | var errorType = error.error; | ||
160 | var body = errorMsg.children("span"); | ||
161 | var title = errorMsg.children("h3"); | ||
162 | var optionsList = errorMsg.children("ul"); | ||
163 | var invalidLayerRevision = $("#invalid-layer-revision-hint"); | ||
164 | var layerRevisionCtrl = $("#layer-revision-ctrl"); | ||
165 | |||
166 | /* remove any existing items */ | ||
167 | optionsList.children().each(function(){ $(this).remove(); }); | ||
168 | body.text(""); | ||
169 | title.text(""); | ||
170 | invalidLayerRevision.hide(); | ||
171 | layerNameCtrl.removeClass("error"); | ||
172 | layerRevisionCtrl.removeClass("error"); | ||
173 | |||
174 | switch (errorType){ | ||
175 | case 'hint-layer-version-exists': | ||
176 | title.text("This layer already exists"); | ||
177 | body.html("A layer <strong>"+layerData.name+"</strong> already exists with this Git repository URL and this revision. You can:"); | ||
178 | optionsList.append("<li>Import <strong>"+layerData.name+"</strong> with a different revision </li>"); | ||
179 | optionsList.append("<li>or <a href=\""+ctx.layerDetailsUrl+error.existing_layer_version+"/\" >change the revision of the existing layer</a></li>"); | ||
180 | |||
181 | layerRevisionCtrl.addClass("error"); | ||
182 | |||
183 | invalidLayerRevision.html("A layer <strong>"+layerData.name+"</strong> already exists with this revision.<br />You can import <strong>"+layerData.name+"</strong> with a different revision"); | ||
184 | invalidLayerRevision.show(); | ||
185 | break; | ||
186 | |||
187 | case 'hint-layer-exists-with-different-url': | ||
188 | title.text("This layer already exists"); | ||
189 | body.html("A layer <strong>"+layerData.name+"</strong> already exists with a different Git repository URL:<br /><br />"+error.current_url+"<br /><br />You Can:"); | ||
190 | optionsList.append("<li>Import the layer under a different name</li>"); | ||
191 | optionsList.append("<li>or <a href=\""+ctx.layerDetailsUrl+error.current_id+"/\" >change the Git repository URL of the existing layer</a></li>"); | ||
192 | duplicatedLayerName.html("A layer <strong>"+layerData.name+"</strong> already exists with a different Git repository URL.<br />To import this layer give it a different name."); | ||
193 | duplicatedLayerName.show(); | ||
194 | layerNameCtrl.addClass("error"); | ||
195 | break; | ||
196 | |||
197 | case 'hint-layer-exists': | ||
198 | title.text("This layer already exists"); | ||
199 | body.html("A layer <strong>"+layerData.name+"</strong> already exists: You Can:"); | ||
200 | optionsList.append("<li>Import the layer under a different name</li>"); | ||
201 | break; | ||
202 | default: | ||
203 | title.text("Error") | ||
204 | body.text(data.error); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | function enable_import_btn (enabled) { | ||
209 | var importAndAddHint = $("#import-and-add-hint"); | ||
210 | |||
211 | if (enabled) { | ||
212 | importAndAddBtn.removeAttr("disabled"); | ||
213 | importAndAddHint.hide(); | ||
214 | return; | ||
215 | } | ||
216 | |||
217 | importAndAddBtn.attr("disabled", "disabled"); | ||
218 | importAndAddHint.show(); | ||
219 | } | ||
220 | |||
221 | function check_form() { | ||
222 | var valid = false; | ||
223 | var inputs = $("input:required"); | ||
224 | |||
225 | for (var i=0; i<inputs.length; i++){ | ||
226 | if (!(valid = inputs[i].value)){ | ||
227 | enable_import_btn(false); | ||
228 | break; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | if (valid) | ||
233 | enable_import_btn(true); | ||
234 | } | ||
235 | |||
236 | vcsURLInput.keyup(function() { | ||
237 | check_form(); | ||
238 | }); | ||
239 | |||
240 | gitRefInput.keyup(function() { | ||
241 | check_form(); | ||
242 | }); | ||
243 | |||
244 | layerNameInput.keyup(function() { | ||
245 | if ($(this).val() && !validLayerName.test($(this).val())){ | ||
246 | layerNameCtrl.addClass("error") | ||
247 | $("#invalid-layer-name-hint").show(); | ||
248 | enable_import_btn(false); | ||
249 | return; | ||
250 | } | ||
251 | |||
252 | /* Don't remove the error class if we're displaying the error for another | ||
253 | * reason. | ||
254 | */ | ||
255 | if (!duplicatedLayerName.is(":visible")) | ||
256 | layerNameCtrl.removeClass("error") | ||
257 | |||
258 | $("#invalid-layer-name-hint").hide(); | ||
259 | check_form(); | ||
260 | }); | ||
261 | |||
262 | /* Have a guess at the layer name */ | ||
263 | vcsURLInput.focusout(function (){ | ||
264 | /* If we a layer name specified don't overwrite it or if there isn't a | ||
265 | * url typed in yet return | ||
266 | */ | ||
267 | if (layerNameInput.val() || !$(this).val()) | ||
268 | return; | ||
269 | |||
270 | if ($(this).val().search("/")){ | ||
271 | var urlPts = $(this).val().split("/"); | ||
272 | var suggestion = urlPts[urlPts.length-1].replace(".git",""); | ||
273 | layerNameInput.val(suggestion); | ||
274 | } | ||
275 | }); | ||
276 | |||
277 | } | ||