]> git.sur5r.net Git - bacula/bacula/blob - gui/bweb/html/bresto.js
ebl Choose the right pool&level when try to run a job
[bacula/bacula] / gui / bweb / html / bresto.js
1
2 //   Bweb - A Bacula web interface
3 //   Bacula® - The Network Backup Solution
4 //
5 //   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
6 //
7 //   The main author of Bweb is Eric Bollengier.
8 //   The main author of Bacula is Kern Sibbald, with contributions from
9 //   many others, a complete list can be found in the file AUTHORS.
10 //
11 //   This program is Free Software; you can redistribute it and/or
12 //   modify it under the terms of version two of the GNU General Public
13 //   License as published by the Free Software Foundation plus additions
14 //   that are listed in the file LICENSE.
15 //
16 //   This program is distributed in the hope that it will be useful, but
17 //   WITHOUT ANY WARRANTY; without even the implied warranty of
18 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 //   General Public License for more details.
20 //
21 //   You should have received a copy of the GNU General Public License
22 //   along with this program; if not, write to the Free Software
23 //   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 //   02110-1301, USA.
25 //
26 //   Bacula® is a registered trademark of John Walker.
27 //   The licensor of Bacula is the Free Software Foundation Europe
28 //   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
29 //   Switzerland, email:ftf@fsfeurope.org.
30
31 // render if vol is online/offline
32 function rd_vol_is_online(val)
33 {
34    return '<img src="/bweb/inflag' + val + '.png">';
35 }
36
37 // TODO: fichier ou rep
38 function rd_file_or_dir(val)
39 {
40    if (val == 'F') {
41       return '<img src="/bweb/A.png">';
42    } else {
43       return '<img src="/bweb/R.png">';
44    }
45 }
46
47 Ext.namespace('Ext.brestore');
48
49 Ext.brestore.jobid=0;            // selected jobid
50 Ext.brestore.jobdate='';         // selected date
51 Ext.brestore.client='';          // selected client
52 Ext.brestore.path='';            // current path (without user location)
53 Ext.brestore.root_path='';       // user location
54
55 Ext.brestore.option_vosb = false;
56 Ext.brestore.option_vafv = false;
57 Ext.brestore.dlglaunch;
58
59 function get_node_path(node)
60 {
61    var temp='';
62    for (var p = node; p; p = p.parentNode) {
63        if (p.parentNode) {
64           if (p.text == '/') {
65              temp = p.text + temp;
66           } else {
67           temp = p.text + '/' + temp;
68           }
69        }
70    }
71    return Ext.brestore.root_path + temp;
72 }
73
74
75 function init_params(baseParams)
76 {
77    baseParams['client']= Ext.brestore.client;
78
79    if (Ext.brestore.option_vosb) {         
80       baseParams['jobid'] = Ext.brestore.jobid;
81    } else {
82       baseParams['date'] = Ext.brestore.jobdate;
83    }
84    return baseParams;
85 }
86
87
88 function ext_init()
89 {
90 //////////////////////////////////////////////////////////////:
91     var Tree = Ext.tree;
92     var tree_loader = new Ext.tree.TreeLoader({
93             baseParams:{}, 
94             dataUrl:'/cgi-bin/bweb/bresto.pl'
95         });
96
97     var tree = new Ext.tree.TreePanel('div-tree', {
98         animate:true, 
99         loader: tree_loader,
100         enableDD:true,
101         enableDragDrop: true,
102         containerScroll: true
103     });
104
105     // set the root node
106     var root = new Ext.tree.AsyncTreeNode({
107         text: 'Select a job',
108         draggable:false,
109         id:'source'
110     });
111     tree.setRootNode(root);
112
113     // render the tree
114     tree.render();
115 //    root.expand();
116
117     tree.on('click', function(node, event) { 
118         Ext.brestore.path = get_node_path(node);
119
120         file_store.removeAll();
121         file_versions_store.removeAll();
122         file_store.load({params:init_params({action: 'list_files',
123                                              node:node.id})
124                        });
125         return true;
126     });
127
128     tree.on('beforeload', function(e) {
129         file_store.removeAll();
130         return true;
131     });
132
133
134 ////////////////////////////////////////////////////////////////
135
136   var file_store = new Ext.data.Store({
137         proxy: new Ext.data.HttpProxy({
138             url: '/cgi-bin/bweb/bresto.pl',
139             method: 'GET',
140             params:{}
141         }),
142
143         reader: new Ext.data.ArrayReader({
144         }, Ext.data.Record.create([
145    {name: 'fileid'    },
146    {name: 'filenameid'},
147    {name: 'pathid'    },
148    {name: 'name'      },
149    {name: 'size',     type: 'int'  },
150    {name: 'mtime',    type: 'date', dateFormat: 'Y-m-d h:i:s'}
151         ]))
152    });
153
154    var cm = new Ext.grid.ColumnModel([{
155            id:        'name', // id assigned so we can apply custom css (e.g. .x-grid-col-topic b { color:#333 })
156            header:    'File',
157            dataIndex: 'name',
158            width:     100,
159            css:       'white-space:normal;'
160         },{
161            header:    "Size",
162            dataIndex: 'size',
163            renderer:  human_size,
164            width:     50
165         },{
166            header:    "Date",
167            dataIndex: 'mtime',
168            width:     100
169         },{
170            dataIndex: 'pathid',
171            hidden: true
172         },{
173            dataIndex: 'filenameid',
174            hidden: true
175         },{
176            dataIndex: 'fileid',
177            hidden: true
178         }
179         ]);
180
181     // by default columns are sortable
182    cm.defaultSortable = true;
183
184     // create the grid
185    var files_grid = new Ext.grid.Grid('div-files', {
186         ds: file_store,
187         cm: cm,
188         ddGroup : 'TreeDD',
189         enableDrag: true,
190         enableDragDrop: true,
191         selModel: new Ext.grid.RowSelectionModel(),
192         loadMask: true,
193         enableColLock:false
194         
195     });
196
197     // when we reload the view,
198     // we clear the file version box
199     file_store.on('beforeload', function(e) {
200         file_versions_store.removeAll();
201         return true;
202     });
203
204     // TODO: selection only when using dblclick
205     files_grid.selModel.on('rowselect', function(e,i,r) { 
206         Ext.brestore.filename = r.json[3];
207         file_versions_store.load({params:init_params({action: 'list_versions',
208                                                      vafv: Ext.brestore.option_vafv,
209                                                      pathid: r.json[2],
210                                                      filenameid: r.json[1]
211                                                      })
212                                  });
213         return true;
214     });
215     files_grid.render();
216
217 //////////////////////////////////////////////////////////////:
218
219   var file_selection_store = new Ext.data.Store({
220         proxy: new Ext.data.MemoryProxy(),
221
222         reader: new Ext.data.ArrayReader({
223         }, Ext.data.Record.create([
224    {name: 'jobid'     },
225    {name: 'fileid'    },
226    {name: 'filenameid'},
227    {name: 'pathid'    },
228    {name: 'name'      },
229    {name: 'size',     type: 'int'  },
230    {name: 'mtime',    type: 'date', dateFormat: 'Y-m-d h:i:s'}
231         ]))
232    });
233
234    var file_selection_cm = new Ext.grid.ColumnModel([{
235            id:        'name', // id assigned so we can apply custom css (e.g. .x-grid-col-topic b { color:#333 })
236            header:    "Name",
237            dataIndex: 'name',
238            width:     250
239         },{
240            header:    "JobId",
241            width:     50,
242            dataIndex: 'jobid'
243         },{
244            header:    "Size",
245            dataIndex: 'size',
246            renderer:  human_size,
247            width:     50
248         },{
249            header:    "Date",
250            dataIndex: 'mtime',
251            width:     100
252         },{
253            dataIndex: 'pathid',
254            hidden: true
255         },{
256            dataIndex: 'filenameid',
257            hidden: true
258         },{
259            dataIndex: 'fileid',
260            hidden: true
261         }
262         ]);
263
264
265     // create the grid
266    var file_selection_grid = new Ext.grid.Grid('div-file-selection', {
267         cm: file_selection_cm,
268         ds: file_selection_store,
269         ddGroup : 'TreeDD',
270         enableDrag: false,
271         enableDrop: true,
272         selModel: new Ext.grid.RowSelectionModel(),
273         loadMask: true,
274         enableColLock:false
275         
276     });
277
278     var file_selection_record = Ext.data.Record.create(
279       {name: 'jobid'},
280       {name: 'fileid'},
281       {name: 'filenameid'},
282       {name: 'pathid'},
283       {name: 'size'},
284       {name: 'mtime'}
285     );
286 // data.selections[0].json[]
287 // data.node.id
288 // http://extjs.com/forum/showthread.php?t=12582&highlight=drag+drop
289     var ddrow = new Ext.dd.DropTarget(file_selection_grid.container, {
290         ddGroup : 'TreeDD',
291         copy:false,
292         notifyDrop : function(dd, e, data){
293            var r;
294            if (data.selections) {
295              if (data.grid.id == 'div-files') {
296                  for(var i=0;i<data.selections.length;i++) {
297                     r = new file_selection_record({
298                       jobid:     Ext.brestore.jobid,
299                       fileid:    data.selections[i].json[0],
300                       filenameid:data.selections[i].json[1],
301                       pathid:    data.selections[i].json[2],
302                       name: Ext.brestore.path + data.selections[i].json[3],
303                       size:      data.selections[i].json[4],
304                       mtime:     data.selections[i].json[5]
305                     });
306                     file_selection_store.add(r)
307                  }
308              }
309
310              if (data.grid.id == 'div-file-versions') {
311                     r = new file_selection_record({
312                       jobid:     data.selections[0].json[3],
313                       fileid:    data.selections[0].json[0],
314                       filenameid:data.selections[0].json[1],
315                       pathid:    data.selections[0].json[2],
316                       name: Ext.brestore.path + Ext.brestore.filename,
317                       size:      data.selections[0].json[7],
318                       mtime:     data.selections[0].json[8]     
319                     });
320                     file_selection_store.add(r)
321              }
322            }
323   
324            if (data.node) {
325               var path= get_node_path(data.node);
326               r = new file_selection_record({
327                       jobid:     Ext.brestore.jobid,
328                       fileid:    0,
329                       filenameid:0,
330                       pathid:    data.node.id,
331                       name:      path,
332                       size:      4096,
333                       mtime:     0
334               });
335               file_selection_store.add(r)
336            }
337   
338            return true;
339     }});
340
341
342    file_selection_grid.on('enddrag', function(dd,e) { 
343         alert(e) ; return true;
344     });
345    file_selection_grid.on('notifyDrop', function(dd,e) { 
346         alert(e) ; return true;
347     });
348    file_selection_grid.render();
349
350 ///////////////////////////////////////////////////////
351
352   var file_versions_store = new Ext.data.Store({
353         proxy: new Ext.data.HttpProxy({
354             url: '/cgi-bin/bweb/bresto.pl',
355             method: 'GET',
356             params:{offset:0, limit:50 }
357         }),
358
359         reader: new Ext.data.ArrayReader({
360         }, Ext.data.Record.create([
361    {name: 'fileid'    },
362    {name: 'filenameid'},
363    {name: 'pathid'    },
364    {name: 'jobid'     },
365    {name: 'volume'    },
366    {name: 'inchanger' },
367    {name: 'md5'       },
368    {name: 'size',     type: 'int'  },
369    {name: 'mtime'} //,    type: 'date', dateFormat: 'Y-m-d h:i:s'}
370         ]))
371    });
372
373    var file_versions_cm = new Ext.grid.ColumnModel([{
374            id:        'name', // id assigned so we can apply custom css (e.g. .x-grid-col-topic b { color:#333 })
375            dataIndex: 'name',
376            hidden: true
377         },{
378            header:    "InChanger",
379            dataIndex: 'inchanger',
380            width:     60,
381            renderer:  rd_vol_is_online
382         },{
383            header:    "Volume",
384            dataIndex: 'volume'
385         },{
386            header:    "JobId",
387            width:     50,
388            dataIndex: 'jobid'
389         },{
390            header:    "Size",
391            dataIndex: 'size',
392            renderer:  human_size,
393            width:     50
394         },{
395            header:    "Date",
396            dataIndex: 'mtime',
397            width:     100
398         },{
399            header:    "MD5",
400            dataIndex: 'md5',
401            width:     160
402         },{
403            dataIndex: 'pathid',
404            hidden: true
405         },{
406            dataIndex: 'filenameid',
407            hidden: true
408         },{
409            dataIndex: 'fileid',
410            hidden: true
411         }
412    ]);
413
414     // by default columns are sortable
415    file_versions_cm.defaultSortable = true;
416
417     // create the grid
418    var file_versions_grid = new Ext.grid.Grid('div-file-versions', {
419         ds: file_versions_store,
420         cm: file_versions_cm,
421         ddGroup : 'TreeDD',
422         enableDrag: true,
423         enableDrop: false,
424         selModel: new Ext.grid.RowSelectionModel(),
425         loadMask: true,
426         enableColLock:false
427         
428     });
429
430     file_versions_grid.on('rowdblclick', function(e) { 
431         alert(e) ; file_versions_store.removeAll(); return true;
432     });
433     file_versions_grid.render();
434
435 //////////////////////////////////////////////////////////////:
436
437
438     var client_store = new Ext.data.Store({
439         proxy: new Ext.data.HttpProxy({
440             url: '/cgi-bin/bweb/bresto.pl',
441             method: 'GET',
442             params:{action:'list_client'}
443         }),
444
445         reader: new Ext.data.ArrayReader({
446         }, Ext.data.Record.create([
447            {name: 'name' }
448         ]))
449     });
450
451     var client_combo = new Ext.form.ComboBox({
452         fieldLabel: 'Clients',
453         store: client_store,
454         displayField:'name',
455         typeAhead: true,
456         mode: 'local',
457         triggerAction: 'all',
458         emptyText:'Select a client...',
459         selectOnFocus:true,
460         forceSelection: true,
461         width:135
462     });
463
464     client_combo.on('valid', function(e) { 
465         Ext.brestore.client = e.getValue();
466         job_store.load( {params:{action: 'list_job',
467                                  client:Ext.brestore.client}});
468         return true;
469     });
470
471 //////////////////////////////////////////////////////////////:
472
473     var job_store = new Ext.data.Store({
474         proxy: new Ext.data.HttpProxy({
475             url: '/cgi-bin/bweb/bresto.pl',
476             method: 'GET',
477             params:{offset:0, limit:50 }
478         }),
479
480         reader: new Ext.data.ArrayReader({
481         }, Ext.data.Record.create([
482            {name: 'jobid' },
483            {name: 'date'  },
484            {name: 'jobname' }
485         ]))
486     });
487
488     var job_combo = new Ext.form.ComboBox({
489         fieldLabel: 'Jobs',
490         store: job_store,
491         displayField:'jobname',
492         typeAhead: true,
493         mode: 'local',
494         triggerAction: 'all',
495         emptyText:'Select a job...',
496         selectOnFocus:true,
497         forceSelection: true,
498         width:350
499     });
500
501     job_combo.on('select', function(e,c) {
502         Ext.brestore.jobid = c.json[0];
503         Ext.brestore.jobdate = c.json[1];
504         Ext.brestore.root_path='';
505         root.setText("Root");
506         tree_loader.baseParams = init_params({init:1, action: 'list_dirs'});
507         root.reload();
508     });
509
510 ////////////////////////////////////////////////////////////////
511
512     function sel_option(item, check)
513     {
514         if (item.id == 'id_vosb') {
515            Ext.brestore.option_vosb = check;
516         }
517         if (item.id == 'id_vafv') {
518            Ext.brestore.option_vafv = check;
519         }
520     }
521
522     var menu = new Ext.menu.Menu({
523         id: 'div-main-menu',
524         items: [ 
525            new Ext.menu.CheckItem({
526                 id: 'id_vosb',
527                 text: 'View only selected backup',
528                 checked: Ext.brestore.option_vosb,
529                 checkHandler: sel_option
530             }),
531            new Ext.menu.CheckItem({
532                 id: 'id_vafv',
533                 text: 'View all file versions',
534                 checked: Ext.brestore.option_vafv,
535                 checkHandler: sel_option
536             })
537         ]
538     });
539 ////////////////////////////////////////////////////////////////:
540
541     // create the primary toolbar
542     var tb2 = new Ext.Toolbar('div-tb-sel');
543     tb2.add({
544         id:'save',
545         text:'Save',
546         disabled:true,
547 //        handler:save,
548         cls:'x-btn-text-icon save',
549         tooltip:'Saves all components to the server'
550     },'-', {
551         id:'add',
552         text:'Component',
553 //        handler:addComponent,
554         cls:'x-btn-text-icon add-cmp',
555         tooltip:'Add a new Component to the dependency builder'
556     }, {
557         id:'option',
558         text:'Option',
559         disabled:true,
560 //        handler:addOption,
561         cls:'x-btn-text-icon add-opt',
562         tooltip:'Add a new optional dependency to the selected component'
563     },'-',{
564         id:'remove',
565         text:'Remove',
566         disabled:true,
567 //        handler:removeNode,
568         cls:'x-btn-text-icon remove',
569         tooltip:'Remove the selected item'
570     });
571
572     var where_field = new Ext.form.TextField({
573             fieldLabel: 'Location',
574             name: 'where',
575             width:175,
576             allowBlank:false
577     });
578
579     var tb = new Ext.Toolbar('div-toolbar', [
580         client_combo,
581         job_combo,
582         '-',
583         {
584           id: 'tb_home',
585 //        icon: '/bweb/up.gif',
586           text: 'Change location',
587           cls:'x-btn-text-icon',
588           handler: function() { 
589                 var where = where_field.getValue();
590                 Ext.brestore.root_path=where;
591                 root.setText(where);
592                 tree_loader.baseParams = init_params({ action:'list_dirs', path: where });
593                 root.reload();
594           }
595         },
596         where_field,
597         '-',
598         {
599             cls: 'x-btn-text-icon bmenu', // icon and text class
600             text:'Options',
601             menu: menu  // assign menu by instance
602         },
603         {
604             icon: '/bweb/remove.png', // icons can also be specified inline
605             cls: 'x-btn-icon',
606             text: 'restore',
607             handler: function() { 
608                 if (Ext.brestore.dlglaunch) {
609                    Ext.brestore.dlglaunch.show();
610                    return 0;
611                 }
612                 Ext.brestore.dlglaunch = new Ext.LayoutDialog("div-resto-dlg", {
613 //                        modal:true,
614                         width:600,
615                         height:400,
616                         shadow:true,
617                         minWidth:300,
618                         minHeight:300,
619                         proxyDrag: true,
620 //                        west: {
621 //                              split:true,
622 //                              initialSize: 150,
623 //                              minSize: 100,
624 //                              maxSize: 250,
625 //                              titlebar: true,
626 //                              collapsible: true,
627 //                              animate: true
628 //                          },
629                         center: {
630                                 autoScroll:true,
631 //                              tabPosition: 'top',
632 //                              closeOnTab: true,
633 //                              alwaysShowTabs: true
634                         }
635                 });
636                 var dialog = Ext.brestore.dlglaunch;
637                 dialog.addKeyListener(27, dialog.hide, dialog);
638                 dialog.addButton('Submit', dialog.hide, dialog);
639                 dialog.addButton('Close', dialog.hide, dialog);
640
641     var fs = new Ext.form.Form({
642         labelAlign: 'right',
643         labelWidth: 80
644     });
645
646     var storage_store = new Ext.data.Store({
647         proxy: new Ext.data.HttpProxy({
648             url: '/cgi-bin/bweb/bresto.pl',
649             method: 'GET',
650             params:{action:'list_storage'}
651         }),
652
653         reader: new Ext.data.ArrayReader({
654         }, Ext.data.Record.create([
655            {name: 'name' }
656         ]))
657     });
658
659     var resto_store = new Ext.data.Store({
660         proxy: new Ext.data.HttpProxy({
661             url: '/cgi-bin/bweb/bresto.pl',
662             method: 'GET',
663             params:{action:'list_resto'}
664         }),
665
666         reader: new Ext.data.ArrayReader({
667         }, Ext.data.Record.create([
668            {name: 'name' }
669         ]))
670     });
671
672     fs.fieldset(
673         {legend:'Restore job'},
674         new Ext.form.ComboBox({
675             fieldLabel: 'Replace',
676             hiddenName:'replace',
677             store: new Ext.data.SimpleStore({
678                  fields: ['replace'],
679                  data : [['always'],['never'],['if newer']]
680             }),
681             displayField:'replace',
682             typeAhead: true,
683             mode: 'local',
684             triggerAction: 'all',
685             emptyText:'never',
686             selectOnFocus:true,
687             width:190
688         }),
689
690         new Ext.form.ComboBox({
691             fieldLabel: 'job',
692             hiddenName:'job',
693             store: resto_store,
694             displayField:'name',
695             typeAhead: true,
696             mode: 'local',
697             triggerAction: 'all',
698             emptyText:'Select a job...',
699             selectOnFocus:true,
700             width:190
701         })
702         ,
703         new Ext.form.TextField({
704             fieldLabel: 'Where',
705             name: 'where',
706             width:190
707         }),
708
709         new Ext.form.ComboBox({
710             fieldLabel: 'client',
711             hiddenName:'client',
712             store: client_store,
713             displayField:'name',
714             typeAhead: true,
715             mode: 'local',
716             triggerAction: 'all',
717             emptyText:'Select a client...',
718             selectOnFocus:true,
719             width:190
720         }),
721         new Ext.form.ComboBox({
722             fieldLabel: 'storage',
723             hiddenName:'storage',
724             store: storage_store,
725             displayField:'name',
726             typeAhead: true,
727             mode: 'local',
728             triggerAction: 'all',
729             emptyText:'Select a storage...',
730             selectOnFocus:true,
731             width:190
732         })
733     );
734     storage_store.load({params:{action: 'list_storage'}});
735     resto_store.load({params:{action: 'list_resto'}});
736     fs.render('div-resto-form');
737
738 //      var f = new Ext.form.BasicForm('div-resto-form', {url: '/bweb/test', method: 'GET',
739 //                                                      baseParams: {init: 1}
740 //                                                     }
741 //                                     );
742
743                 var layout = dialog.getLayout();
744                 layout.beginUpdate();
745                 layout.add('center', new Ext.ContentPanel('div-resto-form', {
746                                     autoCreate:true, title: 'Third Tab', closable:true, background:true}));
747                 layout.endUpdate();
748                 dialog.show();
749             }
750         }
751     ]);
752
753 ////////////////////////////////////////////////////////////////
754
755     var layout = new Ext.BorderLayout(document.body, {
756         north: {
757 //            split: true
758         },
759         south: {
760             split: true, initialSize: 300
761         },
762         east: {
763             split: true, initialSize: 550
764         },
765         west: {
766             split: true, initialSize: 300
767         },
768         center: {
769             initialSize: 450
770         }        
771         
772     });
773
774 layout.beginUpdate();
775   layout.add('north', new Ext.ContentPanel('div-toolbar', {
776       fitToFrame: true, autoCreate:true,closable: false 
777   }));
778   layout.add('south', new Ext.ContentPanel('div-file-selection', {
779       toolbar: tb2,resizeEl:'div-file-selection',
780       fitToFrame: true, autoCreate:true,closable: false
781   }));
782   layout.add('east', new Ext.ContentPanel('div-file-versions', {
783       fitToFrame: true, autoCreate:true,closable: false
784   }));
785   layout.add('west', new Ext.ContentPanel('div-tree', {
786       autoScroll:true, fitToFrame: true, 
787       autoCreate:true,closable: false
788   }));
789   layout.add('center', new Ext.ContentPanel('div-files', {
790       autoScroll:true,autoCreate:true,fitToFrame: true
791   }));
792 layout.endUpdate();     
793
794
795 ////////////////////////////////////////////////////////////////
796
797 //    job_store.load();
798     client_store.load({params:{action: 'list_client'}});
799 //    file_store.load({params:{offset:0, limit:50}});
800 //    file_versions_store.load({params:{offset:0, limit:50}});
801 //    file_selection_store.load();
802
803 }
804 Ext.onReady( ext_init );