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