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