LP#1694577 Reports template searching and paging
[Evergreen.git] / Open-ILS / web / reports / oils_rpt_folders.js
1 dojo.requireLocalization("openils.reports", "reports");
2
3 var rpt_strings = dojo.i18n.getLocalization("openils.reports", "reports");
4
5 var oilsRptFolderNodeCache = {};
6 oilsRptFolderNodeCache.template = {};
7 oilsRptFolderNodeCache.report  = {};
8 oilsRptFolderNodeCache.output  = {};
9 // ephemeral template search results folder needs an ID.
10 var oilsRptSearchResultFolderId = -1000; 
11 var oilsRptSearchResultFolderWindowId = null;
12
13 oilsRptSetSubClass('oilsRptFolderManager','oilsRptObject');
14
15 function oilsRptFolderManager() { this.init(); }
16
17 oilsRptFolderManager.prototype.draw = function(auth) {
18
19         if(!auth) auth = SESSION;
20
21         this.folderTree = {};
22         this.tId = oilsNextId();
23         this.rId = oilsNextId();
24         this.oId = oilsNextId();
25         this.stId = oilsNextId();
26         this.srId = oilsNextId();
27         this.soId = oilsNextId();
28
29         this.ownerFolders = {};
30         this.ownerFolders.template = {};
31         this.ownerFolders.report = {};
32         this.ownerFolders.output = {};
33
34         removeChildren(DOM.oils_rpt_template_folder_tree); 
35         removeChildren(DOM.oils_rpt_report_folder_tree); 
36         removeChildren(DOM.oils_rpt_output_folder_tree); 
37         removeChildren(DOM.oils_rpt_template_shared_folder_tree); 
38         removeChildren(DOM.oils_rpt_report_shared_folder_tree); 
39         removeChildren(DOM.oils_rpt_output_shared_folder_tree); 
40
41         var porg = PERMS.SHARE_REPORT_FOLDER;
42         if( porg < 1 ) 
43                 DOM.oils_rpt_top_folder_shared.disabled = true;
44
45         var obj = this;
46         var orgsel = new oilsRptMyOrgsWidget(
47                 DOM.oils_rpt_top_folder_lib_picker, USER.ws_ou(), porg)
48         orgsel.draw();
49
50         oilsRptTemplateFolderTree = 
51                 new SlimTree(
52                         DOM.oils_rpt_template_folder_tree, 
53                         'oilsRptTemplateFolderTree');
54                         //'images/template-page.gif');
55
56         oilsRptTemplateFolderTree.addNode(this.tId, -1, rpt_strings.FOLDERS_TEMPLATES,
57                 function() {
58                         unHideMe(DOM.oils_rpt_folder_table_alt_td);
59                         unHideMe(DOM.oils_rpt_top_folder);
60                         hideMe(DOM.oils_rpt_editor_div);
61                         appendClear(DOM.oils_rpt_top_folder_type,text(rpt_strings.FOLDERS_TEMPLATE));
62                         hideMe(DOM.oils_rpt_folder_table_right_td);
63                         DOM.oils_rpt_top_folder_create.onclick = function() {
64                                 obj.createTopFolder('template', orgsel);
65                         }
66                 }
67         );
68
69         oilsRptReportFolderTree = 
70                 new SlimTree(
71                         DOM.oils_rpt_report_folder_tree, 
72                         'oilsRptReportFolderTree');
73                         //'images/report-page.gif');
74
75
76         oilsRptReportFolderTree.addNode(this.rId, -1, rpt_strings.FOLDERS_REPORTS,
77                 function() {
78                         unHideMe(DOM.oils_rpt_folder_table_alt_td);
79                         unHideMe(DOM.oils_rpt_top_folder);
80                         hideMe(DOM.oils_rpt_editor_div);
81                         hideMe(DOM.oils_rpt_folder_table_right_td);
82                         appendClear(DOM.oils_rpt_top_folder_type,text(rpt_strings.FOLDERS_REPORT));
83                         DOM.oils_rpt_top_folder_create.onclick = function() {
84                                 obj.createTopFolder('report', orgsel);
85                         }
86                 }
87         );
88
89
90
91         oilsRptOutputFolderTree = 
92                 new SlimTree(
93                         DOM.oils_rpt_output_folder_tree, 
94                         'oilsRptOutputFolderTree');
95                         //'images/output-page.gif');
96
97         oilsRptOutputFolderTree.addNode(this.oId, -1, rpt_strings.FOLDERS_OUTPUT,
98                 function() {
99                         unHideMe(DOM.oils_rpt_folder_table_alt_td);
100                         unHideMe(DOM.oils_rpt_top_folder);
101                         hideMe(DOM.oils_rpt_editor_div);
102                         hideMe(DOM.oils_rpt_folder_table_right_td);
103                         appendClear(DOM.oils_rpt_top_folder_type,text(rpt_strings.FOLDERS_OUTPUT));
104                         DOM.oils_rpt_top_folder_create.onclick = function() {
105                                 obj.createTopFolder('output', orgsel);
106                         }
107                 }
108         );
109
110
111         oilsRptSharedTemplateFolderTree = 
112                 new SlimTree(
113                         DOM.oils_rpt_template_shared_folder_tree, 
114                         'oilsRptSharedTemplateFolderTree');
115                         //'images/template-page.gif');
116
117         oilsRptSharedTemplateFolderTree.addNode(this.stId, -1, rpt_strings.FOLDERS_TEMPLATES)
118
119
120         oilsRptSharedReportFolderTree = 
121                 new SlimTree(
122                         DOM.oils_rpt_report_shared_folder_tree, 
123                         'oilsRptSharedReportFolderTree');
124                         //'images/report-page.gif');
125
126         oilsRptSharedReportFolderTree.addNode(this.srId, -1, rpt_strings.FOLDERS_REPORTS)
127
128         oilsRptSharedOutputFolderTree = 
129                 new SlimTree(
130                         DOM.oils_rpt_output_shared_folder_tree, 
131                         'oilsRptSharedOutputFolderTree');
132                         //'images/output-page.gif');
133
134         oilsRptSharedOutputFolderTree.addNode(this.soId, -1, rpt_strings.FOLDERS_OUTPUT)
135
136     DOM.template_search_submit_button.onclick = function() {
137         oilsRptObject.find(oilsRptSearchResultFolderWindowId).draw();
138     }
139
140         this.fetchFolders(auth);
141 }
142
143 oilsRptFolderManager.prototype.createTopFolder = function(type, orgsel) {
144
145         if( type == 'report' ) folder = new rrf();
146         if( type == 'template' ) folder = new rtf();
147         if( type == 'output' ) folder = new rof();
148
149         folder.owner(USER.id());
150         folder.parent(null);
151
152         /* Protect against empty folder names */
153         if (!DOM.oils_rpt_top_folder_name.value) {
154                 return;
155         }
156
157         folder.name(DOM.oils_rpt_top_folder_name.value);
158         folder.shared(getSelectorVal(DOM.oils_rpt_top_folder_shared));
159
160         if( folder.shared() == 't' )
161                 folder.share_with( orgsel.getValue() );
162
163         oilsRptCreateFolder(folder, type,
164                 function(success) {
165                         if(success) {
166                                 oilsRptAlertSuccess();
167                                 oilsRptCurrentFolderManager.draw();
168                                 hideMe(DOM.oils_rpt_top_folder);
169                                 hideMe(DOM.oils_rpt_folder_table_alt_td);
170                                 unHideMe(DOM.oils_rpt_editor_div);
171                         }
172                 }
173         );
174 }
175
176
177 oilsRptFolderManager.prototype.fetchFolders = function(auth) {
178         var obj = this;
179         if(PERMS.RUN_REPORTS != -1) {
180                 var req = new Request(OILS_RPT_FETCH_FOLDERS, auth, 'template');
181                 req.callback( function(r) { obj.drawFolders('template', r.getResultObject()); } );
182                 req.send();
183
184                 var req = new Request(OILS_RPT_FETCH_FOLDERS, auth, 'report');
185                 req.callback( function(r) { obj.drawFolders('report', r.getResultObject()); } );
186                 req.send();
187         }
188
189         var req = new Request(OILS_RPT_FETCH_FOLDERS, auth, 'output');
190         req.callback( function(r) { obj.drawFolders('output', r.getResultObject()); } );
191         req.send();
192 }
193
194
195 oilsRptFolderManager.prototype.drawFolders = function(type, folders) {
196
197         var tree;
198         var owners = {};
199
200     // Special search results folders ; not added to folder tree.
201     if (type == 'template') {
202         var resFolder = new rtf();
203         resFolder.id(oilsRptSearchResultFolderId);
204         resFolder.name(''); // not shown
205         resFolder.owner(USER);
206         folders.unshift(resFolder);
207     }
208
209         for( var i = 0; i < folders.length; i++ ) {
210
211                 var folder = folders[i];
212                 var id = oilsNextId();
213                 var node = { folder : folder, treeId : id };
214
215                 oilsRptFolderNodeCache[type][folder.id()] = node;
216                 node.folderWindow = new oilsRptFolderWindow(type, folder.id())
217
218         if (folder.id() == oilsRptSearchResultFolderId) 
219             oilsRptSearchResultFolderWindowId = node.folderWindow.id;
220
221                 /*
222                 _debug("creating folder node for "+folder.name()+" : id = "+
223                         folder.id()+' treeId = '+id + ' window id = ' + node.folderWindow.id);
224                         */
225
226                 /* shared folders get a folder for the usrname of the 
227                         owner as the parent node for the folders in the tree */
228                 if(!folder.parent() && folder.owner().id() != USER.id()) {
229                         if(owners[folder.owner().id()]) {
230                                 node.ownerNode = owners[folder.owner().id()];
231                                 continue;
232                         }
233
234                         _debug("building usrname node "+type+" -> " +folder.owner().usrname());
235
236                         var id = oilsNextId();
237                         var pid = this.stId;
238                         var tree = oilsRptSharedTemplateFolderTree;
239                         var treename = 'oilsRptSharedTemplateFolderTree';
240
241                         if(type=='report') {
242                                 tree = oilsRptSharedReportFolderTree;
243                                 treename = 'oilsRptSharedReportFolderTree';
244                                 pid = this.srId;
245                         }
246
247                         if(type=='output') {
248                                 tree = oilsRptSharedOutputFolderTree;
249                                 treename = 'oilsRptSharedOutputFolderTree';
250                                 pid = this.soId;
251                         }
252
253                         tree.addNode(id, pid, folder.owner().usrname());
254                         tree.close(pid);
255                         owners[folder.owner().id()] = id;
256                         node.ownerNode = id;
257                 }
258         }
259
260     var search_folders = [];
261         for( var i = 0; i < folders.length; i++ ) {
262
263                 var folder = folders[i];
264                 var mine = (folder.owner().id() == USER.id());
265                 var pid;
266                 var treename;
267
268                 switch(type) {
269                         case 'template': 
270                                 if(mine) {
271                                         tree = oilsRptTemplateFolderTree;
272                                         treename = 'oilsRptTemplateFolderTree';
273                                         pid = this.tId;
274                                 } else {
275                                         tree = oilsRptSharedTemplateFolderTree;
276                                         treename = 'oilsRptSharedTemplateFolderTree';
277                                         pid = this.stId;
278                                 }
279                                 break;
280                         case 'report': 
281                                 if(mine) {
282                                         tree = oilsRptTemplateFolderTree;
283                                         treename = 'oilsRptTemplateFolderTree';
284                                         pid = this.rId;
285                                 } else {
286                                         tree = oilsRptSharedTemplateFolderTree;
287                                         treename = 'oilsRptSharedTemplateFolderTree';
288                                         pid = this.srId;
289                                 }
290                                 break;
291                         case 'output': 
292                                 if(mine) {
293                                         tree = oilsRptTemplateFolderTree;
294                                         treename = 'oilsRptTemplateFolderTree';
295                                         pid = this.oId;
296                                 } else {
297                                         tree = oilsRptSharedTemplateFolderTree;
298                                         treename = 'oilsRptSharedTemplateFolderTree';
299                                         pid = this.soId;
300                                 }
301                 }
302
303                 node = this.findNode(type, folder.id());
304                 id = node.treeId;
305                 if( folder.parent() ) {
306             var pnode = this.findNode(type, folder.parent());
307                         pid = pnode.treeId;
308             node.depth = pnode.depth + 1;
309         } else {
310             node.depth = 0;
311         }
312
313                 var fname = folder.name();
314
315                 if(!mine) {
316                         fname = folder.name() + ' ('+folder.share_with().shortname()+')';
317                         if( node.ownerNode ) pid = node.ownerNode;
318
319                 } else {
320                         if(isTrue(folder.shared()))
321                                 fname = folder.name() + ' ('+folder.share_with().shortname()+')';
322                 }
323
324                 var action = 'javascript:oilsRptObject.find('+node.folderWindow.id+').draw();';
325
326                 /*
327                 _debug('adding node '+fname+' id = ' + id + ' pid = '
328                         +pid + ' parent = ' + folder.parent() + ' folder-window = ' + node.folderWindow.id );
329                         */
330
331         if (folder.id() != oilsRptSearchResultFolderId) {
332             search_folders.push({id : folder.id(), pid: folder.parent(), fname : fname, depth : node.depth});
333                     tree.addNode(id, pid, fname, action);
334                     tree.close(pid);
335         }
336         }
337
338     // search only applies to templates
339     if (type != 'template') return;
340
341     // Sort the list of search folders from top to bottom of the folder tree.
342     var depth_cache = {};
343     function add_folder(node) {
344         if (!node) return;
345
346         var label = node.fname;
347         // Left-pad the selector options by depth with U+2003 'EM SPACE'
348         // characters so the browser won't collapse the space.
349         for (var i = 0; i < node.depth; i++) label = ' ' + label;
350
351         insertSelectorVal(
352             DOM.template_search_folder_selector, -1, label, node.id);
353
354         var children = search_folders.filter(
355             function(f) { return (f.pid == node.id) });
356         dojo.forEach(children, add_folder);
357     }
358
359     // start with the parent-less folders
360     dojo.forEach(
361         search_folders.filter(
362             function(f) {return f.pid == null}), add_folder);
363 }
364
365
366 oilsRptFolderManager.prototype.findNode = function(type, id) {
367         return oilsRptFolderNodeCache[type][id];
368 }
369
370
371
372
373
374
375 /* this only works if the initial folder tree has been drawn 
376         if defined, "action" must be a function pointer that takes the
377         folder node as the param 
378
379     eachFolder - optional callback called with each folder
380     node after its added to the folder list.
381 */
382 var __someid;
383 function oilsRptBuildFolder(type, node, treeVar, rootName, action, shared, eachFolder) {
384         removeChildren(node);
385         var tree = new SlimTree(node, treeVar);
386         this.treeId = oilsNextId();
387         tree.addNode(this.treeId, -1, rootName);
388
389         __someid = oilsNextId();
390
391         var cache = oilsRptFolderNodeCache[type];
392
393         for( var c in cache ) {
394                 var tid = cache[c].treeId + __someid;
395                 var pid = this.treeId;
396                 var f = cache[c].folder;
397
398                 if( !shared && (f.owner().id() != USER.id()) ) continue;
399
400                 if(f.parent()) {
401                         /* find the parent's tree id so we can latch on to it */
402                         var pnode = cache[f.parent()];
403                         var pid = pnode.treeId + __someid;
404                 }
405
406                 tree.addNode(tid, pid, f.name(), __setFolderCB(tree, tid, action, cache[c]));
407
408         if (eachFolder) eachFolder(cache[c]);
409         }
410         eval(treeVar +' = tree;');
411 }
412
413 function __setFolderCB(tree, id, action, node) {
414         var act;
415         if( action ) 
416                 act = function() { action( node ); };
417         return act;
418 }
419