summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-mod-system/htdocs/luci-static/resources/view/system
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2019-04-01 16:53:52 +0200
committerJo-Philipp Wich <jo@mein.io>2019-07-07 15:36:24 +0200
commit675824e377cee636beaaa003ce7dcf346ae148ab (patch)
treeb72adc0595d6c2945c85fc34ebafea2115a6b797 /modules/luci-mod-system/htdocs/luci-static/resources/view/system
parentc7a9900c8734f19e34af5bd4a4106566d4ca3ca1 (diff)
luci-mod-system: use client side cbi forms for system and led config
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'modules/luci-mod-system/htdocs/luci-static/resources/view/system')
-rw-r--r--modules/luci-mod-system/htdocs/luci-static/resources/view/system/leds.js144
-rw-r--r--modules/luci-mod-system/htdocs/luci-static/resources/view/system/system.js285
2 files changed, 429 insertions, 0 deletions
diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/leds.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/leds.js
new file mode 100644
index 0000000000..eba366519f
--- /dev/null
+++ b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/leds.js
@@ -0,0 +1,144 @@
+'use strict';
+'require uci';
+'require rpc';
+'require form';
+
+return L.view.extend({
+ callInitAction: rpc.declare({
+ object: 'luci',
+ method: 'initCall',
+ params: [ 'name', 'action' ],
+ expect: { result: false }
+ }),
+
+ callLeds: rpc.declare({
+ object: 'luci',
+ method: 'leds'
+ }),
+
+ callUSB: rpc.declare({
+ object: 'luci',
+ method: 'usb'
+ }),
+
+ callNetdevs: rpc.declare({
+ object: 'luci',
+ method: 'ifaddrs',
+ expect: { result: [] },
+ filter: function(res) {
+ var devs = {};
+ for (var i = 0; i < res.length; i++)
+ devs[res[i].name] = true;
+ return Object.keys(devs).sort();
+ }
+ }),
+
+ load: function() {
+ rpc.batch();
+ this.callLeds();
+ this.callUSB();
+ this.callNetdevs();
+ return rpc.flush();
+ },
+
+ render: function(results) {
+ var leds = results[0],
+ usb = results[1],
+ netdevs = results[2],
+ triggers = {},
+ trigger, m, s, o;
+
+ for (var k in leds)
+ for (var i = 0; i < leds[k].triggers.length; i++)
+ triggers[leds[k].triggers[i]] = true;
+
+ m = new form.Map('system',
+ _('<abbr title="Light Emitting Diode">LED</abbr> Configuration'),
+ _('Customizes the behaviour of the device <abbr title="Light Emitting Diode">LED</abbr>s if possible.'));
+
+ s = m.section(form.TypedSection, 'led', '');
+ s.anonymous = true;
+ s.addremove = true;
+
+ s.option(form.Value, 'name', _('Name'));
+
+ o = s.option(form.ListValue, 'sysfs', _('<abbr title="Light Emitting Diode">LED</abbr> Name'));
+ Object.keys(leds).sort().forEach(function(name) { o.value(name) });
+
+ o = s.option(form.Flag, 'default', _('Default state'));
+ o.rmempty = false;
+
+ trigger = s.option(form.ListValue, 'trigger', _('Trigger'));
+ Object.keys(triggers).sort().forEach(function(t) { trigger.value(t, t.replace(/-/g, '')) });
+ trigger.value('usbdev');
+ trigger.value('usbport');
+
+ o = s.option(form.Value, 'delayon', _('On-State Delay'));
+ o.depends('trigger', 'timer');
+
+ o = s.option(form.Value, 'delayoff', _('Off-State Delay'));
+ o.depends('trigger', 'timer');
+
+ o = s.option(form.ListValue, '_net_dev', _('Device'));
+ o.rmempty = true;
+ o.ucioption = 'dev';
+ o.depends('trigger', 'netdev');
+ o.remove = function(section_id) {
+ var t = trigger.formvalue(section_id);
+ if (t != 'netdev' && t != 'usbdev')
+ uci.unset('system', section_id, 'dev');
+ };
+ o.value('');
+ netdevs.sort().forEach(function(dev) { o.value(dev) });
+
+ o = s.option(form.MultiValue, 'mode', _('Trigger Mode'));
+ o.rmempty = true;
+ o.depends('trigger', 'netdev');
+ o.value('link', _('Link On'));
+ o.value('tx', _('Transmit'));
+ o.value('rx', _('Receive'));
+
+ o = s.option(form.ListValue, '_usb_dev', _('USB Device'));
+ o.depends('trigger', 'usbdev');
+ o.rmempty = true;
+ o.ucioption = 'dev';
+ o.remove = function(section_id) {
+ var t = trigger.formvalue(section_id);
+ if (t != 'netdev' && t != 'usbdev')
+ uci.unset('system', section_id, 'dev');
+ }
+ o.value('');
+ (usb.devices || []).forEach(function(usbdev) {
+ o.value(usbdev.id, '%s (%s - %s)'.format(usbdev.id, usbdev.vendor || '?', usbdev.product || '?'));
+ });
+
+ o = s.option(form.MultiValue, 'port', _('USB Ports'));
+ o.depends('trigger', 'usbport');
+ o.rmempty = true;
+ o.cfgvalue = function(section_id) {
+ var ports = [],
+ value = uci.get('system', section_id, 'port');
+
+ if (!Array.isArray(value))
+ value = String(value || '').split(/\s+/);
+
+ for (var i = 0; i < value.length; i++)
+ if (value[i].match(/^usb(\d+)-port(\d+)$/))
+ ports.push(value[i]);
+ else if (value[i].match(/^(\d+)-(\d+)$/))
+ ports.push('usb%d-port%d'.format(Regexp.$1, Regexp.$2));
+
+ return ports;
+ };
+ (usb.ports || []).forEach(function(usbport) {
+ o.value('usb%d-port%d'.format(usbport.hub, usbport.port),
+ 'Hub %d, Port %d'.format(usbport.hub, usbport.port));
+ });
+
+ o = s.option(form.Value, 'port_mask', _('Switch Port Mask'));
+ o.depends('trigger', 'switch0');
+ o.depends('trigger', 'switch1');
+
+ return m.render();
+ }
+});
diff --git a/modules/luci-mod-system/htdocs/luci-static/resources/view/system/system.js b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/system.js
new file mode 100644
index 0000000000..bbe483c0ab
--- /dev/null
+++ b/modules/luci-mod-system/htdocs/luci-static/resources/view/system/system.js
@@ -0,0 +1,285 @@
+'use strict';
+'require uci';
+'require rpc';
+'require form';
+
+return L.view.extend({
+ callInitList: rpc.declare({
+ object: 'luci',
+ method: 'initList',
+ params: [ 'name' ],
+ expect: { result: {} },
+ filter: function(res) {
+ for (var k in res)
+ return +res[k].enabled;
+ return null;
+ }
+ }),
+
+ callInitAction: rpc.declare({
+ object: 'luci',
+ method: 'initCall',
+ params: [ 'name', 'action' ],
+ expect: { result: false }
+ }),
+
+ callLocaltime: rpc.declare({
+ object: 'luci',
+ method: 'localtime',
+ expect: { localtime: 0 }
+ }),
+
+ callTimezone: rpc.declare({
+ object: 'luci',
+ method: 'timezone',
+ expect: { result: {} }
+ }),
+
+ CBILocalTime: form.DummyValue.extend({
+ renderWidget: function(section_id, option_id, cfgvalue) {
+ return E([], [
+ E('span', { 'id': 'localtime' },
+ new Date(cfgvalue * 1000).toLocaleString()),
+ ' ',
+ E('button', {
+ 'class': 'cbi-button cbi-button-apply',
+ 'click': L.bind(function(ev) {
+ ev.target.blur();
+ ev.target.classList.add('spinning');
+ ev.target.disabled = true;
+ this.callLocaltime(Math.floor(Date.now() / 1000)).then(function() {
+ ev.target.classList.remove('spinning');
+ ev.target.disabled = false;
+ });
+ }, this)
+ }, _('Sync with browser')),
+ ' ',
+ this.ntpd_support ? E('button', {
+ 'class': 'cbi-button cbi-button-apply',
+ 'click': L.bind(function(ev) {
+ ev.target.blur();
+ ev.target.classList.add('spinning');
+ ev.target.disabled = true;
+ this.callLocaltime(Math.floor(Date.now() / 1000)).then(function() {
+ ev.target.classList.remove('spinning');
+ ev.target.disabled = false;
+ });
+ }, this)
+ }, _('Sync with NTP-Server')) : ''
+ ]);
+ },
+ }),
+
+ load: function() {
+ rpc.batch();
+ this.callInitList('sysntpd');
+ this.callInitList('zram');
+ this.callTimezone();
+ this.callLocaltime();
+ uci.load('luci');
+ uci.load('system');
+ return rpc.flush();
+ },
+
+ render: function(rpc_replies) {
+ var ntpd_support = rpc_replies[0],
+ zram_support = rpc_replies[1],
+ timezones = rpc_replies[2],
+ localtime = rpc_replies[3],
+ view = this,
+ ntp_setup, ntp_enabled, m, s, o;
+
+ m = new form.Map('system',
+ _('System'),
+ _('Here you can configure the basic aspects of your device like its hostname or the timezone.'));
+
+ m.chain('luci');
+ m.tabbed = true;
+
+ s = m.section(form.TypedSection, 'system', _('System Properties'));
+ s.anonymous = true;
+ s.addremove = false;
+
+ s.tab('general', _('General Settings'));
+ s.tab('logging', _('Logging'));
+ s.tab('timesync', _('Time Synchronization'));
+ s.tab('language', _('Language and Style'));
+
+ /*
+ * System Properties
+ */
+
+ o = s.taboption('general', this.CBILocalTime, '_systime', _('Local Time'));
+ o.cfgvalue = function() { return localtime };
+ o.ntpd_support = ntpd_support;
+
+ o = s.taboption('general', form.Value, 'hostname', _('Hostname'));
+ o.datatype = 'hostname';
+
+ o = s.taboption('general', form.ListValue, 'zonename', _('Timezone'));
+ o.value('UTC');
+
+ var zones = Object.keys(timezones || {}).sort();
+ for (var i = 0; i < zones.length; i++)
+ o.value(zones[i]);
+
+ o.write = function(section_id, formvalue) {
+ var tz = timezones[formvalue] ? timezones[formvalue].tzstring : null;
+ uci.set('system', section_id, 'zonename', formvalue);
+ uci.set('system', section_id, 'timezone', tz);
+ };
+
+ /*
+ * Logging
+ */
+
+ o = s.taboption('logging', form.Value, 'log_size', _('System log buffer size'), "kiB")
+ o.optional = true
+ o.placeholder = 16
+ o.datatype = 'uinteger'
+
+ o = s.taboption('logging', form.Value, 'log_ip', _('External system log server'))
+ o.optional = true
+ o.placeholder = '0.0.0.0'
+ o.datatype = 'ip4addr'
+
+ o = s.taboption('logging', form.Value, 'log_port', _('External system log server port'))
+ o.optional = true
+ o.placeholder = 514
+ o.datatype = 'port'
+
+ o = s.taboption('logging', form.ListValue, 'log_proto', _('External system log server protocol'))
+ o.value('udp', 'UDP')
+ o.value('tcp', 'TCP')
+
+ o = s.taboption('logging', form.Value, 'log_file', _('Write system log to file'))
+ o.optional = true
+ o.placeholder = '/tmp/system.log'
+
+ o = s.taboption('logging', form.ListValue, 'conloglevel', _('Log output level'))
+ o.value(8, _('Debug'))
+ o.value(7, _('Info'))
+ o.value(6, _('Notice'))
+ o.value(5, _('Warning'))
+ o.value(4, _('Error'))
+ o.value(3, _('Critical'))
+ o.value(2, _('Alert'))
+ o.value(1, _('Emergency'))
+
+ o = s.taboption('logging', form.ListValue, 'cronloglevel', _('Cron Log Level'))
+ o.default = 8
+ o.value(5, _('Debug'))
+ o.value(8, _('Normal'))
+ o.value(9, _('Warning'))
+
+ /*
+ * Zram Properties
+ */
+
+ if (zram_support != null) {
+ s.tab('zram', _('ZRam Settings'));
+
+ o = s.taboption('zram', form.Value, 'zram_size_mb', _('ZRam Size'), _('Size of the ZRam device in megabytes'));
+ o.optional = true;
+ o.placeholder = 16;
+ o.datatype = 'uinteger';
+
+ o = s.taboption('zram', form.ListValue, 'zram_comp_algo', _('ZRam Compression Algorithm'));
+ o.optional = true;
+ o.placeholder = 'lzo';
+ o.value('lzo', 'lzo');
+ o.value('lz4', 'lz4');
+ o.value('deflate', 'deflate');
+
+ o = s.taboption('zram', form.Value, 'zram_comp_streams', _('ZRam Compression Streams'), _('Number of parallel threads used for compression'));
+ o.optional = true;
+ o.placeholder = 1;
+ o.datatype = 'uinteger';
+ }
+
+ /*
+ * Language & Style
+ */
+
+ o = s.taboption('language', form.ListValue, '_lang', _('Language'))
+ o.uciconfig = 'luci';
+ o.ucisection = 'main';
+ o.ucioption = 'lang';
+ o.value('auto');
+
+ var k = Object.keys(uci.get('luci', 'languages') || {}).sort();
+ for (var i = 0; i < k.length; i++)
+ if (k[i].charAt(0) != '.')
+ o.value(k[i], uci.get('luci', 'languages', k[i]));
+
+ o = s.taboption('language', form.ListValue, '_mediaurlbase', _('Design'))
+ o.uciconfig = 'luci';
+ o.ucisection = 'main';
+ o.ucioption = 'mediaurlbase';
+
+ var k = Object.keys(uci.get('luci', 'themes') || {}).sort();
+ for (var i = 0; i < k.length; i++)
+ if (k[i].charAt(0) != '.')
+ o.value(uci.get('luci', 'themes', k[i]), k[i]);
+
+ /*
+ * NTP
+ */
+
+ if (ntpd_support != null) {
+ var default_servers = [
+ '0.openwrt.pool.ntp.org', '1.openwrt.pool.ntp.org',
+ '2.openwrt.pool.ntp.org', '3.openwrt.pool.ntp.org'
+ ];
+
+ o = s.taboption('timesync', form.Flag, 'enabled', _('Enable NTP client'));
+ o.rmempty = false;
+ o.ucisection = 'ntp';
+ o.default = o.disabled;
+ o.write = function(section_id, value) {
+ ntpd_support = +value;
+
+ if (ntpd_support && !uci.get('system', 'ntp')) {
+ uci.add('system', 'timeserver', 'ntp');
+ uci.set('system', 'ntp', 'server', default_servers);
+ }
+
+ if (!ntpd_support)
+ uci.set('system', 'ntp', 'enabled', 0);
+ else
+ uci.unset('system', 'ntp', 'enabled');
+
+ return view.callInitAction('sysntpd', 'enable');
+ };
+ o.load = function(section_id) {
+ return (ntpd_support == 1 &&
+ uci.get('system', 'ntp') != null &&
+ uci.get('system', 'ntp', 'enabled') != 0) ? '1' : '0';
+ };
+
+ o = s.taboption('timesync', form.Flag, 'enable_server', _('Provide NTP server'));
+ o.ucisection = 'ntp';
+ o.depends('enabled', '1');
+
+ o = s.taboption('timesync', form.DynamicList, 'server', _('NTP server candidates'));
+ o.datatype = 'host(0)';
+ o.ucisection = 'ntp';
+ o.depends('enabled', '1');
+ o.remove = function() {}; // retain server list even if disabled
+ o.load = function(section_id) {
+ return uci.get('system', 'ntp')
+ ? uci.get('system', 'ntp', 'server')
+ : default_servers;
+ };
+ }
+
+ window.setInterval(L.bind(function() {
+ this.callLocaltime().then(function(t) {
+ var lt = document.getElementById('localtime');
+ if (lt) lt.innerHTML = new Date(t * 1000).toLocaleString();
+ });
+ }, this), 5000);
+
+ return m.render();
+ }
+});