~coreygoldberg/uci-engine/subunit-results

« back to all changes in this revision

Viewing changes to webui/tickets/static/tickets/webui.js

Merge trunk, resolving conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
"use strict";
2
2
 
3
3
// Make jslint happy
4
 
var window;
5
4
var YUI;
6
5
 
7
6
YUI.add('webui', function (Y) {
8
 
    var json_error_msg = "The ticket system returned data that could not be understood. " +
9
 
                         "Please try refreshing, or contact support if this problem persists.",
10
 
        refresh_msg = "Refreshing data...";
11
 
    var default_refresh = 15;
 
7
    var json_error_msg = (
 
8
        "The ticket system returned data that could not be understood. " +
 
9
        "Please try refreshing, or contact support if this problem " +
 
10
        "persists."),
 
11
        refresh_msg = "Refreshing data...",
 
12
        default_refresh = 60,
 
13
        static_prefix = "/static/common/";
12
14
    Y.webui = {
13
15
        url_prefix: "/api/v1/",
14
 
        refresh_interval: (parseInt(Y.one('#refresh_rate'), 10) || default_refresh) * 1000,
 
16
        refresh_interval: default_refresh * 1000,
 
17
        refresh_timer: null,
15
18
        done_loading: false,
16
 
        log_prefixes: Y.Array(['package_build', 'image_build', 'image_test', 'package_publish']),
 
19
        log_prefixes: Y.Array(
 
20
            ['package_build', 'image_build', 'image_test',
 
21
             'package_publish']),
17
22
        log_step_map: {
18
23
            "Image building": "image_build",
19
24
            "Image testing": "image_test",
21
26
            "Package publishing": "package_publish"
22
27
        },
23
28
        logs: {},
 
29
        tempurls: {},
24
30
        get_log_name: function (step_name) {
25
31
            var log_name = Y.webui.log_step_map[step_name];
26
32
 
43
49
 
44
50
            Y.webui.logs[key].push(log_data);
45
51
        },
46
 
        add_refresh_div: function (callback) {
47
 
            var refresh,
48
 
                refresh_rate,
49
 
                refresh_enabled,
50
 
                onChange;
51
 
 
52
 
            refresh = Y.Node.create('<div id="refresh"></div>');
53
 
 
54
 
            refresh.setHTML('<small>Auto refresh <input type="checkbox" checked="true"' +
55
 
                'id="refresh_enabled"></input> every <input type="text"' +
56
 
                'id="refresh_rate" value="' + default_refresh + '" maxlength="3" size="2"/> seconds.</small>'
57
 
                );
58
 
 
59
 
            Y.one('div#main-content').append(refresh);
60
 
 
61
 
            Y.webui.refresh_timeout = null;
62
 
            refresh_rate = Y.one("#refresh_rate");
63
 
            refresh_enabled = Y.one("#refresh_enabled");
64
 
            Y.webui.refresh_enabled = refresh_enabled.get('checked');
65
 
 
66
 
            onChange = function () {
67
 
                var value = refresh_rate.get('value'),
68
 
                    val;
69
 
 
70
 
                val = parseInt(value, 10);
71
 
 
72
 
                if (Y.webui.refresh_timeout) {
73
 
                    clearTimeout(Y.webui.refresh_timeout);
74
 
                }
75
 
                if (val !== 0) {
76
 
                    Y.webui.refresh_interval = val * 1000;
77
 
                    callback();
78
 
                }
79
 
            };
80
 
            refresh_rate.on('change', onChange);
81
 
            refresh_enabled.on('change', function () {
82
 
                if (Y.webui.refresh_timeout) {
83
 
                    clearTimeout(Y.webui.refresh_timeout);
84
 
                }
85
 
 
86
 
                Y.webui.refresh_enabled = refresh_enabled.get('checked');
87
 
 
88
 
                if (Y.webui.refresh_enabled) {
89
 
                    callback();
90
 
                }
91
 
            });
92
 
            onChange();
 
52
 
 
53
        /**
 
54
         * Setup page auto-refresh.
 
55
         *
 
56
         * Immediately runs the callback when auto-refresh is set up
 
57
         * (page is loaded) then use Y.later() for periodically calling
 
58
         * the 'callback' at the `Y.webui.refresh_interval` rate.
 
59
         *
 
60
         * @method setup_auto_refresh
 
61
         */
 
62
        setup_auto_refresh: function (callback) {
 
63
            callback();
 
64
            Y.webui.refresh_timer = Y.later(
 
65
                Y.webui.refresh_interval, Y, callback, '', true);
93
66
        },
 
67
 
94
68
        get_workflow_data: function (api_url) {
95
69
            var wf_data = {},
96
70
                wf_str = {},
161
135
            if (Y.webui.main_table) {
162
136
                Y.webui.main_table.showMessage("loading data...");
163
137
            }
 
138
            // Load a map of tempurls for the context artifacts from GK.
 
139
            Y.io("/gk/api/v1/ticket/" + ticket_id, {
 
140
                sync: true,
 
141
                on: {
 
142
                    success: function (tx, r) {
 
143
                        Y.webui.tempurls = Y.JSON.parse(r.responseText);
 
144
                    },
 
145
                    failure: function (tx, r, e) {
 
146
                        console.log("Failed to load tempurls: ", tx, r, e);
 
147
                    }
 
148
                }
 
149
            });
 
150
            // Load ticket information from TS.
164
151
            Y.io(Y.webui.url_prefix + "fullticket/" + ticket_id + "/", {
165
152
                sync: true,
166
153
                on: {
188
175
                }
189
176
            });
190
177
        },
191
 
        get_tickets: function () {
 
178
        get_tickets: function (type) {
 
179
            var url_suffix = "";
 
180
            var status_callback;
 
181
 
 
182
            if (type === "open") {
 
183
                url_suffix = "opentickets/";
 
184
                status_callback = Y.webui.check_open_statuses;
 
185
            } else if (type === "complete") {
 
186
                status_callback = Y.webui.check_complete_statuses;
 
187
                url_suffix = "ticketstatus/?current_workflow_step=1000";
 
188
            } else if (type === "failed") {
 
189
                status_callback = Y.webui.check_failed_statuses;
 
190
                url_suffix = "ticketstatus/?status=300";
 
191
            }
192
192
 
193
193
            if (Y.webui.main_table) {
194
194
                Y.webui.main_table.showMessage("loading data...");
195
195
            }
196
 
            Y.io(Y.webui.url_prefix + "opentickets/", {
 
196
            Y.io(Y.webui.url_prefix + url_suffix, {
197
197
                on: {
198
198
                    success: function (tx, r) {
199
199
                        var data,
209
209
 
210
210
                        if (data.objects && data.objects.length !== 0) {
211
211
                            for (i = 0; i < data.objects.length; i += 1) {
212
 
                                if (data.objects[i] && data.objects[i].status !== "Failed") {
213
 
                                    Y.webui.add_item(data.objects[i]);
 
212
                                if (data.objects[i]) {
 
213
                                    if (type === "failed" || data.objects[i].status !== "Failed") {
 
214
                                        Y.webui.add_item(data.objects[i]);
 
215
                                    }
214
216
                                }
215
217
                            }
216
 
                            Y.webui.check_statuses();
 
218
                            status_callback();
217
219
                        }
218
220
                        if (Y.webui.main_table.data.size() === 0) {
219
221
                            Y.webui.main_table.showMessage("No results found");
319
321
        },
320
322
        artifact_link: function (data, new_name) {
321
323
            var name = Y.webui.basename(data.name),
322
 
                link = Y.Node.create("<a/>");
 
324
                link = Y.Node.create('<a/>');
 
325
 
 
326
            // Lookup a corresponding tempurl.
 
327
            var tempurl = Y.webui.tempurls[name];
323
328
 
324
329
            if (new_name) {
325
330
                name = new_name;
326
331
            }
327
 
 
328
 
            link.set('href', data.reference);
329
332
            link.set('text', name);
330
333
 
 
334
            // Link the artifact to the tempurl or fallback to the original
 
335
            // TS reference.
 
336
            if (tempurl === undefined) {
 
337
                console.log('No tempurl for:', data.name);
 
338
                link.set('href', data.reference);
 
339
            } else {
 
340
                link.set('href', tempurl);
 
341
            }
 
342
 
331
343
            return link;
332
344
        },
333
345
        sp_upload: function (data) {
443
455
 
444
456
                    if (!found_step) {
445
457
                        step_status = 'Completed';
446
 
                        status_image = 'check.svg';
 
458
                        status_image = static_prefix + 'check.svg';
447
459
                    }
448
460
 
449
461
                    if (wf_data[i].name === "Completed" || wf_data[i].name === "Failed" ||
454
466
                    if (!found_step && (current_step === wf_data[i].name)) {
455
467
                        found_step = true;
456
468
                        if (data.status !== "Completed" && short_status !== "Failed") {
457
 
                            step_status = "In Progress";
458
 
                            status_image = 'spinner3.gif';
 
469
                            if(data.status === 'Paused') {
 
470
                                step_status = "Needs Attention";
 
471
                                status_image = static_prefix + 'paused.svg';
 
472
                            } else {
 
473
                                step_status = "In Progress";
 
474
                                status_image = static_prefix + 'spinner3.gif';
 
475
                            }
459
476
                        } else {
460
477
                            step_status = data.status;
461
478
                            if (short_status === "Failed") {
462
 
                                status_image = "cross.svg";
 
479
                                status_image = static_prefix + "cross.svg";
463
480
                            } else {
464
 
                                status_image = "check.svg";
 
481
                                status_image = static_prefix + "check.svg";
465
482
                            }
466
483
                        }
467
484
                    }
472
489
 
473
490
                    if (data.current_workflow_step === "Failed" && wf_data[i].name === "Failed") {
474
491
                        step_status = "Failed";
475
 
                        status_image = "cross.svg";
 
492
                        status_image = static_prefix + "cross.svg";
476
493
                    }
477
494
 
478
495
                    if (!skipped_step) {
485
502
                        tr.appendChild(td1);
486
503
                        td = tr.appendChild('<td class="workflow_status_td"></td>');
487
504
                        if (status_image) {
488
 
                            td.appendChild('<img src="' + status_image +
489
 
                                    '" title="' + step_status + '">');
 
505
                            var elem = '<img src="' + status_image + '" title="' + step_status + '">';
 
506
                            if(data.status === 'Paused') {
 
507
                                elem = '<a href="/ticket/' + data.id + '/review">' + elem + '</a>';
 
508
                            }
 
509
                            td.appendChild(elem);
490
510
                        }
491
511
 
492
512
                        log_name = Y.webui.get_log_name(wf_data[i].name);
533
553
 
534
554
                        if (key === 'base_image') {
535
555
                            value = '<a href="' + value + '">' + value.slice(value.lastIndexOf('/') + 1) +
536
 
                                '</a>&nbsp;<a href="' + value + '"><img src="cdrom.svg" title="image"></a>';
 
556
                                '</a>&nbsp;<a href="' + value + '"><img src="' + static_prefix + 'cdrom.svg" title="image"></a>';
537
557
                        }
538
558
 
539
559
                        key = key.replace("_", " ");
568
588
            }
569
589
 
570
590
            if (current_step !== "Completed" && short_status !== "Failed") {
571
 
              table.appendChild(Y.Node.create('<tr><td></td><td><a href="logview.html?ticket_id=' + data.id + '">Watch Build</a></tr>'));
 
591
              table.appendChild(Y.Node.create('<tr><td></td><td><a href="livelog?lander_unit=' + data.lander_unit + '">Watch Build</a></tr>'));
572
592
            }
573
593
 
574
594
            if (data.subticket) {
623
643
                }
624
644
            }
625
645
        },
 
646
 
 
647
        /**
 
648
         * Returns the ticket ID based on the window URL.
 
649
         *
 
650
         * Checks the known ticket page path (/ticket/<id>), then match
 
651
         * a valid integer ID.
 
652
         *
 
653
         * @method get_ticket_id
 
654
         */
626
655
        get_ticket_id: function () {
627
 
            var query = window.location.search.split('?')[1],
628
 
                ticket_id = null,
629
 
                ob;
630
 
 
631
 
            if (query) {
632
 
                ob = Y.QueryString.parse(query);
633
 
                ticket_id = ob.ticket_id;
634
 
            }
635
 
 
636
 
            return ticket_id;
 
656
            var path = Y.config.win.location.pathname;
 
657
            if (!path.match(/\/ticket\/\d+\//g)) {
 
658
                return null;
 
659
            }
 
660
            var id_match = path.match(/\d+/g);
 
661
            if (!id_match) {
 
662
                return null;
 
663
            }
 
664
            return id_match[0];
637
665
        },
 
666
 
 
667
        /**
 
668
         * Updates ticket information.
 
669
         *
 
670
         * @method update_ticket
 
671
         */
638
672
        update_ticket: function () {
639
673
            var ticket_id = Y.webui.get_ticket_id();
640
 
 
641
674
            if (ticket_id) {
642
675
                Y.webui.get_ticket(ticket_id, Y.one('#container'));
643
676
            }
644
 
 
645
 
            // we're done so allow more refreshes if needed.
646
 
            if (Y.webui.refresh_timeout) {
647
 
                clearTimeout(Y.webui.refresh_timeout);
648
 
                Y.webui.refresh_timeout = null;
649
 
            }
650
 
 
651
 
            if (Y.webui.refresh_enabled && !Y.webui.refresh_timeout && Y.webui.refresh_interval > 0) {
652
 
                Y.webui.refresh_timeout = setTimeout(Y.webui.update_ticket, Y.webui.refresh_interval);
653
 
            }
654
677
        },
655
678
        has_ticket: function (ticket_ids, id) {
656
679
            return ticket_ids[id] === true;
657
680
        },
658
 
        check_statuses: function () {
 
681
        check_complete_statuses: function () {
 
682
            return Y.webui.check_statuses('complete', Y.webui.check_complete_statuses);
 
683
        },
 
684
        check_failed_statuses: function () {
 
685
            return Y.webui.check_statuses('failed', Y.webui.check_failed_statuses);
 
686
        },
 
687
        check_open_statuses: function () {
 
688
            return Y.webui.check_statuses('open', Y.webui.check_open_statuses);
 
689
        },
 
690
        check_statuses: function (type, status_callback) {
659
691
            var ticket_id_map = {},
660
692
                table_data = Y.webui.main_table.get('data').toJSON(),
661
693
                i,
662
694
                record,
663
695
                ticket_id,
664
696
                ticket_ids,
665
 
                ids;
 
697
                ids,
 
698
                url_suffix = "";
 
699
 
 
700
            if (type === "open") {
 
701
                url_suffix = "opentickets/";
 
702
            } else if (type === "complete") {
 
703
                url_suffix = "ticketstatus/?current_workflow_step=1000";
 
704
            } else if (type === "failed") {
 
705
                url_suffix = "ticketstatus/?status=300";
 
706
            }
666
707
 
667
708
            for (i = 0; i < table_data.length; i += 1) {
668
709
                record = table_data[i];
669
710
 
670
711
                ticket_id = record.ticket_id;
671
712
 
672
 
                if (record.status !== 'Completed' && record.current_workflow_step !== 'Completed') {
 
713
                if (type === "complete" || (record.status !== 'Completed' && record.current_workflow_step !== 'Completed')) {
673
714
                    if (ticket_id) {
674
715
                        ticket_id_map[ticket_id] = true;
675
716
                    }
678
719
 
679
720
            // Check for new tickets and add them to the table.
680
721
            if (Y.webui.main_table && Y.webui.done_loading) {
681
 
                Y.io(Y.webui.url_prefix + "opentickets/", {
 
722
                Y.io(Y.webui.url_prefix + url_suffix, {
682
723
                    on: {
683
724
                        success: function (tx, r) {
684
725
                            var data,
696
737
                            if (data && data.length !== 0) {
697
738
                                for (j = 0; j < data.length; j += 1) {
698
739
                                    id = data[j].id;
699
 
                                    if (!Y.webui.has_ticket(ticket_id_map, id) && data[j].status !== "Failed") {
700
 
                                        Y.webui.add_item(data[j]);
701
 
                                        ticket_id_map[id] = true;
 
740
                                    if (!Y.webui.has_ticket(ticket_id_map, id)) {
 
741
                                        if (type === "failed" || data[j].status !== "Failed") {
 
742
                                            Y.webui.add_item(data[j]);
 
743
                                            ticket_id_map[id] = true;
 
744
                                        }
702
745
                                    }
703
746
                                }
704
747
                            }
744
787
 
745
788
                            Y.webui.main_table.set('data', recordset);
746
789
                            Y.webui.main_table.render();
747
 
 
748
 
                            // we're done so allow more refreshes if needed.
749
 
                            if (Y.webui.refresh_timeout) {
750
 
                                clearTimeout(Y.webui.refresh_timeout);
751
 
                                Y.webui.refresh_timeout = null;
752
 
                            }
753
 
                            if (Y.webui.refresh_enabled && !Y.webui.refresh_timeout && Y.webui.refresh_interval > 0) {
754
 
                                Y.webui.refresh_timeout = setTimeout(Y.webui.check_statuses, Y.webui.refresh_interval);
755
 
                            }
756
790
                        },
757
 
                        complete: function () {
758
 
                            if (Y.webui.refresh_enabled && !Y.webui.refresh_timeout && Y.webui.refresh_interval > 0) {
759
 
                                Y.webui.refresh_timeout = setTimeout(Y.webui.check_statuses, Y.webui.refresh_interval);
760
 
                            }
761
 
                        }
762
791
                    }
763
792
                });
764
 
            } else {
765
 
                if (Y.webui.refresh_timeout) {
766
 
                    clearTimeout(Y.webui.refresh_timeout);
767
 
                    Y.webui.refresh_timeout = null;
768
 
                }
769
 
                if (Y.webui.refresh_enabled && !Y.webui.refresh_timeout && Y.webui.refresh_interval > 0) {
770
 
                    Y.webui.refresh_timeout = setTimeout(Y.webui.check_statuses, Y.webui.refresh_interval);
771
 
                }
772
793
            }
773
794
        },
774
795
        add_item: function (item) {
790
811
        make_main_table: function (div_id) {
791
812
 
792
813
            var link_it = function (o) {
793
 
                    return '<a class="row_link" href="/ticket.html?ticket_id=' +
794
 
                        o.data.ticket_id + '">' + o.value + '</a>';
 
814
                    return '<a class="row_link" href="/ticket/' +
 
815
                        o.data.ticket_id + '/">' + o.value + '</a>';
795
816
                },
796
817
                format_id = function (o) {
797
818
                    o.rowClass = "data-row-" + o.data.ticket_id;