Project

General

Profile

Download (16.7 KB) Statistics
| Branch: | Revision:
1
define([
2
"dojo/on",
3
'dojo/_base/lang',
4
'steam2/statusColorMap',
5
'steam2/user',
6
'stabile/griddialog',
7
'dojox/grid/DataGrid',
8
'dojo/string',
9
'stabile/stores'
10
], function(on, lang, statusColorMap, user){
11

    
12
var grid = {
13

    
14
    // Gets a text representation of an action button with action handlers.
15
    actionButton: function(args){
16
        var actionHandler;
17
        args.title = args.title || args.action;
18
        if(args.confirm){
19
            if (args.actionHandler)
20
                actionHandler = "grid.actionConfirmDialog('" + args.id + "','" + args.action + "','" + args.name + "','" + args.title + "','" + args.type + "','" + args.actionHandler + "')";
21
            else
22
                actionHandler = "grid.actionConfirmDialog('" + args.id + "','" + args.action + "','" + args.name + "','" + args.title + "','" + args.type + "')";
23
        }
24
        else{
25
            if (args.actionHandler)
26
                actionHandler = args.actionHandler + "('" + args.id + "','" + args.action + "','" + args.type + "')";
27
            else
28
                actionHandler = "grid.actionHandler('" + args.id + "','" + args.action + "','" + args.type + "')";
29
        }
30
        // left out button text intentionally since image replacement didn't work out in IE
31
        var t = '<button type="button" title="${title}" class="action_button ${action}_icon" id="${action}_${id}" onclick="${actionHandler};return false;"><span>${action}</span></button>';
32
        args.actionHandler = actionHandler;
33
        return dojo.string.substitute(t, args);
34
    },
35

    
36
    actionCheckBox: function(args){
37
        return '<input id="bulk-action-' + args.id + '" "class="bulk-action" type="checkbox" />';
38
    },
39

    
40
    // Gets a text representation of a save button.
41
    // args:
42
    //    type {String}: grid to save, e.g., images, servers
43
    saveButton : function(type){
44
        // returning false, to disable form submit
45
        var actionHandler = "grid.saveHandler('" + type + "'); return false;";
46
        var t = '<button type="submit" title="Save" class="btn btn-sm btn-primary pull-right" onclick="${actionHandler}">Save</button>';
47
        return dojo.string.substitute(t, {'actionHandler':actionHandler});
48
    },
49

    
50
    // save the contents of the dialog.
51
    // FIXME: bad naming
52
    // args:
53
    //    name {String}: name of grid object
54
    saveHandler : function(name){
55
        // FIXME: action "" == "save"
56
        // We have to set the action since there might be a leftover from an
57
        // old action
58
        if (window[name].grid.dialog.item.action) { // action is not initialized for new items //co
59
            window[name].store.setValue(window[name].grid.dialog.item, 'action', "");
60
        }
61
        window[name].grid.dialog.save(); 
62
     },
63

    
64
    // Shows actions confirm dialog.
65
    // args:
66
    //    id {String}: id of item
67
    //    action {String}: the action to perform
68
    //    name {String}: the name of the object, e.g., servers, images
69
    actionConfirmDialog: function(id, action, name, title, type, myactionHandler){
70
        if(!id || !action || !name || !title || !type){
71
            console.error("not all arguments supplied!", arguments);
72
        }
73
        var actionHandler = "grid.actionHandler";
74
        if (myactionHandler) actionHandler = myactionHandler;
75
        var content = [
76
            '<div align="center" style="margin: 18px;"><p>Are you sure you want to ${title}</p>',
77
            '<div>',
78
            '<button class="btn btn-danger btn-sm" onClick="' + actionHandler + '(\'${id}\',\'${action}\',\'${type}\');dijit.byId(\'confirmDialog\').hide()">OK</button> ',
79
            '<button class="btn btn-info btn-sm" onClick="dijit.byId(\'confirmDialog\').hide()">Cancel</button></button>',
80
            '</div></div>'].join('');
81
        content = dojo.string.substitute(content, {'id':id, 'action':action, 'type': type, 'title':title});
82
        var dialog = dijit.byId('confirmDialog');
83
        if(!dialog){
84
            dialog = new dijit.Dialog({ id: 'confirmDialog', style: "width: 300px"});
85
        }
86
        dialog.set('title', type + ": " + name);
87
        dialog.set('content', content);
88
        dialog.show();
89
        return dialog;
90
    },
91

    
92
    alertDialog: function(title, content, myactionHandler, parm1, parm2){
93
        var content = [
94
            '<div align="center" style="padding:10px;">',
95
            content,
96
            '<div>',
97
            '<button class="btn btn-primary" onClick="' + myactionHandler + '(\'${parm1}\',\'${parm2}\'); dijit.byId(\'alertDialog\').hide()">OK</button>',
98
            '</div></div>'].join('');
99
        content = dojo.string.substitute(content, {'parm1':parm1, 'parm2':parm2});
100
        var dialog = dijit.byId('alertDialog');
101
        if(!dialog){
102
            dialog = new dijit.Dialog({ id: 'alertDialog', style: "width: 300px"});
103
        }
104
        dialog.set('title', title);
105
        dialog.set('content', content );
106
        dialog.show();
107
        return dialog;
108
    },
109

    
110
    // Performs the given action on the given object.
111
    actionHandler: function(id, action, type){
112
        var store = stores[type];
113
        var item = store.fetchItemByIdentity({
114
            identity: id,
115
            onItem: function(item, request){
116
                // HACK: special case when dowloading images.
117
                // FIXME: move these specialcases away.
118
                if(action == "download"){
119
                    // somehow, path isn't of the String type: appending "" to it to ensure that.
120
                    //window.location.href = (item.path + "").replace('/mnt/stabile/images/', '/stabile/download/');
121
                    //window.location.href = "/stabile/images?action=download&image=" + escape(item.path + "");
122
                    window.location.href = "/stabile/images?action=download&uuid=" + item.uuid;
123
                      return;
124
                }
125

    
126
                var data = {
127
                    "items": [{uuid:store.getValue(item, "uuid"), action:action}]
128
                };
129

    
130
                if (type == "nodes") {
131
                    data = {"items": [{mac:item.mac, action:action}]};
132
                } else if (type == "users") {
133
                    data = {"items": [{username:item.username, action:action}]};
134
                }
135

    
136
                else if(action == "start"){
137
                    var value = dijit.byId('mac') && dijit.byId('mac').get('value');
138
                    if (user.is_admin && value && value!="" & value !="--") {
139
                        data = {
140
                            "items": [{uuid:store.getValue(item, "uuid"), action:action, mac:value}]
141
                        };
142
                    }
143
                }
144
                
145
                if ((action == 'delete' || action=='deleteentirely') && (type == 'servers' || type == 'images'|| type == 'networks'|| type == 'nodes'|| type == 'users')) {
146
                    if(window[type].grid.dialog.isOpen()){window[type].grid.dialog.hide();}
147
                    store.deleteItem(item);
148
                    store.save({onComplete: function(){
149
                        if (type == 'servers')
150
                            home.grid.updatePending = images.grid.updatePending = networks.grid.updatePending = true;
151
                    }});
152
                } else {
153
                    // send action to server
154
                    dojo.xhrPost({
155
                        url: "/stabile/" + type,
156
                        postData: dojo.toJson(data),
157
                        load: function(response){
158

    
159
                            if (type == 'servers')
160
                                home.grid.updatePending = images.grid.updatePending = networks.grid.updatePending = true;
161

    
162
                            var newstatus = server.parseResponse(response)["status"];
163
                            console.log("response", newstatus, item);
164
                            if (item.status != newstatus)
165
                                ui_update.publish([{"type": "update","tab": type, "status": newstatus, "uuid": item.uuid}])
166

    
167
                            if((action === "delete" /*|| action === "master" */) && window[type].grid.dialog.isOpen())
168
                                {window[type].grid.dialog.hide();}
169

    
170
                            // Also update systems on home tab when deleting servers
171
                            if (action == 'delete' && type == 'servers'){
172
                                steam2.stores.systems.fetchItemByIdentity({
173
                                    identity: id,
174
                                    onItem: function(item, request){
175
                                        if (action == 'delete') {
176
                                            home.grid.removeSystem(item);
177
                                        }
178
                                    }
179
                                });
180
                            }
181

    
182
                        },
183
                        error: function(error){
184
                            console.error("grid::actionHandler", error);
185
                        }
186
                    });
187
                }
188
                dojo.publish(type + ":" + action, item);
189
            }
190
        });
191
    },
192

    
193
    // Creates the grid.
194
    create: function(args){
195
    // exceptions are apparantly caught by dojo in onLoad
196
        if(!args){console.error("args must be supplied");}
197
        if(!args.store) {console.error("store property must be supplied in args");}
198
        if(!args.structure) {console.error("structure property must be supplied args");} //
199
        if(!args.dialogStructure) {console.error("dialogStructure property must be supplied args");}
200

    
201
        dojo.forEach(args.structure, function(s){
202
            if (s.hidden && user.is_admin) s.hidden = false;
203
        });
204

    
205
        var self = new dojox.grid.DataGrid({
206
            singleClickEdit:false,//true,
207
            clientSort: true,
208
            sortInfo: args.sortInfo || 1,
209
            store: args.store,
210
            structure: args.structure,
211
            rowSelector: "4px",
212
            query: args.storeQuery || { },
213
            queryOptions: { ignoreCase:true, cache:true },
214
            autoRender: true,
215
            autoHeight: false,
216
            rowsPerPage: 2000,
217
            selectionMode: "single",
218
            class: args['class'] || "grid-div",
219

    
220
            renderTooltip: function(){
221
                //var q = dojo.query('.irigo-tooltip', this.domNode);
222
                var q = dojo.query('.irigo-tooltip');
223
                if(q.irigoTooltip){q.irigoTooltip();}
224
            },
225
            postrender: function(){
226
                this.renderTooltip();
227
                if(this.onPostRender) {this.onPostRender();}
228
            }
229
            // autoHeight: true // is broken
230
        }, args.domnode);
231

    
232
        self.model = args.model;
233
        self.name = args.name;
234
        self.dialogStructure = args.dialogStructure;
235
        self.dialogExtras = args.dialogExtras;
236
        self.rowStyler = args.rowStyler;
237
        self.updatePending = true;
238

    
239
        if(args.canSort){self.canSort = args.canSort;}
240

    
241
        //Fixme: onDialog no longer used...?
242
        //self.onDialog = args.onDialog;
243
        self.onDialogButtons = args.onDialogButtons;
244
        self.onBeforeDialog = args.onBeforeDialog;
245
        self.onPostRender = args.onPostRender;
246
        self.currentEditHandler = null;
247
        self.onBeforeSave = args.onBeforeSave;
248
        self.getActionButtons = args.getActionButtons;
249

    
250
        self.dialog = griddialog(self);
251

    
252
        self.onStyleRow = function(row){
253
            /*var item = self.getItem(row.index);
254
            if(item){
255
                var status = self.store.getValue(item,"status");
256
                var color = statusColorMap.get(status);
257
                row.customStyles = "cursor:pointer; color:" + color;
258
                dojo.setStyle(self.getRowNode(row.index), "color", statusColorMap.get(status)); // ugly
259
                if(self.rowStyler){self.rowStyler(row, item);}
260
            };*/
261
        };
262

    
263
        on(self, "styleRow", function(row){
264
            row.customStyles = "cursor:pointer;";
265
            var item = self.getItem(row.index);
266
            if(item){
267
                //var status = self.store.getValue(item,"status");
268
                //var color = statusColorMap.get(status);
269
                var color = statusColorMap.get(item.status);
270
                //row.customStyles += "color:" + color + ";";
271
                row.customClasses += " " + color;
272
                self.focus.styleRow(row);
273
                //self.edit.styleRow(row);
274
                //dojo.setStyle(self.getRowNode(row.index), "color", color); // ugly
275
                if(self.rowStyler){self.rowStyler(row, item);}
276
            };
277
        });
278

    
279
        self.onFetchError = function(err,req) {
280
            //location = "/stabile/auth/login";
281
        };
282

    
283
        self.refresh = function(){
284
            var storename;
285
            if (self.store == stores['servers']) storename = "servers";
286
            else if (self.store == stores['images']) storename = "images";
287
            else if (self.store == stores['networks']) storename = "images";
288
            else if (self.store == stores['systems']) storename = "systems";
289
            else if (self.store == stores['users']) storename = "users";
290
            else if (self.store == stores['nodes']) storename = "nodes";
291
            console.log("refreshing", storename, self);
292
            self.store.reset();
293
        };
294

    
295
        self.refreshRow = function(task, idprop) {
296
            if (!idprop) idprop = "uuid";
297
            self.store.fetchItemByIdentity({identity: task[idprop],
298
                onItem: function(item){
299
                    for (var key in task) {
300
                        if (key=='id' || key=='sender' || key=='timestamp' || key=='type' || key=='uuid') {;}
301
                        else if (item[key]) {
302
                             item[key] = task[key];
303
                        }
304
                    }
305
                    self.store.save();
306
                    var i = self.getItemIndex(item);
307
                    if (task.tab == 'images' && images.grid.getRowNode(i)) images.grid.getRowNode(i).style["font-weight"]='';
308
                    self.updateRow(i);
309
                    self.updateRowStyles(i);
310
                    if (window[task.tab].updateSums) window[task.tab].updateSums();
311
                    //dojo.setStyle(self.getRowNode(i), "color", statusColorMap.get(item.status)); // ugly
312
                }
313
            });
314
        };
315

    
316
        self.handleSelectTab = function(e){
317
            if(!e || e.id == self.name){
318
                if (self.updatePending) {
319
                    self.updatePending = false;
320
                    console.log("doing pending refresh", self.name);
321
//                    self.refresh();
322
                }
323
                self.refresh();
324
                var that = this;
325
                setTimeout(function() {
326
                    that.renderTooltip();
327
                }, 1000)
328
            }
329
        }
330

    
331

    
332
        // save the grid and refresh it
333
        self.save = function(args){
334
            if(self.store.isDirty()){
335
                self.store.save({
336
                    onComplete: function(){
337
                        if (!self.store.isDirty()) {
338
                        //    if (!self.name == "images" && !self.name == "networks") {self.refresh();}
339
                        }
340
                        if(args.onComplete){
341
                            args.onComplete();
342
                        }
343
                    },
344
                    onError: function(){
345
                        console.log("Error saving grid");
346
    //                    self.refresh();
347
                    }
348
                });
349
            }
350
            else{
351
                IRIGO.toaster([{
352
                    message: "Nothing to commit!",
353
                    type: "message",
354
                    duration: 3000
355
                }]);
356
            }
357
        };
358

    
359
        self.newItem = function(){
360
            var model = self.model();
361
            self.dialog.show(model);
362
        };
363

    
364
        self.itemClickHandler = function(event){
365
            var item = self.selection.getSelected()[0];
366
            if(!item){ // e.g. click on header
367
                return;
368
            }
369
            if(event && event.cell && event.cell.field == 'action' || event.cell.steamid == 'console'|| event.cell.steamid == 'terminal'){
370
                return;
371
            }
372
            if(item.id && (item.id=='0' || item.id=='1') && !user.is_admin){ // regular users can not edit built-in networks
373
                return;
374
            }
375
            self.dialog.show(item);
376
        };
377

    
378
        self.update = function(task){
379
            var tabid;
380
            if (dijit.byId('tabContainer')) tabid = dijit.byId('tabContainer').selectedChildWidget.id;
381
            if(self.dialog.isOpen()){
382
                return;
383
            }
384
            if(task.tab == self.name || task.force){
385
                self.refresh();
386
            }
387
        };
388

    
389
        //dojo.connect(ui_update, 'onUpdate', self, self.update);
390
        dojo.connect(self, 'onRowClick', self.itemClickHandler);
391
            return self;
392
    }// end of create
393
};
394

    
395
window.grid = grid;
396
return grid;
397
});
398

    
399

    
400

    
401

    
402

    
(6-6/23)