2 // Bweb - A Bacula web interface
3 // Bacula® - The Network Backup Solution
5 // Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
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.
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.
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.
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
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.
31 // render if vol is online/offline
32 function rd_vol_is_online(val)
34 return '<img src="/bweb/inflag' + val + '.png">';
37 // TODO: fichier ou rep
38 function rd_file_or_dir(val)
41 return '<img src="/bweb/A.png">';
43 return '<img src="/bweb/R.png">';
47 Ext.namespace('Ext.brestore');
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
55 Ext.brestore.option_vosb = false;
56 Ext.brestore.option_vafv = false;
57 Ext.brestore.dlglaunch;
59 function get_node_path(node)
62 for (var p = node; p; p = p.parentNode) {
67 temp = p.text + '/' + temp;
71 return Ext.brestore.root_path + temp;
75 function init_params(baseParams)
77 baseParams['client']= Ext.brestore.client;
79 if (Ext.brestore.option_vosb) {
80 baseParams['jobid'] = Ext.brestore.jobid;
82 baseParams['date'] = Ext.brestore.jobdate;
90 //////////////////////////////////////////////////////////////:
92 var tree_loader = new Ext.tree.TreeLoader({
94 dataUrl:'/cgi-bin/bweb/bresto.pl'
97 var tree = new Ext.tree.TreePanel('div-tree', {
101 enableDragDrop: true,
102 containerScroll: true
106 var root = new Ext.tree.AsyncTreeNode({
107 text: 'Select a job',
111 tree.setRootNode(root);
117 tree.on('click', function(node, event) {
118 Ext.brestore.path = get_node_path(node);
120 file_store.removeAll();
121 file_versions_store.removeAll();
122 file_store.load({params:init_params({action: 'list_files',
128 tree.on('beforeload', function(e) {
129 file_store.removeAll();
134 ////////////////////////////////////////////////////////////////
136 var file_store = new Ext.data.Store({
137 proxy: new Ext.data.HttpProxy({
138 url: '/cgi-bin/bweb/bresto.pl',
143 reader: new Ext.data.ArrayReader({
144 }, Ext.data.Record.create([
146 {name: 'filenameid'},
149 {name: 'size', type: 'int' },
150 {name: 'mtime', type: 'date', dateFormat: 'Y-m-d h:i:s'}
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 })
159 css: 'white-space:normal;'
163 renderer: human_size,
173 dataIndex: 'filenameid',
181 // by default columns are sortable
182 cm.defaultSortable = true;
185 var files_grid = new Ext.grid.Grid('div-files', {
190 enableDragDrop: true,
191 selModel: new Ext.grid.RowSelectionModel(),
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();
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,
210 filenameid: r.json[1]
217 //////////////////////////////////////////////////////////////:
219 var file_selection_store = new Ext.data.Store({
220 proxy: new Ext.data.MemoryProxy(),
222 reader: new Ext.data.ArrayReader({
223 }, Ext.data.Record.create([
226 {name: 'filenameid'},
229 {name: 'size', type: 'int' },
230 {name: 'mtime', type: 'date', dateFormat: 'Y-m-d h:i:s'}
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 })
246 renderer: human_size,
256 dataIndex: 'filenameid',
266 var file_selection_grid = new Ext.grid.Grid('div-file-selection', {
267 cm: file_selection_cm,
268 ds: file_selection_store,
272 selModel: new Ext.grid.RowSelectionModel(),
278 var file_selection_record = Ext.data.Record.create(
281 {name: 'filenameid'},
286 // data.selections[0].json[]
288 // http://extjs.com/forum/showthread.php?t=12582&highlight=drag+drop
289 var ddrow = new Ext.dd.DropTarget(file_selection_grid.container, {
292 notifyDrop : function(dd, e, data){
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]
306 file_selection_store.add(r)
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]
320 file_selection_store.add(r)
325 var path= get_node_path(data.node);
326 r = new file_selection_record({
327 jobid: Ext.brestore.jobid,
330 pathid: data.node.id,
335 file_selection_store.add(r)
342 file_selection_grid.on('enddrag', function(dd,e) {
343 alert(e) ; return true;
345 file_selection_grid.on('notifyDrop', function(dd,e) {
346 alert(e) ; return true;
348 file_selection_grid.render();
350 ///////////////////////////////////////////////////////
352 var file_versions_store = new Ext.data.Store({
353 proxy: new Ext.data.HttpProxy({
354 url: '/cgi-bin/bweb/bresto.pl',
356 params:{offset:0, limit:50 }
359 reader: new Ext.data.ArrayReader({
360 }, Ext.data.Record.create([
362 {name: 'filenameid'},
366 {name: 'inchanger' },
368 {name: 'size', type: 'int' },
369 {name: 'mtime'} //, type: 'date', dateFormat: 'Y-m-d h:i:s'}
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 })
379 dataIndex: 'inchanger',
381 renderer: rd_vol_is_online
392 renderer: human_size,
406 dataIndex: 'filenameid',
414 // by default columns are sortable
415 file_versions_cm.defaultSortable = true;
418 var file_versions_grid = new Ext.grid.Grid('div-file-versions', {
419 ds: file_versions_store,
420 cm: file_versions_cm,
424 selModel: new Ext.grid.RowSelectionModel(),
430 file_versions_grid.on('rowdblclick', function(e) {
431 alert(e) ; file_versions_store.removeAll(); return true;
433 file_versions_grid.render();
435 //////////////////////////////////////////////////////////////:
438 var client_store = new Ext.data.Store({
439 proxy: new Ext.data.HttpProxy({
440 url: '/cgi-bin/bweb/bresto.pl',
442 params:{action:'list_client'}
445 reader: new Ext.data.ArrayReader({
446 }, Ext.data.Record.create([
451 var client_combo = new Ext.form.ComboBox({
452 fieldLabel: 'Clients',
457 triggerAction: 'all',
458 emptyText:'Select a client...',
460 forceSelection: true,
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}});
471 //////////////////////////////////////////////////////////////:
473 var job_store = new Ext.data.Store({
474 proxy: new Ext.data.HttpProxy({
475 url: '/cgi-bin/bweb/bresto.pl',
477 params:{offset:0, limit:50 }
480 reader: new Ext.data.ArrayReader({
481 }, Ext.data.Record.create([
488 var job_combo = new Ext.form.ComboBox({
491 displayField:'jobname',
494 triggerAction: 'all',
495 emptyText:'Select a job...',
497 forceSelection: true,
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'});
510 ////////////////////////////////////////////////////////////////
512 function sel_option(item, check)
514 if (item.id == 'id_vosb') {
515 Ext.brestore.option_vosb = check;
517 if (item.id == 'id_vafv') {
518 Ext.brestore.option_vafv = check;
522 var menu = new Ext.menu.Menu({
525 new Ext.menu.CheckItem({
527 text: 'View only selected backup',
528 checked: Ext.brestore.option_vosb,
529 checkHandler: sel_option
531 new Ext.menu.CheckItem({
533 text: 'View all file versions',
534 checked: Ext.brestore.option_vafv,
535 checkHandler: sel_option
539 ////////////////////////////////////////////////////////////////:
541 // create the primary toolbar
542 var tb2 = new Ext.Toolbar('div-tb-sel');
548 cls:'x-btn-text-icon save',
549 tooltip:'Saves all components to the server'
553 // handler:addComponent,
554 cls:'x-btn-text-icon add-cmp',
555 tooltip:'Add a new Component to the dependency builder'
560 // handler:addOption,
561 cls:'x-btn-text-icon add-opt',
562 tooltip:'Add a new optional dependency to the selected component'
567 // handler:removeNode,
568 cls:'x-btn-text-icon remove',
569 tooltip:'Remove the selected item'
572 var where_field = new Ext.form.TextField({
573 fieldLabel: 'Location',
579 var tb = new Ext.Toolbar('div-toolbar', [
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;
592 tree_loader.baseParams = init_params({ action:'list_dirs', path: where });
599 cls: 'x-btn-text-icon bmenu', // icon and text class
601 menu: menu // assign menu by instance
604 icon: '/bweb/remove.png', // icons can also be specified inline
607 handler: function() {
608 if (Ext.brestore.dlglaunch) {
609 Ext.brestore.dlglaunch.show();
612 Ext.brestore.dlglaunch = new Ext.LayoutDialog("div-resto-dlg", {
626 // collapsible: true,
631 // tabPosition: 'top',
633 // alwaysShowTabs: true
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);
641 var fs = new Ext.form.Form({
646 var storage_store = new Ext.data.Store({
647 proxy: new Ext.data.HttpProxy({
648 url: '/cgi-bin/bweb/bresto.pl',
650 params:{action:'list_storage'}
653 reader: new Ext.data.ArrayReader({
654 }, Ext.data.Record.create([
659 var resto_store = new Ext.data.Store({
660 proxy: new Ext.data.HttpProxy({
661 url: '/cgi-bin/bweb/bresto.pl',
663 params:{action:'list_resto'}
666 reader: new Ext.data.ArrayReader({
667 }, Ext.data.Record.create([
673 {legend:'Restore job'},
674 new Ext.form.ComboBox({
675 fieldLabel: 'Replace',
676 hiddenName:'replace',
677 store: new Ext.data.SimpleStore({
679 data : [['always'],['never'],['if newer']]
681 displayField:'replace',
684 triggerAction: 'all',
690 new Ext.form.ComboBox({
697 triggerAction: 'all',
698 emptyText:'Select a job...',
703 new Ext.form.TextField({
709 new Ext.form.ComboBox({
710 fieldLabel: 'client',
716 triggerAction: 'all',
717 emptyText:'Select a client...',
721 new Ext.form.ComboBox({
722 fieldLabel: 'storage',
723 hiddenName:'storage',
724 store: storage_store,
728 triggerAction: 'all',
729 emptyText:'Select a storage...',
734 storage_store.load({params:{action: 'list_storage'}});
735 resto_store.load({params:{action: 'list_resto'}});
736 fs.render('div-resto-form');
738 // var f = new Ext.form.BasicForm('div-resto-form', {url: '/bweb/test', method: 'GET',
739 // baseParams: {init: 1}
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}));
753 ////////////////////////////////////////////////////////////////
755 var layout = new Ext.BorderLayout(document.body, {
760 split: true, initialSize: 300
763 split: true, initialSize: 550
766 split: true, initialSize: 300
774 layout.beginUpdate();
775 layout.add('north', new Ext.ContentPanel('div-toolbar', {
776 fitToFrame: true, autoCreate:true,closable: false
778 layout.add('south', new Ext.ContentPanel('div-file-selection', {
779 toolbar: tb2,resizeEl:'div-file-selection',
780 fitToFrame: true, autoCreate:true,closable: false
782 layout.add('east', new Ext.ContentPanel('div-file-versions', {
783 fitToFrame: true, autoCreate:true,closable: false
785 layout.add('west', new Ext.ContentPanel('div-tree', {
786 autoScroll:true, fitToFrame: true,
787 autoCreate:true,closable: false
789 layout.add('center', new Ext.ContentPanel('div-files', {
790 autoScroll:true,autoCreate:true,fitToFrame: true
795 ////////////////////////////////////////////////////////////////
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();
804 Ext.onReady( ext_init );