From ac96b8be436c95eed5fffdb2117e3c8d7a79dcb0 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 22 Jul 2019 16:31:25 +0200 Subject: luci-base: widgets.js: implement CBIDeviceSelect netdev picker Signed-off-by: Jo-Philipp Wich --- .../htdocs/luci-static/resources/tools/widgets.js | 113 ++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) (limited to 'modules/luci-base/htdocs') diff --git a/modules/luci-base/htdocs/luci-static/resources/tools/widgets.js b/modules/luci-base/htdocs/luci-static/resources/tools/widgets.js index 0e023a78b..39e5aa165 100644 --- a/modules/luci-base/htdocs/luci-static/resources/tools/widgets.js +++ b/modules/luci-base/htdocs/luci-static/resources/tools/widgets.js @@ -416,9 +416,120 @@ var CBINetworkSelect = form.ListValue.extend({ }, }); +var CBIDeviceSelect = form.ListValue.extend({ + __name__: 'CBI.DeviceSelect', + + load: function(section_id) { + return network.getDevices().then(L.bind(function(devices) { + this.devices = devices; + + return this.super('load', section_id); + }, this)); + }, + + filter: function(section_id, value) { + return true; + }, + + renderWidget: function(section_id, option_index, cfgvalue) { + var values = L.toArray((cfgvalue != null) ? cfgvalue : this.default), + choices = {}, + checked = {}, + order = []; + + for (var i = 0; i < values.length; i++) + checked[values[i]] = true; + + values = []; + + if (!this.multiple && (this.rmempty || this.optional)) + choices[''] = E('em', _('unspecified')); + + for (var i = 0; i < this.devices.length; i++) { + var device = this.devices[i], + name = device.getName(), + type = device.getType(); + + if (name == 'lo' || name == this.exclude || !this.filter(section_id, name)) + continue; + + if (this.noaliases && type == 'alias') + continue; + + if (this.nobridges && type == 'bridge') + continue; + + if (this.noinactive && device.isUp() == false) + continue; + + var item = E([ + E('img', { + 'title': device.getI18n(), + 'src': L.resource('icons/%s%s.png'.format(type, device.isUp() ? '' : '_disabled')) + }), + E('span', { 'class': 'hide-open' }, [ name ]), + E('span', { 'class': 'hide-close'}, [ device.getI18n() ]) + ]); + + var networks = device.getNetworks(); + + if (networks.length > 0) + L.dom.append(item.lastChild, [ ' (', networks.join(', '), ')' ]); + + if (checked[name]) + values.push(name); + + choices[name] = item; + order.push(name); + } + + if (!this.nocreate) { + var keys = Object.keys(checked).sort(); + + for (var i = 0; i < keys.length; i++) { + if (choices.hasOwnProperty(keys[i])) + continue; + + choices[keys[i]] = E([ + E('img', { + 'title': _('Absent Interface'), + 'src': L.resource('icons/ethernet_disabled.png') + }), + E('span', { 'class': 'hide-open' }, [ keys[i] ]), + E('span', { 'class': 'hide-close'}, [ '%s: "%h"'.format(_('Absent Interface'), keys[i]) ]) + ]); + + values.push(keys[i]); + order.push(keys[i]); + } + } + + var widget = new ui.Dropdown(this.multiple ? values : values[0], choices, { + id: this.cbid(section_id), + sort: order, + multiple: this.multiple, + optional: this.optional || this.rmempty, + select_placeholder: E('em', _('unspecified')), + display_items: this.display_size || this.size || 3, + dropdown_items: this.dropdown_size || this.size || 5, + validate: L.bind(this.validate, this, section_id), + create: !this.nocreate, + create_markup: '' + + '
  • ' + + '' + + '{{value}}' + + ''+_('Custom Interface')+': "{{value}}"' + + '
  • ' + }); + + return widget.render(); + }, +}); + return L.Class.extend({ ZoneSelect: CBIZoneSelect, ZoneForwards: CBIZoneForwards, - NetworkSelect: CBINetworkSelect + NetworkSelect: CBINetworkSelect, + DeviceSelect: CBIDeviceSelect, }); -- cgit v1.2.3