lldpd.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * Copyright (c) 2018-2020, Tano Systems LLC. All Rights Reserved.
  3. * Anton Kikin <a.kikin@tano-systems.com>
  4. * Copyright (c) 2023-2024. All Rights Reserved.
  5. * Paul Donald <newtwen+github@gmail.com>
  6. */
  7. 'use strict';
  8. 'require ui';
  9. 'require form';
  10. 'require network';
  11. 'require session';
  12. 'require uci';
  13. /*
  14. * Filter neighbors (-H)
  15. *
  16. * The filter column means that filtering is enabled
  17. * The 1proto column tells that only one protocol will be kept.
  18. * The 1neigh column tells that only one neighbor will be kept.
  19. *
  20. * incoming outgoing
  21. * filter 1proto 1neigh filter 1proto 1neigh
  22. * 0
  23. * 1 x x x x
  24. * 2 x x
  25. * 3 x x
  26. * 4 x x
  27. * 5 x
  28. * 6 x
  29. * 7 x x x x x
  30. * 8 x x x
  31. * 9 x x x x
  32. * 10 x x
  33. * 11 x x
  34. * 12 x x x x
  35. * 13 x x x
  36. * 14 x x x x
  37. * 15 x x x
  38. * 16 x x x x x
  39. * 17 x x x x
  40. * 18 x x x
  41. * 19 x x x
  42. */
  43. const etitle = _('enable filter');
  44. const ptitle = _('keep only one protocol');
  45. const ntitle = _('keep only one neighbor');
  46. var cbiFilterSelect = form.Value.extend({
  47. __name__: 'CBI.LLDPD.FilterSelect',
  48. __init__: function() {
  49. this.super('__init__', arguments);
  50. this.selected = null;
  51. this.filterVal = [
  52. [ 0, 0, 0, 0, 0, 0 ],
  53. [ 1, 1, 0, 1, 1, 0 ],
  54. [ 1, 1, 0, 0, 0, 0 ],
  55. [ 0, 0, 0, 1, 1, 0 ],
  56. [ 1, 0, 0, 1, 0, 0 ],
  57. [ 1, 0, 0, 0, 0, 0 ],
  58. [ 0, 0, 0, 1, 0, 0 ],
  59. [ 1, 1, 1, 1, 1, 0 ],
  60. [ 1, 1, 1, 0, 0, 0 ],
  61. [ 1, 0, 1, 1, 1, 0 ],
  62. [ 0, 0, 0, 1, 0, 1 ],
  63. [ 1, 0, 1, 0, 0, 0 ],
  64. [ 1, 0, 1, 1, 0, 1 ],
  65. [ 1, 0, 1, 1, 0, 0 ],
  66. [ 1, 1, 0, 1, 0, 1 ],
  67. [ 1, 1, 0, 1, 0, 0 ],
  68. [ 1, 1, 1, 1, 0, 1 ],
  69. [ 1, 1, 1, 1, 0, 0 ],
  70. [ 1, 0, 0, 1, 0, 1 ],
  71. [ 1, 0, 0, 1, 1, 0 ]
  72. ];
  73. },
  74. /** @private */
  75. handleRowClick: function(section_id, ev) {
  76. var row = ev.currentTarget;
  77. var tbody = row.parentNode;
  78. var selected = row.getAttribute('data-filter');
  79. var input = tbody.querySelector('[id="' + this.cbid(section_id) + '-' + selected + '"]');
  80. this.selected = selected;
  81. tbody.querySelectorAll('tr').forEach(function(e) {
  82. e.classList.remove('lldpd-filter-selected');
  83. });
  84. input.checked = true;
  85. row.classList.add('lldpd-filter-selected');
  86. },
  87. formvalue: function(section_id) {
  88. return this.selected || this.cfgvalue(section_id);
  89. },
  90. renderFrame: function(section_id, in_table, option_index, nodes) {
  91. var tmp = this.description;
  92. // Prepend description with table legend
  93. this.description =
  94. '<ul><li>' + 'E &mdash; ' + etitle + '</li>' +
  95. '<li>' + 'P &mdash; ' + ptitle + '</li>' +
  96. '<li>' + 'N &mdash; ' + ntitle + '</li>' +
  97. '</ul>' + this.description;
  98. var rendered = this.super('renderFrame', arguments);
  99. // Restore original description
  100. this.description = tmp;
  101. return rendered;
  102. },
  103. renderWidget: function(section_id, option_index, cfgvalue) {
  104. //default value is "15" - rows are zero based
  105. var selected = parseInt(cfgvalue) || 15;
  106. var tbody = [];
  107. var renderFilterVal = L.bind(function(row, col) {
  108. return this.filterVal[row][col] ? '&#x2714;' : '';
  109. }, this);
  110. for (var i = 0; i < this.filterVal.length; i++) {
  111. tbody.push(E('tr', {
  112. 'class': ((selected == i) ? 'lldpd-filter-selected' : ''),
  113. 'click': L.bind(this.handleRowClick, this, section_id),
  114. 'data-filter': i,
  115. }, [
  116. E('td', {}, [
  117. E('input', {
  118. 'class': 'cbi-input-radio',
  119. 'data-update': 'click change',
  120. 'type': 'radio',
  121. 'id': this.cbid(section_id) + '-' + i,
  122. 'name': this.cbid(section_id),
  123. 'checked': (selected == i) ? '' : null,
  124. 'value': i
  125. })
  126. ]),
  127. E('td', {}, i),
  128. E('td', {'title': etitle}, renderFilterVal(i, 0)),
  129. E('td', {'title': ptitle}, renderFilterVal(i, 1)),
  130. E('td', {'title': ntitle}, renderFilterVal(i, 2)),
  131. E('td', {'title': etitle}, renderFilterVal(i, 3)),
  132. E('td', {'title': ptitle}, renderFilterVal(i, 4)),
  133. E('td', {'title': ntitle}, renderFilterVal(i, 5))
  134. ]));
  135. };
  136. var table = E('table', { 'class': 'lldpd-filter', 'id': this.cbid(section_id) }, [
  137. E('thead', {}, [
  138. E('tr', {}, [
  139. E('th', { 'rowspan': 2 }),
  140. E('th', { 'rowspan': 2 }, _('Filter')),
  141. E('th', { 'colspan': 3 }, _('Incoming')),
  142. E('th', { 'colspan': 3 }, _('Outgoing'))
  143. ]),
  144. E('tr', {}, [
  145. E('th', {}, 'E'),
  146. E('th', {}, 'P'),
  147. E('th', {}, 'N'),
  148. E('th', {}, 'E'),
  149. E('th', {}, 'P'),
  150. E('th', {}, 'N'),
  151. ])
  152. ]),
  153. E('tbody', {}, tbody)
  154. ]);
  155. return table;
  156. },
  157. });
  158. var CBIMultiIOSelect = form.MultiValue.extend({
  159. __name__: 'CBI.MultiIOSelect',
  160. renderWidget: function(section_id, option_index, cfgvalue) {
  161. var value = (cfgvalue != null) ? cfgvalue : this.default ? this.default : '',
  162. choices = this.transformChoices() ? this.transformChoices() : '';
  163. var widget = new ui.Dropdown(L.toArray(value), choices, {
  164. id: this.cbid(section_id),
  165. sort: this.keylist,
  166. multiple: true,
  167. optional: true,
  168. display_items: 5,
  169. dropdown_items: -1,
  170. create: true,
  171. disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
  172. validate: L.bind(this.validate, this, section_id),
  173. });
  174. return widget.render();
  175. }
  176. });
  177. function init() {
  178. return new Promise(function(resolveFn, rejectFn) {
  179. var data = session.getLocalData('luci-app-lldpd');
  180. if (data !== null) {
  181. return resolveFn();
  182. }
  183. data = {};
  184. return uci.load('luci').then(function() {
  185. session.setLocalData('luci-app-lldpd', data);
  186. return resolveFn();
  187. });
  188. });
  189. }
  190. return L.Class.extend({
  191. cbiFilterSelect: cbiFilterSelect,
  192. CBIMultiIOSelect: CBIMultiIOSelect,
  193. init: init,
  194. });