Statistics
| Branch: | Tag: | Revision:

root / ui / static / snf / js / ui / web / ui_error_view.js @ a08a37d2

History | View | Annotate | Download (9.3 kB)

1
;(function(root){
2

    
3
    // root
4
    var root = root;
5
    
6
    // setup namepsaces
7
    var snf = root.synnefo = root.synnefo || {};
8
    var models = snf.models = snf.models || {}
9
    var storage = snf.storage = snf.storage || {};
10
    var ui = snf.ui = snf.ui || {};
11
    var util = snf.util = snf.util || {};
12

    
13
    var views = snf.views = snf.views || {}
14

    
15
    // shortcuts
16
    var bb = root.Backbone;
17

    
18
    views.ErrorView = views.Overlay.extend({
19
        
20
        view_id: "error_view",
21
        content_selector: "#error-overlay-content",
22
        css_class: 'overlay-error',
23
        overlay_id: "error-overlay",
24
        error_stack: {},
25

    
26
        initialize: function() {
27
            views.ErrorView.__super__.initialize.apply(this, arguments);
28
            var self = this;
29

    
30
            this.error_state = false;
31

    
32
            this.$(".actions .show-details, .actions .hide-details").click(function() {
33
                self.$(".error-details").toggle();
34
                self.$(".show-details").toggle();
35
                self.$(".hide-details").toggle();
36
            });
37

    
38
            this.$(".key.details").click(function() {
39
                $(this).next().toggle();
40
                if (!$(this).next().is(":visible")) {
41
                    $(this).addClass("expand");
42
                } else {
43
                    $(this).removeClass("expand");
44
                }
45
            })
46

    
47
            this.$(".actions .report-error").click(_.bind(function() {
48
                this.report_error();
49
            }, this));
50

    
51
            this.$(".actions .hide-details").hide();
52

    
53
            this.$(".reload-app").click(function(){
54
                window.location.reload(true);
55
            });
56

    
57
            this.$(".show-next").click(_.bind(function(){
58
                this.show_next_error();
59
            }, this));
60

    
61
            this.$(".show-prev").click(_.bind(function(){
62
                this.show_prev_error();
63
            }, this));
64

    
65
            this.displaying_error = false;
66
            this.error_stack_index = [];
67
            this.error_stack = {};
68
        },
69

    
70
        error_object: function() {
71
            return {ns:this.ns, code:this.code, message:this.message, details:this.details};
72
        },
73

    
74
        report_error: function() {
75
            this.feedback_view = this.feedback_view || ui.main.feedback_view;
76
            this.hide(false);
77
            this.displaying_error = true;
78

    
79
            window.setTimeout(_.bind(function() {
80
                this.feedback_view.show(this.get_report_message(), true, {error: this.error_object()});
81
            }, this), 400);
82
        },
83

    
84
        get_report_message: function() {
85
            var fdb_msg =   "Error report\n" +
86
                "-------------------" + "\n" +
87
                "Code: " + this.code + "\n" + 
88
                "Type: " + this.type + "\n" +
89
                "Message: " + this.message + "\n" +
90
                "Module: " + this.ns + "\n" +
91
                "Details: " + this.details + "\n\n" +
92
                "Please describe the actions that triggered the error:\n"
93
            
94
            return fdb_msg;
95
        },
96
        
97
        show_error: function(ns, code, message, type, details, error_options) {
98
            
99
            var error_entry = [ns, code, message, type, details, error_options];
100
            var last_error_key = this.update_errors_stack(error_entry);
101
            
102
            if (!this.is_visible && !this.displaying_error) {
103
                this.current_error = last_error_key;
104
                this.display_error.call(this, last_error_key);
105
                this.show();
106
            }
107

    
108
            this.update_errors_stack();
109
        },
110

    
111
        update_errors_stack: function(entry) {
112
            if (snf.api.error_state != snf.api.STATES.ERROR) { 
113
                this.error_stack = {};
114
                this.error_stack_index = [];
115
            };
116

    
117
            var stack_key = (new Date()).getTime();
118
            this.error_stack[stack_key] = entry;
119
            this.error_stack_index.push(stack_key);
120
            this.errors_occured = this.error_stack_index.length;
121
            
122
            this.$(".error-nav").hide();
123
            //this.update_errors_stack_layout();
124
            return stack_key;
125
        },
126

    
127
        is_last_error: function(stack_key) {
128
            return this.error_stack_index.indexOf(stack_key) == this.error_stack_index.length - 1;
129
        },
130

    
131
        is_first_error: function(stack_key) {
132
            return this.error_stack_index.indexOf(stack_key) == 0;
133
        },
134

    
135
        update_errors_stack_layout: function() {
136
            if (!this.current_error) { return };
137

    
138
            if (this.errors_occured <= 1) {
139
                this.$(".error-nav").hide();
140
            } else {
141
                this.$(".error-nav").show();
142
            };
143
            
144
            if (this.is_last_error(this.current_error)) {
145
                this.$(".show-next").hide();
146
            } else {
147
                this.$(".show-next").show();
148
            }
149

    
150
            if (this.is_first_error(this.current_error)) {
151
                this.$(".show-prev").hide();
152
            } else {
153
                this.$(".show-prev").show();
154
            }
155
        },
156

    
157
        show_next_error: function() {
158
        },
159

    
160
        show_prev_error: function() {
161
        },
162

    
163
        display_error: function(stack_key) {
164
            var err = this.error_stack[stack_key];
165
            var ns = err[0], code = err[1], message = err[2], type = err[3], details = err[4], error_options = err[5]
166

    
167
            this.error_options = {'allow_report': true, 'allow_reload': true, 
168
                'extra_details': {}, 'non_critical': false, 
169
                'allow_details': false,
170
                'allow_close': true };
171
            
172
            if (error_options) {
173
                this.error_options = _.extend(this.error_options, error_options);
174
            }
175

    
176
            this.code = code;
177
            this.ns = ns;
178
            this.type = type;
179
            this.details = details ? (details.toString ? details.toString() : details) : undefined;
180
            this.message = message;
181
            this.title = error_options.title || undefined;
182

    
183
            this.update_details();
184
            
185
            if (error_options.non_critical) {
186
                this.el.addClass("non-critical");
187
                this.error_options.allow_details = false;
188
            } else {
189
                this.el.removeClass("non-critical");
190
                this.error_options.allow_details = true;
191
            }
192
            
193
            if (APP_DEBUG) {
194
                this.error_options.allow_details = true;
195
            }
196
            
197
            this.$(".actions .show-details").click();
198
            this.$(".error-details").hide();
199
            this.$(".key.details").click();
200
            this.$(".error-more-details").hide();
201
        },
202

    
203
        update_details: function() {
204
            var title = "Application error";
205
            if (this.ns && this.type) {
206
                title = this.title || this.type + " Error";
207
            }
208

    
209
            this.$(".header .title").text(title);
210
            this.$(".error-code").text(this.code || "");
211
            this.$(".error-type").text(this.type || "");
212
            this.$(".error-module").text(this.ns || "");
213
            this.$(".message p").text(this.message || "");
214
            this.$(".error-more-details p").html(this.details || "no info");
215

    
216
            this.$(".extra-details").remove();
217
            _.each(this.error_options.extra_details, function(value, key){
218
                var opt = $(('<span class="extra-details key">{0}</span>' +
219
                            '<span class="extra-details value">{1}</span>').format(key, value))
220
                this.$(".value.error-type").after(opt);
221
            })
222

    
223
        },
224

    
225
        beforeOpen: function() {
226
            this.$(".error-details").hide();
227
            this.$(".key.details").addClass("expand");
228
            this.$(".show-details").show();
229
            this.$(".hide-details").hide();
230
            
231
            if (this.error_options.allow_details) {
232
                this.$(".show-details").show();
233
            } else {
234
                this.$(".show-details").hide();
235
            }
236

    
237
            if (this.error_options.allow_report) {
238
                this.$(".report-error").show();
239
            } else {
240
                this.$(".report-error").hide();
241
            }
242

    
243
            if (this.error_options.allow_reload) {
244
                this.$(".reload-app").show();
245
            } else {
246
                this.$(".reload-app").hide();
247
            }
248

    
249
            if (this.error_options.allow_close) {
250
                this.$(".closeme").show();
251
            } else {
252
                this.$(".closeme").hide();
253
            }
254

    
255
        },
256

    
257
        onOpen: function() {
258
            this.displaying_error = true;
259
            var self = this;
260

    
261
            this.$(".closeme").unbind("click");
262
            this.$(".closeme").bind("click", function(){
263
                self.hide("reset");
264
            })
265
        },
266

    
267
        hide: function(reset_state) {
268
            if (reset_state === "reset") {
269
                // delay reset error state for fade out
270
                window.setTimeout(_.bind(function(){
271
                    this.displaying_error = false;
272
                    this.error_stack = {};
273
                    snf.api.trigger("reset");
274
                }, this), 500);
275
            } else {
276
                this.displaying_error = false;
277
            }
278
            views.ErrorView.__super__.hide.apply(this);
279
        },
280

    
281
        onClose: function(reset_state) {
282
            this.trigger("close", this);
283
        }
284
    });
285

    
286
})(this);