From 9628409409366637ba5de3d20f8358f492a2cce8 Mon Sep 17 00:00:00 2001
From: Xaver Maierhofer <xwissen@xwissen.info>
Date: Wed, 1 Feb 2017 22:13:06 +0100
Subject: [PATCH] [TASK] Add node filter

---
 .eslintrc                     |   1 +
 README.md                     |   1 +
 app.js                        |   6 +++++
 assets/icons/fonts/icon.ttf   | Bin 3400 -> 3500 bytes
 assets/icons/fonts/icon.woff  | Bin 2472 -> 2516 bytes
 assets/icons/fonts/icon.woff2 | Bin 1760 -> 1796 bytes
 assets/icons/icon.scss        |   1 +
 lib/filters/hostname.js       |  41 ++++++++++++++++++++++++++++++++++
 lib/gui.js                    |   7 ++++--
 locale/de.json                |   1 +
 locale/en.json                |   1 +
 scss/modules/_filter.scss     |  26 +++++++++++++++++++++
 scss/night.scss               |   7 ++++++
 13 files changed, 90 insertions(+), 2 deletions(-)
 create mode 100644 lib/filters/hostname.js

diff --git a/.eslintrc b/.eslintrc
index 64cc9da..35fcf81 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 0e89f18..83857c3 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 6e8875f..0401293 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
GIT binary patch
delta 880
zcmX>hwMM$0fsuiMftR6yftew|%`L>Ybgkw!1_s^<3=9l1?k=uw49*N}3=F&l3=9kk
z{=xc24s{8O85kHN7#JABl5-Oa>V%eGU|?W;!oa|IDm}5d;QxOHW(Ee{3<d@Uj`W<$
zw9-Ah?HL%DA22Ymt;k4COyTN1!OXzGaEF0`!7L*qwLX#gJrgSf1EUB71A|INZb=1a
zHnR@{1LFn;1_qOy{NzMICVmSB24)anFE_EGfFYW}mVtrM0_32)#N5>Vu8lqn3|t)y
z42;VQ@{3E3N*=qwz`$d`z`$q*_8iEA&*hur`E9;3a5FK0z?JQXn;|sQ;pRz<wv1wv
z?HHG8D=;vC91q4aV7&|sM;MsFEExtCh7}A93~CGt3@i+6llhp$8M`N|FsU<kPxfL`
zW$c=q$7Hg30h0+M3v&nq!{#f@rEK-g3<?Ydj1L$mFfcQ)GjKC7m>ZiatBWd{vMQP?
zUPwsTz<A)_1V)8_4+;!E7#OTH0=bESfrnul*h&TlMg}ehF({jfft|q+%4TLzWoU)6
zSs1t&4no<i4BQM)plmh<u6jl`kn34E85kKr;mgdx$im6M#K6a(2o+~$@M5rpvRN2J
z7*<2stPEldXP|601`&o247m)c48;r?3}p<N45<v|45<u73=Fxc#TjLpspY9f3=BaG
zsSN21r3^U?i6E(<)b!HHyxgkw*fc6ISTQIt7&7QG7=f_?gCT=C1A|+BUWr?NQF^L^
zk)DBql>)+e1uF$ZT_as114DBL!cGYTyRMialOdmB@(OMVd2DV#a{T05+{%n%lmBsR
zF)@lv*5J7r%9ogzQk0*WqMKHlmzSCYju*!N{~4ITfy>9hz#st@1M!&|L>U+vSQr=>
VAc+f<-Wbl<E;<iVfk<hGn*qhCtA79h

delta 741
zcmZ1@eL||9fsuiMftR6yftew|%`L>YSbTyK0|T!P0|SGMyNjzEgA)TA0|PG)0|SGC
zf3UuhLtVmR1_s6m1_p+(<lMx9X>qg9GcYhdVPIf9l%7~z@c%ypGXn!J3j+fKM|w_W
zTKe;c>lqlBuP`vMm1LwQrm+9e^JidSxWmA}V3v`QTA#@Lo{5!#fl-8kfk7oBx1@qI
zn^}i}fpG%^1A|dcesUu3I(`cV2IdtE3=BHCi4_G5Q4F>W42%{a2jwN^rmp$3xPpO!
z%Y%V|aZ*8kaY_F*bzKGq?mG+&jH+PIF)}dpi1^)&=ePOFz|F(}0+(~Xt%T4_-&Rgy
zv}F{XY{$4%8zjWczyR_9gA7<N1H&E$W-v>JfrViK$c+pN3@i*Rllhp$C#y55P4;I}
znOw?bym=Lq5##0u%%yDg3=BLB)4+Nd7#JBi7=)l~CI)r}Z77?WL4~0f%4T8UVAuj>
zvodfqT!pgP7&sU{gKTHvWME_v0K1Ekg_D7afsa8ND$dN{!C(w!voHuSEMj0bU;rs%
zWe{W73zcAF5MX%7kin48P{5GRki(G3P|Q%wz>tw&ke-uRTs+y1+o~R2R)N8aL4m=D
z!Hhwd!IVLl!HB_t!H~g>fx#_5uf#3CC_PodNY6mQN&#kyf|Y`inXaj>k%6HZ18&P0
z7{VA*8HyN+88R928S)qu7z`Qo7z`%y@JpdP0q#JC$$C7>jG~i+c(f+h@!Vu&n4HEd
euP(yC$N)-ZkQfD}Vumxei_U}M5D~rKRssONn2KHi

diff --git a/assets/icons/fonts/icon.woff b/assets/icons/fonts/icon.woff
index 7cc19f45434c92dfaadee96d32043182541c9272..ef0bc9e665b038c8791e022cb2cf25f55ac21e1d 100644
GIT binary patch
delta 2376
zcmZ1>d_`EK+~3X3KP1GTfr0Z112+Q$0|Rf!L=okBF9rtoYhFv=-f(jZ@nv9O4`E<n
zkYZq9kSSfOdClF$)s2CHy?}v%L6(7mL4m=MfyF;q--v;MeF6gmg9ifxLxRJCgd@qh
zi3JP{>^B$~7}^;a7*EwPE!&xqnwY}Cz>&bfz@X2-z+lGJdxAM5BQ=qMfdiyhhJk@W
zh53Cw6LUsxNd*G~#~KC(26YAo1|9ZnX3yNjiUI}(jw=id3~XR562Op`n48MLz;TCx
zf#Deg1LN}ju8lqg`Nbs+44g+87#IY=4rFFvteBHKH9JS<s%XRe8`it0--zTo<q@*A
zEM%pI%OTc9948rXS#8pCzRK>|!O`DRzjbflciC&Z3%6geu%36fa!%!&<YWA2CP~ds
zI^O5g5xcxM*lCG_wn+G<MGMrnwkUarN_YNy(ZBmr$kOt%WUs*I8ENO{94~)2$F_L7
zqa1&d#4=SmDH#hvKHk=#j!Y+>S8Hmwul(jw{Fbr*+9`)@<1JN8w=bCU-}%paV7k}p
z{JQ#m)7CA$X{J`2FYR<cBU$Zzw)2j&+so`9#rSAfG1zv<Iq@%czhGCwv9~Gdg}8^4
zs7dFti<TvVe;MyO%wM>lUAT5-%8vE6H?Ci|7O<M=rFJWM;lD4_=5fhOd&u*vw;lTX
zFu+X2k8c}$@X99v)l~|2I{wUBIqyQnIhp+TnHjYw>ld<IeLt;BwYvG`g=@k2I+hZ@
zy0l+0RZl*?`Rj%Pqm56!TOXYi{wgZNzm#oq=fRYG3yJLaC%=4e4~lmDJJUr;<ad7X
z{!4K!5}gwzTLUE%Ox)6Wj-_<@bZQ!l9!tten<ANfY$oTH!?_8<zr?J%md#|JId$3Z
zSx&zDbAP3OK76*`>vO)%ZQK6pzRI|-e`f!kef|0Rw~B}FY&tA#_u>PeyvmnNJ{9xl
zyL23#s6MB5O(a9$qyn2`UXwUjg{{|5Fj)O!6=R5r^L4{QUDwS#X^iKOZa4b#<olF|
zJ9s*yd^pb^y|Kt;@fo+ab=jqDSsGQ%S~IseF&=*$Em`+Tva;WL?(BLS#^xWUI}K!R
za3A)&&cQQz-QEN9CUs4=@!9`#_4XWDld36alOoqY(7MUyDt2npM01B=$E6#ZIK}K@
zuemYTf9;!gRZ*^`NyTfO@RdDEo(f4CA#-!r*aeB4p0w=MDz*~Vuw4FfZoA(2TE5#m
z=Lqy(>OLwLS@rGh{6qc;^}js$>&05;$j&_<x$SJ+-w&5}MmL<?KG*h6hTimU7gom=
z8`k@|9#<A<d~q^_?YSF^w$c2}?zv@!56kn{zLL<npSt7A=VIm?g~F__FFXzYHsh?{
zt;yeX&K#P3=!xc=M|`qLcSYYmuxo!ED{u4r&*$I!_6wIC`q#hv|Ci^p=da0QD4R6z
zYW>os-qWk5#Z@d^{`|wkrSn4P-Fbb|@6RTw6%HpgW=4Ebz0}<4QdL#<?d{8(4o9O;
zoL1_&P=426?zzZRu7Haoybn&^-oia=(Qf-GarvLl-e$OA;FWNqjb)O~!*_l~d=ZzY
zykdVpr+KU2v|n7Cd}f+!1TQ~(rLk*S@UyeGrBYv&s@1Dzully+^pswk6PtWywzXWh
z(rjDH?0fP_X5%}MCbraTa?1A4N+Ksa9&6Hg#&quYy*Uxve(YvmDZQlE=9E~s>SiWU
zjnipzlg*w7Ui)vk^QdN<_3j&5)88^w-p`)y+Q=R`Ra8>D>v5ZBWuRQ6paAd67FluE
z*?wj_ryfmq@2{6DK7VxT)T2j5=gIt#+%C{lQM`NiuCnI^DmxzB&Mja2+^jIA@?duU
zy7l?DDiSRp-9EFn{O0bB#Rq=MZQr<U+s2D~uU))&_wL1w*Y+O#oxM9tch2QUTLh|(
zJ?^!>`phF%S+}^j*E%!t@7A!Q$+K6b8SnW#Nq_R$G^V~6XH!-O+f>${G!I?t$Lcr#
zd)&@~ho`1;yYsPC)mqO@x43RIb#2<64?d>WNB>W>IXw6KT;F}teCm@ErJkza-+6fA
zz7@)o&Q|JI{!%J`%>KZ~LW$vKis$^t57p|woXqzBap$A;iP+tL?p*Hc*DDfdh`pir
zXm{Dq!`XX2JD;C9bEfg<l`|uBrgqgIOAAV`_%Ca8ob}|_)LFk+D?6n1=hVwCy0P<J
z>(9^mJ>ti^Lvzn)WN*t12)xH!^(1$vQuvZgD^Ug|jpR=|LaylKh`#(GqIQpWMf!cq
z-CV0b_(kwOc6q4c5GcwtOX2C$$)`5FFmmwoR{rE+_xzRDe#hmfrk&D~o4oo}1>^7Q
zC+qDk7ILI^=ehgmZdev~$;-jjR5a^Fg6=M54%Rm|Tc=N*vS${%)-0Fu-P1+SExJ8f
z!L;Vnbh~D$e}~LwFzlDpmvnV*pA<9cr0s7;pQTH#X=kYYebkuq|HKvFU$!&4R?exM
zyYH2s|K4S%-~PBii!XLT!o8<{0qf$PYyF>J{WUwrzW$}M+`C6}#cR*;L_W%5kN<Ps
z@x5-kb$O?b?6P{MYkUv<w&(rkm(rQ4&%jVICpjS@A%&sIcw6_m<`>$x`OOb!Fa!s4
z$U)>%5)vLTCvma~BqSxUI3+5iF@Ba{V3lTYV}Qt~B_+%`aNyK|gD(!xICkK`1HPsE
zjV3p++X-4QJuz(hsl%h)utlnwX~NNClh3nD)W7>@^YZhf^Vj#CsNwt_^!>m635E?;
zqHA8QQ@ZkT^T)prcONgG`CawBSDbcSaGYwK<UGE4S@T@vl;8Q^vEHffeAk&Jfn`@;
z#?iwf3=BuR?KgwnpOTQk@QC+e@QlYlbN3k)7#lVmnEJMT_QNeq%}kG(kFh)Gu`@?V
zF&IQ~G5(&M%wbcX5Wv9Dmc_P{fq@}_fk6c1lh!_Kzrzk9uKmKtI~rC9d|k3&i|J!E
zC2kMLnM$=?6O%PJs#?z%-N0&gQ0v8J9<c*LJCfZNIiB+He}AU-du>DYJx>n(#8bgf
z1kHDxNS;^OJ?GSC$;v~r@e_@gd8(yPy606Xvx}*}B0;S3jCQ^L#NbLhCI2m7g)Ark
zJ1ggZewy&s7i(T5y#M`n<+pVGIL}oUo05gSwBu#Vr4LS;)^>P;wWUqlB&OAS0{)o)
z*#79mQ=Y`5#l2ax4{v&_m4E8ctk$2=>-$fi-m}GT+v?@(*jI*I&Jh!9EsprTZvE|J
gI}XLke`5Yo>%0);(d2|QZU?p=o(u*ChCT*X0L+g=<p2Nx

delta 2324
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
Z`=<Z4GeI6rPDtZ+VC&%lwOjfaSOGnzK&1cx

diff --git a/assets/icons/fonts/icon.woff2 b/assets/icons/fonts/icon.woff2
index 0377338e069c95378c91bcf8ce06f6efe4592d5a..6d92253e7578fafaddf0164cbe174567eb2b03d3 100644
GIT binary patch
literal 1796
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

literal 1760
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
MrjNbHTZw@I0M^Gp>Hq)$

diff --git a/assets/icons/icon.scss b/assets/icons/icon.scss
index d589691..89ca76a 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 0000000..b311c07
--- /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 815a839..b195a75 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 9034e42..0eadaa6 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 1b4ec56..e3ec0ac 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 4e690dc..8e209b0 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 ddaa1ce..a7c8bf3 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 {
-- 
GitLab