luci-app-olsr: handle empty result for non-status tables
[oweals/luci.git] / modules / luci-mod-network / htdocs / luci-static / resources / view / network / wifi_join.js
1 var poll = null;
2
3 function format_signal(bss) {
4         var qval = bss.quality || 0,
5             qmax = bss.quality_max || 100,
6             scale = 100 / qmax * qval,
7             range = 'none';
8
9         if (!bss.bssid || bss.bssid == '00:00:00:00:00:00')
10                 range = 'none';
11         else if (scale < 15)
12                 range = '0';
13         else if (scale < 35)
14                 range = '0-25';
15         else if (scale < 55)
16                 range = '25-50';
17         else if (scale < 75)
18                 range = '50-75';
19         else
20                 range = '75-100';
21
22         return E('span', {
23                 class: 'ifacebadge',
24                 title: '%s: %d%s / %s: %d/%d'.format(_('Signal'), bss.signal, _('dB'), _('Quality'), qval, qmax)
25         }, [
26                 E('img', { src: L.resource('icons/signal-%s.png').format(range) }),
27                 ' %d%%'.format(scale)
28         ]);
29 }
30
31 function format_encryption(bss) {
32         var enc = bss.encryption || { }
33
34         if (enc.wep === true)
35                 return 'WEP';
36         else if (enc.wpa > 0)
37                 return E('abbr', {
38                         title: 'Pairwise: %h / Group: %h'.format(
39                                 enc.pair_ciphers.join(', '),
40                                 enc.group_ciphers.join(', '))
41                         },
42                         '%h - %h'.format(
43                                 (enc.wpa === 3) ? _('mixed WPA/WPA2') : (enc.wpa === 2 ? 'WPA2' : 'WPA'),
44                                 enc.auth_suites.join(', ')));
45         else
46                 return E('em', enc.enabled ? _('unknown') : _('open'));
47 }
48
49 function format_actions(dev, type, bss) {
50         var enc = bss.encryption || { },
51             input = [
52                         E('input', { type: 'submit', class: 'cbi-button cbi-button-action important', value: _('Join Network') }),
53                         E('input', { type: 'hidden', name: 'token',    value: L.env.token }),
54                         E('input', { type: 'hidden', name: 'device',   value: dev }),
55                         E('input', { type: 'hidden', name: 'join',     value: bss.ssid }),
56                         E('input', { type: 'hidden', name: 'mode',     value: bss.mode }),
57                         E('input', { type: 'hidden', name: 'bssid',    value: bss.bssid }),
58                         E('input', { type: 'hidden', name: 'channel',  value: bss.channel }),
59                         E('input', { type: 'hidden', name: 'clbridge', value: type === 'wl' ? 1 : 0 }),
60                         E('input', { type: 'hidden', name: 'wep',      value: enc.wep ? 1 : 0 })
61                 ];
62
63         if (enc.wpa) {
64                 input.push(E('input', { type: 'hidden', name: 'wpa_version', value: enc.wpa }));
65
66                 enc.auth_suites.forEach(function(s) {
67                         input.push(E('input', { type: 'hidden', name: 'wpa_suites', value: s }));
68                 });
69
70                 enc.group_ciphers.forEach(function(s) {
71                         input.push(E('input', { type: 'hidden', name: 'wpa_group', value: s }));
72                 });
73
74                 enc.pair_ciphers.forEach(function(s) {
75                         input.push(E('input', { type: 'hidden', name: 'wpa_pairwise', value: s }));
76                 });
77         }
78
79         return E('form', {
80                 class: 'inline',
81                 method: 'post',
82                 action: L.url('admin/network/wireless_join')
83         }, input);
84 }
85
86 function fade(bss, content) {
87         if (bss.stale)
88                 return E('span', { style: 'opacity:0.5' }, content);
89         else
90                 return content;
91 }
92
93 function flush() {
94         L.stop(poll);
95         L.halt();
96
97         scan();
98 }
99
100 function scan() {
101         var tbl = document.querySelector('[data-wifi-scan]'),
102             dev = tbl.getAttribute('data-wifi-scan'),
103             type = tbl.getAttribute('data-wifi-type');
104
105         cbi_update_table(tbl, [], E('em', { class: 'spinning' }, _('Starting wireless scan...')));
106
107         L.post(L.url('admin/network/wireless_scan_trigger', dev), null, function(s) {
108                 if (s.status !== 204) {
109                         cbi_update_table(tbl, [], E('em', _('Scan request failed')));
110                         return;
111                 }
112
113                 var count = 0;
114
115                 poll = L.poll(3, L.url('admin/network/wireless_scan_results', dev), null, function(s, results) {
116
117                         if (Array.isArray(results)) {
118                                 var bss = [];
119
120                                 results.sort(function(a, b) {
121                                         var diff = (b.quality - a.quality) || (a.channel - b.channel);
122
123                                         if (diff)
124                                                 return diff;
125
126                                         if (a.ssid < b.ssid)
127                                                 return -1;
128                                         else if (a.ssid > b.ssid)
129                                                 return 1;
130
131                                         if (a.bssid < b.bssid)
132                                                 return -1;
133                                         else if (a.bssid > b.bssid)
134                                                 return 1;
135                                 }).forEach(function(res) {
136                                         bss.push([
137                                                 fade(res, format_signal(res)),
138                                                 fade(res, res.ssid ? '%h'.format(res.ssid) : E('em', {}, _('hidden'))),
139                                                 fade(res, res.channel),
140                                                 fade(res, res.mode),
141                                                 fade(res, res.bssid),
142                                                 fade(res, format_encryption(res)),
143                                                 format_actions(dev, type, res)
144                                         ]);
145                                 });
146
147                                 cbi_update_table(tbl, bss, E('em', {}, _('No networks in range')));
148                         }
149                         else {
150                                 cbi_update_table(tbl, [], E('em', { class: 'spinning' }, _('No scan results available yet...')));
151                         }
152
153
154                         if (count++ >= 3) {
155                                 count = 0;
156                                 L.post(L.url('admin/network/wireless_scan_trigger', dev, 1), null, function() {});
157                         }
158                 });
159
160                 L.run();
161         });
162 }
163
164 document.addEventListener('DOMContentLoaded', scan);