[CCSDK-683] fixed dg import from local git repo
[ccsdk/distribution.git] / dgbuilder / public / red / ui / library.js
1 /**
2  * Copyright 2013 IBM Corp.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  **/
16 RED.library = (function() {
17     
18     
19     function loadFlowLibrary() {
20         $.getJSON("library/flows",function(data) {
21             //console.log(data);
22
23             var buildMenu = function(data,root) {
24                 var i;
25                 var li;
26                 var a;
27                 var ul = document.createElement("ul");
28                 ul.id = "btn-import-library-submenu";
29                 ul.className = "dropdown-menu";
30                 if (data.d) {
31                     for (i in data.d) {
32                         if (data.d.hasOwnProperty(i)) {
33                             li = document.createElement("li");
34                             li.className = "dropdown-submenu pull-left";
35                             a = document.createElement("a");
36                             a.href="#";
37                             a.innerHTML = i;
38                             li.appendChild(a);
39                             li.appendChild(buildMenu(data.d[i],root+(root!==""?"/":"")+i));
40                             ul.appendChild(li);
41                         }
42                     }
43                 }
44                 if (data.f) {
45                     for (i in data.f) {
46                         if (data.f.hasOwnProperty(i)) {
47                             li = document.createElement("li");
48                             a = document.createElement("a");
49                             a.href="#";
50                             a.innerHTML = data.f[i];
51                             a.flowName = root+(root!==""?"/":"")+data.f[i];
52                             a.onclick = function() {
53                                 $.get('library/flows/'+this.flowName, function(data) {
54                                         var nodeSet = getCurrentFlowNodeSet();
55                                         //console.dir(nodeSet);
56                                         if(nodeSet != null && nodeSet.length == 0){
57                                                 RED.view.setIsImportAction(true);
58                                         }
59                                         RED.view.importNodes(data);
60                                 });
61                             };
62                             li.appendChild(a);
63                             ul.appendChild(li);
64                         }
65                     }
66                 }
67                 return ul;
68             };
69             var menu = buildMenu(data,"");
70             //TODO: need an api in RED.menu for this
71             $("#btn-import-library-submenu").replaceWith(menu);
72         });
73     }
74     loadFlowLibrary();
75
76
77     
78     function createUI(options) {
79         var libraryData = {};
80         var selectedLibraryItem = null;
81         var libraryEditor = null;
82        // Orion editor has set/getText
83         // ACE editor has set/getValue
84         // normalise to set/getValue
85         if (options.editor.setText) {
86             // Orion doesn't like having pos passed in, so proxy the call to drop it
87             options.editor.setValue = function(text,pos) {
88                 options.editor.setText.call(options.editor,text);
89             }
90         }
91         if (options.editor.getText) {
92             options.editor.getValue = options.editor.getText;
93         }
94  
95         function buildFileListItem(item) {
96             var li = document.createElement("li");
97             li.onmouseover = function(e) { $(this).addClass("list-hover"); };
98             li.onmouseout = function(e) { $(this).removeClass("list-hover"); };
99             return li;
100         }
101         
102         function buildFileList(root,data) {
103             var ul = document.createElement("ul");
104             var li;
105             for (var i=0;i<data.length;i++) {
106                 var v = data[i];
107                 if (typeof v === "string") {
108                     // directory
109                     li = buildFileListItem(v);
110                     li.onclick = (function () {
111                         var dirName = v;
112                         return function(e) {
113                             var bcli = $('<li class="active"><span class="divider">/</span> <a href="#">'+dirName+'</a></li>');
114                             $("a",bcli).click(function(e) { 
115                                 $(this).parent().nextAll().remove();
116                                 $.getJSON("library/"+options.url+root+dirName,function(data) {
117                                     $("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data));
118                                 });
119                                 e.stopPropagation();
120                             });
121                             var bc = $("#node-dialog-library-breadcrumbs");
122                             $(".active",bc).removeClass("active");
123                             bc.append(bcli);
124                             $.getJSON("library/"+options.url+root+dirName,function(data) {
125                                     $("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data));
126                             });
127                         }
128                     })();
129                     li.innerHTML = '<i class="fa fa-folder"></i> '+v+"</i>";
130                     ul.appendChild(li);
131                 } else {
132                     // file
133                    li = buildFileListItem(v);
134                    li.innerHTML = v.name;
135                    li.onclick = (function() {
136                        var item = v;
137                        return function(e) {
138                            $(".list-selected",ul).removeClass("list-selected");
139                            $(this).addClass("list-selected");
140                            $.get("library/"+options.url+root+item.fn, function(data) {
141                                    selectedLibraryItem = item;
142                                    libraryEditor.setText(data);
143                            });
144                        }
145                    })();
146                    ul.appendChild(li);
147                 }
148             }
149             return ul;
150         }
151     
152 /*
153 //Commented this portion as is not used by the DGBuilder application
154         $('#node-input-name').addClass('input-append-left').css("width","65%").after(
155             '<div class="btn-group" style="margin-left: 0px;">'+
156             '<button id="node-input-'+options.type+'-lookup" class="btn input-append-right" data-toggle="dropdown"><i class="fa fa-book"></i> <i class="fa fa-caret-down"></i></button>'+
157             '<ul class="dropdown-menu pull-right" role="menu">'+
158             '<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">Open Library...</a></li>'+
159             '<li><a id="node-input-'+options.type+'-menu-save-library" tabindex="-1" href="#">Save to Library...</a></li>'+
160             '</ul></div>'
161         );
162     
163         
164         
165         $('#node-input-'+options.type+'-menu-open-library').click(function(e) {
166             $("#node-select-library").children().remove();
167             var bc = $("#node-dialog-library-breadcrumbs");
168             bc.children().first().nextAll().remove();
169             libraryEditor.setText('');
170             
171             $.getJSON("library/"+options.url,function(data) {
172                 $("#node-select-library").append(buildFileList("/",data));
173                 $("#node-dialog-library-breadcrumbs a").click(function(e) {
174                     $(this).parent().nextAll().remove();
175                     $("#node-select-library").children().first().replaceWith(buildFileList("/",data));
176                     e.stopPropagation();
177                 });
178                 $( "#node-dialog-library-lookup" ).dialog( "open" );
179             });
180             
181             e.preventDefault();
182         });
183     
184         $('#node-input-'+options.type+'-menu-save-library').click(function(e) {
185             //var found = false;
186             var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
187
188             //var buildPathList = function(data,root) {
189             //    var paths = [];
190             //    if (data.d) {
191             //        for (var i in data.d) {
192             //            var dn = root+(root==""?"":"/")+i;
193             //            var d = {
194             //                label:dn,
195             //                files:[]
196             //            };
197             //            for (var f in data.d[i].f) {
198             //                d.files.push(data.d[i].f[f].fn.split("/").slice(-1)[0]);
199             //            }
200             //            paths.push(d);
201             //            paths = paths.concat(buildPathList(data.d[i],root+(root==""?"":"/")+i));
202             //        }
203             //    }
204             //    return paths;
205             //};
206             $("#node-dialog-library-save-folder").attr("value","");
207
208             var filename = name.replace(/[^\w-]/g,"-");
209             if (filename === "") {
210                 filename = "unnamed-"+options.type;
211             }
212             $("#node-dialog-library-save-filename").attr("value",filename+".js");
213
214             //var paths = buildPathList(libraryData,"");
215             //$("#node-dialog-library-save-folder").autocomplete({
216             //        minLength: 0,
217             //        source: paths,
218             //        select: function( event, ui ) {
219             //            $("#node-dialog-library-save-filename").autocomplete({
220             //                    minLength: 0,
221             //                    source: ui.item.files
222             //            });
223             //        }
224             //});
225
226             $( "#node-dialog-library-save" ).dialog( "open" );
227             e.preventDefault();
228         });
229         require(["orion/editor/edit"], function(edit) {
230             libraryEditor = edit({
231                 parent:document.getElementById('node-select-library-text'),
232                 lang:"js",
233                 readonly: true
234             });
235         });
236     
237         
238         $( "#node-dialog-library-lookup" ).dialog({
239             title: options.type+" library",
240             modal: true,
241             autoOpen: false,
242             width: 800,
243             height: 450,
244             buttons: [
245                 {
246                     text: "Ok",
247                     click: function() {
248                         if (selectedLibraryItem) {
249                             for (var i=0;i<options.fields.length;i++) {
250                                 var field = options.fields[i];
251                                 $("#node-input-"+field).val(selectedLibraryItem[field]);
252                             }
253                             options.editor.setText(libraryEditor.getText());
254                         }
255                         $( this ).dialog( "close" );
256                     }
257                 },
258                 {
259                     text: "Cancel",
260                     click: function() {
261                         $( this ).dialog( "close" );
262                     }
263                 }
264             ],
265             open: function(e) {
266                 var form = $("form",this);
267                 form.height(form.parent().height()-30);
268                 $("#node-select-library-text").height("100%");
269                 $(".form-row:last-child",form).children().height(form.height()-60);
270             },
271             resize: function(e) {
272                 var form = $("form",this);
273                 form.height(form.parent().height()-30);
274                 $(".form-row:last-child",form).children().height(form.height()-60);
275             }
276         });
277         
278    */ 
279         function saveToLibrary(overwrite) {
280             var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,"");
281             if (name === "") {
282                 name = "Unnamed "+options.type;
283             }
284             var filename = $("#node-dialog-library-save-filename").val().replace(/(^\s*)|(\s*$)/g,"");
285             var pathname = $("#node-dialog-library-save-folder").val().replace(/(^\s*)|(\s*$)/g,"");
286             if (filename === "" || !/.+\.js$/.test(filename)) {
287                 RED.notify("Invalid filename","warning");
288                 return;
289             }
290             var fullpath = pathname+(pathname===""?"":"/")+filename;
291             if (!overwrite) {
292                 //var pathnameParts = pathname.split("/");
293                 //var exists = false;
294                 //var ds = libraryData;
295                 //for (var pnp in pathnameParts) {
296                 //    if (ds.d && pathnameParts[pnp] in ds.d) {
297                 //        ds = ds.d[pathnameParts[pnp]];
298                 //    } else {
299                 //        ds = null;
300                 //        break;
301                 //    }
302                 //}
303                 //if (ds && ds.f) {
304                 //    for (var f in ds.f) {
305                 //        if (ds.f[f].fn == fullpath) {
306                 //            exists = true;
307                 //            break;
308                 //        }
309                 //    }
310                 //}
311                 //if (exists) {
312                 //    $("#node-dialog-library-save-type").html(options.type);
313                 //    $("#node-dialog-library-save-name").html(fullpath);
314                 //    $("#node-dialog-library-save-confirm").dialog( "open" );
315                 //    return;
316                 //}
317             }
318             var queryArgs = [];
319             for (var i=0;i<options.fields.length;i++) {
320                 var field = options.fields[i];
321                 if (field == "name") {
322                     queryArgs.push("name="+encodeURIComponent(name));
323                 } else {
324                     queryArgs.push(encodeURIComponent(field)+"="+encodeURIComponent($("#node-input-"+field).val()));
325                 }
326             }
327             var queryString = queryArgs.join("&");
328             
329             var text = options.editor.getText();
330             $.post("library/"+options.url+'/'+fullpath+"?"+queryString,text,function() {
331                     RED.notify("Saved "+options.type,"success");
332             });
333         }
334         $( "#node-dialog-library-save-confirm" ).dialog({
335             title: "Save to library",
336             modal: true,
337             autoOpen: false,
338             width: 530,
339             height: 230,
340             buttons: [
341                 {
342                     text: "Ok",
343                     click: function() {
344                         saveToLibrary(true);
345                         $( this ).dialog( "close" );
346                     }
347                 },
348                 {
349                     text: "Cancel",
350                     click: function() {
351                         $( this ).dialog( "close" );
352                     }
353                 }
354             ]
355         });
356         $( "#node-dialog-library-save" ).dialog({
357             title: "Save to library",
358             modal: true,
359             autoOpen: false,
360             width: 530,
361             height: 230,
362             buttons: [
363                 {
364                     text: "Ok",
365                     click: function() {
366                         saveToLibrary(false);
367                         $( this ).dialog( "close" );
368                     }
369                 },
370                 {
371                     text: "Cancel",
372                     click: function() {
373                         $( this ).dialog( "close" );
374                     }
375                 }
376             ]
377         });
378
379     }
380     
381     return {
382         create: createUI,
383         loadFlowLibrary: loadFlowLibrary
384     }
385 })();
386
387