diff --git a/.eslintrc b/.eslintrc index 64cc9dafb5c0079852a694eb28f91cfabe6f03f9..35fcf812c52bbe09b314d5fc27dcbd243e139f55 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,3 +10,4 @@ rules: "guard-for-in": 0 "no-undefined": 0 "no-nested-ternary": 0 + "no-extend-native": ["error", { "exceptions": ["String"] }] diff --git a/README.md b/README.md index 0e89f18e9fb3765b38b10518805596a5bf36209f..83857c3a682cfd9827f9b7eb7bcb264ba88a5239 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ - Add modes - For example add a night layer and style - Updates selected node or list (incl. image stats cache-breaker) - not only overview tables +- Node filter is implemented - Zoom level if you click a node (`nodeZoom`) - Zoom level 22 available, but it is to close for a click - Formatted Code - Translation support - https://crowdin.com/project/meshviewer diff --git a/app.js b/app.js index 6e8875f37e06d1660c70bcb7894e1d65454e37a7..040129310f2b1f2263823ab1cfdb6beeb2c6ae30 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,10 @@ 'use strict'; +// Node search polyfill for mobile browsers and IE +if (!String.prototype.includes) { + String.prototype.includes = function () { + return String.prototype.indexOf.apply(this, arguments) !== -1; + }; +} require.config({ baseUrl: 'lib', diff --git a/assets/icons/fonts/icon.ttf b/assets/icons/fonts/icon.ttf index 8b8d8221cc5bfa2d9530bb615bce4ea55a9ed94d..bf938cc1ca9d7e1c1cff49c6fb6ba71676618cde 100644 Binary files a/assets/icons/fonts/icon.ttf and b/assets/icons/fonts/icon.ttf differ diff --git a/assets/icons/fonts/icon.woff b/assets/icons/fonts/icon.woff index 7cc19f45434c92dfaadee96d32043182541c9272..ef0bc9e665b038c8791e022cb2cf25f55ac21e1d 100644 Binary files a/assets/icons/fonts/icon.woff and b/assets/icons/fonts/icon.woff differ diff --git a/assets/icons/fonts/icon.woff2 b/assets/icons/fonts/icon.woff2 index 0377338e069c95378c91bcf8ce06f6efe4592d5a..6d92253e7578fafaddf0164cbe174567eb2b03d3 100644 Binary files a/assets/icons/fonts/icon.woff2 and b/assets/icons/fonts/icon.woff2 differ diff --git a/assets/icons/icon.scss b/assets/icons/icon.scss index d589691b6fc75c35c4106eff41c4d9922dc9b5c2..89ca76aa73094550f65ba855208400ebf6cbeff0 100644 --- a/assets/icons/icon.scss +++ b/assets/icons/icon.scss @@ -43,3 +43,4 @@ @include icon('android-remove', '\f2f4'); @include icon('ios-person', '\f47e'); @include icon('layer', '\f229'); +@include icon('filter', '\f38B'); diff --git a/lib/filters/hostname.js b/lib/filters/hostname.js new file mode 100644 index 0000000000000000000000000000000000000000..b311c076afb51b56367a3a25aefe3fc5dd240512 --- /dev/null +++ b/lib/filters/hostname.js @@ -0,0 +1,41 @@ +define(function () { + 'use strict'; + + return function () { + var refreshFunctions = []; + var timer; + var input = document.createElement('input'); + + function refresh() { + clearTimeout(timer); + timer = setTimeout(function () { + refreshFunctions.forEach(function (f) { + f(); + }); + }, 250); + } + + function run(d) { + return (d.nodeinfo !== undefined ? d.nodeinfo.hostname.toLowerCase().includes(input.value.toLowerCase()) : ''); + } + + function setRefresh(f) { + refreshFunctions.push(f); + } + + function render(el) { + input.type = 'search'; + input.placeholder = _.t('sidebar.nodeFilter'); + input.addEventListener('input', refresh); + el.classList.add('filter-node'); + el.classList.add('ion-filter'); + el.appendChild(input); + } + + return { + run: run, + setRefresh: setRefresh, + render: render + }; + }; +}); diff --git a/lib/gui.js b/lib/gui.js index 815a839a8db449185c0a661ca43a3eccb4efd36e..b195a7515501f4c2026ecfa558751d129f58323a 100644 --- a/lib/gui.js +++ b/lib/gui.js @@ -1,10 +1,10 @@ define(['chroma-js', 'map', 'sidebar', 'tabs', 'container', 'legend', 'linklist', 'nodelist', 'simplenodelist', 'infobox/main', 'proportions', 'forcegraph', 'title', 'about', 'datadistributor', - 'filters/filtergui'], + 'filters/filtergui', 'filters/hostname'], function (chroma, Map, Sidebar, Tabs, Container, Legend, Linklist, Nodelist, SimpleNodelist, Infobox, Proportions, ForceGraph, - Title, About, DataDistributor, FilterGUI) { + Title, About, DataDistributor, FilterGUI, HostnameFilter) { 'use strict'; return function (config, router) { @@ -105,6 +105,9 @@ define(['chroma-js', 'map', 'sidebar', 'tabs', 'container', 'legend', fanout.watchFilters(filterGUI); header.add(filterGUI); + var hostnameFilter = new HostnameFilter(); + fanout.addFilter(hostnameFilter); + sidebar.add(tabs); tabs.add('sidebar.actual', overview); tabs.add('node.nodes', nodelist); diff --git a/locale/de.json b/locale/de.json index 9034e425049f82e5671aa6d941b71294c0bc527c..0eadaa610ea123c335c051828c114536d1fbdc86 100644 --- a/locale/de.json +++ b/locale/de.json @@ -39,6 +39,7 @@ "copy":"Kopieren" }, "sidebar":{ + "nodeFilter": "Knotenfilter", "nodes":"%{total} Knoten, davon %{online} Knoten online", "clients":"mit %{smart_count} Nutzer |||| mit %{smart_count} Nutzern", "gateway":"auf %{smart_count} Gateway |||| auf %{smart_count} Gateways", diff --git a/locale/en.json b/locale/en.json index 1b4ec56d3e794924e15e9105fd1e462fbc408e7b..e3ec0ac3466d721bfb2c48ca0b86dfb53f6388bf 100644 --- a/locale/en.json +++ b/locale/en.json @@ -39,6 +39,7 @@ "copy": "Copy" }, "sidebar": { + "nodeFilter": "Node filter", "nodes": "%{total} nodes, including %{online} nodes online", "clients": "with %{smart_count} client |||| with %{smart_count} clients", "gateway": "on %{smart_count} gateway |||| on %{smart_count} gateways", diff --git a/scss/modules/_filter.scss b/scss/modules/_filter.scss index 4e690dc330ed77d891bafb944f3788a917bf521b..8e209b05e391ad98c5fa9eae40ac6a5464d62e66 100644 --- a/scss/modules/_filter.scss +++ b/scss/modules/_filter.scss @@ -37,4 +37,30 @@ } } } + + .filter-node { + border: 0; + padding: 0 5px; + width: 100%; + + &::before { + font-size: 1.8em; + } + + input { + background: transparent; + border: 0; + border-bottom: 1px solid $color-primary; + font-family: $font-family; + font-size: $font-size; + margin: 0 15px 0 3px; + outline: none; + padding: 0 2px; + width: 100%; + } + + button { + display: none; + } + } } diff --git a/scss/night.scss b/scss/night.scss index ddaa1ce2ee4cd6cd29036cfcac6988c5e9a65eb7..a7c8bf399c0c22562d1aadf940ffd77eb7e4b76a 100644 --- a/scss/night.scss +++ b/scss/night.scss @@ -35,6 +35,13 @@ html { } } + //@import 'modules/filter'; + .filter-node { + input { + color: $color-black; + } + } + //@import 'modules/sidebar'; .sidebar { .infobox, .container {