};
this.globals = {
- timeout: 3000,
+ timeout: 15000,
resource: '/luci2',
sid: '00000000000000000000000000000000'
};
},
- 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',
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) {
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]];
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];
}
}),
- listDeviceNamestatus: _luci2.rpc.declare({
+ getDeviceStatus: _luci2.rpc.declare({
object: 'network.device',
method: 'status',
params: [ 'name' ],
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: [ ] }
})
};
{
var name = node.view.split(/\//).join('.');
+ if (_luci2.globals.currentView)
+ _luci2.globals.currentView.finish();
+
_luci2.ui.renderViewMenu();
if (!_luci2._views)
_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';
}).then(function(data) {
try {
var viewConstructorSource = (
- '(function(L, $) {\n' +
+ '(function(L, $) { ' +
'return %s' +
'})(_luci2, $);\n\n' +
'//@ sourceURL=%s'
acls: node.write || { }
});
+ _luci2.globals.currentView = _luci2._views[name];
return _luci2._views[name].render();
}
catch(e) {
});
},
+ 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.<del>%s</del>'.format(config, c[1]));
+ else
+ log.push('uci delete %s.%s.<del>%s</del>'.format(config, c[1], c[2]));
+ break;
+
+ case 'rename':
+ if (c.length < 4)
+ log.push('uci rename %s.<ins>%s=<strong>%s</strong></ins>'.format(config, c[1], c[2], c[3]));
+ else
+ log.push('uci rename %s.%s.<ins>%s=<strong>%s</strong></ins>'.format(config, c[1], c[2], c[3], c[4]));
+ break;
+
+ case 'add':
+ log.push('uci add %s <ins>%s</ins> (= <ins><strong>%s</strong></ins>)'.format(config, c[2], c[1]));
+ break;
+
+ case 'list-add':
+ log.push('uci add_list %s.%s.<ins>%s=<strong>%s</strong></ins>'.format(config, c[1], c[2], c[3], c[4]));
+ break;
+
+ case 'list-del':
+ log.push('uci del_list %s.%s.<del>%s=<strong>%s</strong></del>'.format(config, c[1], c[2], c[3], c[4]));
+ break;
+
+ case 'set':
+ if (c.length < 4)
+ log.push('uci set %s.<ins>%s=<strong>%s</strong></ins>'.format(config, c[1], c[2]));
+ else
+ log.push('uci set %s.%s.<ins>%s=<strong>%s</strong></ins>'.format(config, c[1], c[2], c[3], c[4]));
+ break;
+ }
+ }
+
+ html += '<code>/etc/config/%s</code><pre class="uci-changes">%s</pre>'.format(config, log.join('\n'));
+ n += changes[config].length;
+ }
+
+ if (n > 0)
+ $('#changes')
+ .empty()
+ .show()
+ .append($('<a />')
+ .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() {
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;
+ }
}
});
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;
}
}
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;
_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;