X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fluci2%2Fui.git;a=blobdiff_plain;f=luci2%2Fhtdocs%2Fluci2%2Fluci2.js;h=ffa58ea0de2d8ceedf9c119a711c57624940caab;hp=02b0015a4f432ac6c966aaf67a589ae8a1f294ae;hb=b7e255f6d02885cb0d093812e32f4632734d4b6f;hpb=e45ac0ac7ff66f6e832eaee2403760fa191898db diff --git a/luci2/htdocs/luci2/luci2.js b/luci2/htdocs/luci2/luci2.js index 02b0015..ffa58ea 100644 --- a/luci2/htdocs/luci2/luci2.js +++ b/luci2/htdocs/luci2/luci2.js @@ -387,7 +387,7 @@ function LuCI2() }; this.globals = { - timeout: 3000, + timeout: 15000, resource: '/luci2', sid: '00000000000000000000000000000000' }; @@ -584,13 +584,44 @@ function LuCI2() }, - changes: _luci2.rpc.declare({ + configs: _luci2.rpc.declare({ + object: 'uci', + method: 'configs', + expect: { configs: [ ] } + }), + + _changes: _luci2.rpc.declare({ object: 'uci', method: 'changes', params: [ 'config' ], expect: { changes: [ ] } }), + changes: function(config) + { + if (typeof(config) == 'string') + return this._changes(config); + + var configlist; + return this.configs().then(function(configs) { + _luci2.rpc.batch(); + configlist = configs; + + for (var i = 0; i < configs.length; i++) + _luci2.uci._changes(configs[i]); + + return _luci2.rpc.flush(); + }).then(function(changes) { + var rv = { }; + + for (var i = 0; i < configlist.length; i++) + if (changes[i].length) + rv[configlist[i]] = changes[i]; + + return rv; + }); + }, + commit: _luci2.rpc.declare({ object: 'uci', method: 'commit', @@ -757,13 +788,13 @@ function LuCI2() var net = nets[i] = networks[i]; var dev = net.l3_device || net.l2_device; if (dev) - net.device = devs[dev] = { }; + net.device = devs[dev] || (devs[dev] = { }); } _luci2.rpc.batch(); for (var dev in devs) - _luci2.network.listDeviceNamestatus(dev); + _luci2.network.getDeviceStatus(dev); return _luci2.rpc.flush(); }).then(function(devices) { @@ -786,7 +817,7 @@ function LuCI2() if (!devs[brm[j]]) { devs[brm[j]] = { }; - _luci2.network.listDeviceNamestatus(brm[j]); + _luci2.network.getDeviceStatus(brm[j]); } devs[devices[i]['device']].subdevices[j] = devs[brm[j]]; @@ -836,6 +867,9 @@ function LuCI2() for (var i = 0; i < interfaces.length; i++) { + if (!interfaces[i].route) + continue; + for (var j = 0; j < interfaces[i].route.length; j++) { var rt = interfaces[i].route[j]; @@ -897,7 +931,7 @@ function LuCI2() } }), - listDeviceNamestatus: _luci2.rpc.declare({ + getDeviceStatus: _luci2.rpc.declare({ object: 'network.device', method: 'status', params: [ 'name' ], @@ -912,6 +946,73 @@ function LuCI2() object: 'luci2.network', method: 'conntrack_count', expect: { '': { count: 0, limit: 0 } } + }), + + listSwitchNames: _luci2.rpc.declare({ + object: 'luci2.network', + method: 'switch_list', + expect: { switches: [ ] } + }), + + getSwitchInfo: _luci2.rpc.declare({ + object: 'luci2.network', + method: 'switch_info', + params: [ 'switch' ], + expect: { info: { } }, + filter: function(data, params) { + data['attrs'] = data['switch']; + data['vlan_attrs'] = data['vlan']; + data['port_attrs'] = data['port']; + data['switch'] = params['switch']; + + delete data.vlan; + delete data.port; + + return data; + } + }), + + getSwitchStatus: _luci2.rpc.declare({ + object: 'luci2.network', + method: 'switch_status', + params: [ 'switch' ], + expect: { ports: [ ] } + }), + + + runPing: _luci2.rpc.declare({ + object: 'luci2.network', + method: 'ping', + params: [ 'data' ], + expect: { '': { code: -1 } } + }), + + runPing6: _luci2.rpc.declare({ + object: 'luci2.network', + method: 'ping6', + params: [ 'data' ], + expect: { '': { code: -1 } } + }), + + runTraceroute: _luci2.rpc.declare({ + object: 'luci2.network', + method: 'traceroute', + params: [ 'data' ], + expect: { '': { code: -1 } } + }), + + runTraceroute6: _luci2.rpc.declare({ + object: 'luci2.network', + method: 'traceroute6', + params: [ 'data' ], + expect: { '': { code: -1 } } + }), + + runNslookup: _luci2.rpc.declare({ + object: 'luci2.network', + method: 'nslookup', + params: [ 'data' ], + expect: { '': { code: -1 } } }) }; @@ -2003,6 +2104,9 @@ function LuCI2() { var name = node.view.split(/\//).join('.'); + if (_luci2.globals.currentView) + _luci2.globals.currentView.finish(); + _luci2.ui.renderViewMenu(); if (!_luci2._views) @@ -2011,7 +2115,10 @@ function LuCI2() _luci2.setHash('view', node.view); if (_luci2._views[name] instanceof _luci2.ui.view) + { + _luci2.globals.currentView = _luci2._views[name]; return _luci2._views[name].render(); + } var url = _luci2.globals.resource + '/view/' + name + '.js'; @@ -2022,7 +2129,7 @@ function LuCI2() }).then(function(data) { try { var viewConstructorSource = ( - '(function(L, $) {\n' + + '(function(L, $) { ' + 'return %s' + '})(_luci2, $);\n\n' + '//@ sourceURL=%s' @@ -2035,6 +2142,7 @@ function LuCI2() acls: node.write || { } }); + _luci2.globals.currentView = _luci2._views[name]; return _luci2._views[name].render(); } catch(e) { @@ -2053,12 +2161,90 @@ function LuCI2() }); }, + updateChanges: function() + { + return _luci2.uci.changes().then(function(changes) { + var n = 0; + var html = ''; + + for (var config in changes) + { + var log = [ ]; + + for (var i = 0; i < changes[config].length; i++) + { + var c = changes[config][i]; + + switch (c[0]) + { + case 'order': + break; + + case 'remove': + if (c.length < 3) + log.push('uci delete %s.%s'.format(config, c[1])); + else + log.push('uci delete %s.%s.%s'.format(config, c[1], c[2])); + break; + + case 'rename': + if (c.length < 4) + log.push('uci rename %s.%s=%s'.format(config, c[1], c[2], c[3])); + else + log.push('uci rename %s.%s.%s=%s'.format(config, c[1], c[2], c[3], c[4])); + break; + + case 'add': + log.push('uci add %s %s (= %s)'.format(config, c[2], c[1])); + break; + + case 'list-add': + log.push('uci add_list %s.%s.%s=%s'.format(config, c[1], c[2], c[3], c[4])); + break; + + case 'list-del': + log.push('uci del_list %s.%s.%s=%s'.format(config, c[1], c[2], c[3], c[4])); + break; + + case 'set': + if (c.length < 4) + log.push('uci set %s.%s=%s'.format(config, c[1], c[2])); + else + log.push('uci set %s.%s.%s=%s'.format(config, c[1], c[2], c[3], c[4])); + break; + } + } + + html += '/etc/config/%s
%s
'.format(config, log.join('\n')); + n += changes[config].length; + } + + if (n > 0) + $('#changes') + .empty() + .show() + .append($('') + .attr('href', '#') + .addClass('label') + .addClass('notice') + .text(_luci2.trcp('Pending configuration changes', '1 change', '%d changes', n).format(n)) + .click(function(ev) { + _luci2.ui.dialog(_luci2.tr('Staged configuration changes'), html, { style: 'close' }); + ev.preventDefault(); + })); + else + $('#changes') + .hide(); + }); + }, + init: function() { _luci2.ui.loading(true); $.when( _luci2.ui.updateHostname(), + _luci2.ui.updateChanges(), _luci2.ui.renderMainMenu() ).then(function() { _luci2.ui.renderView(_luci2.globals.defaultNode).then(function() { @@ -2137,6 +2323,42 @@ function LuCI2() return this._fetch_template().then(function() { return _luci2.deferrable(self.execute()); }); + }, + + repeat: function(func, interval) + { + var self = this; + + if (!self._timeouts) + self._timeouts = [ ]; + + var index = self._timeouts.length; + + if (typeof(interval) != 'number') + interval = 5000; + + var setTimer, runTimer; + + setTimer = function() { + self._timeouts[index] = window.setTimeout(runTimer, interval); + }; + + runTimer = function() { + _luci2.deferrable(func.call(self)).then(setTimer); + }; + + runTimer(); + }, + + finish: function() + { + if ($.isArray(this._timeouts)) + { + for (var i = 0; i < this._timeouts.length; i++) + window.clearTimeout(this._timeouts[i]); + + delete this._timeouts; + } } }); @@ -2190,7 +2412,10 @@ function LuCI2() var child = this.firstChildView(nodes[i]); if (child) { - $.extend(node, child); + for (var key in child) + if (!node.hasOwnProperty(key) && child.hasOwnProperty(key)) + node[key] = child[key]; + return node; } } @@ -2475,7 +2700,9 @@ function LuCI2() this.ui.devicebadge = AbstractWidget.extend({ render: function() { - var dev = this.options.l3_device || this.options.device || '?'; + var l2dev = this.options.l2_device || this.options.device; + var l3dev = this.options.l3_device; + var dev = l3dev || l2dev || '?'; var span = document.createElement('span'); span.className = 'ifacebadge'; @@ -2516,7 +2743,7 @@ function LuCI2() var type = 'ethernet'; var desc = _luci2.tr('Ethernet device'); - if (this.options.l3_device != this.options.device) + if (l3dev != l2dev) { type = 'tunnel'; desc = _luci2.tr('Tunnel interface'); @@ -2766,6 +2993,7 @@ function LuCI2() } } + validation.i18n('Must be a valid IPv6 address'); return false; }, @@ -3469,12 +3697,10 @@ function LuCI2() if (chg) { - val = val ? this.options.enabled : this.options.disabled; - if (this.options.optional && val == this.options.initial) this.map.set(uci.config, uci.section, uci.option, undefined); else - this.map.set(uci.config, uci.section, uci.option, val); + this.map.set(uci.config, uci.section, uci.option, val ? this.options.enabled : this.options.disabled); } return chg; @@ -5396,7 +5622,9 @@ function LuCI2() _luci2.uci['delete'](c, s, (o === true) ? undefined : o); } - return _luci2.rpc.flush(); + return _luci2.rpc.flush().then(function() { + return _luci2.ui.updateChanges(); + }); }, this)); var self = this; @@ -5415,33 +5643,6 @@ function LuCI2() }); }, - dialog: function(id) - { - var d = $('
'); - var p = $('

'); - - $('') - .attr('src', _luci2.globals.resource + '/icons/loading.gif') - .css('vertical-align', 'middle') - .css('padding-right', '10px') - .appendTo(p); - - p.append(_luci2.tr('Loading data...')); - - p.appendTo(d); - d.appendTo(id); - - return d.dialog({ - modal: true, - draggable: false, - resizable: false, - height: 90, - open: function() { - $(this).parent().children('.ui-dialog-titlebar').hide(); - } - }); - }, - insertInto: function(id) { var self = this;