From 9628409409366637ba5de3d20f8358f492a2cce8 Mon Sep 17 00:00:00 2001 From: Xaver Maierhofer 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 zcmah{T}TvB7(I7pcgkINrBJgHoJGxkSexDaDai`T4WuZ{B0>OtK5-O~a5b{BSq6Z&@9`mJF?aVkJfzZHr?>XoDx!=9>E$n->zX$;! zgxipDIg#kSSa^Nt8-+=#wdc=uC2$rBxkavCx^gsrW+M3v5ZB22`ZKyUv3qKXe3kYk zrRS}U4OT+Pq!lY3KuihYR%MC#}sijiN69mi$bvq|jhyM#jr- z$`{CI$Xn96etnlzahwGl-kj0LEnG(@{nVgl^^EbZ>ki`s_oz)-x%|kdy`R}oxkldR zUe3ATue#EWij#j3lt_T(H}j>o2IacfD0w2ko3bpWIn)?B$ zM2a1j_J{{|gVe;eTWS>d?X1)?`$TFHKDif|U6u<UNW>_8A`Kh|2`R26CU zM_MCG$>fZ9zdk9{^%YB7)3g_H*5_A_$KK%r0aSZfVuhH8Wi;ZhhkcCs;9)<{SoN@i zKv5`8_r5Yp&iig+31LJ$ETbDIJnUo4OAq^b?4pMi>TAfrKprMWF+?;*8wN5)-W(k= z#th;fN+}eOhVHm}j8wr61sjXoC93G)%ft{x+%=839Z2M|BZ=H_%24CYn%bdml_!Zs z=wKn6 pHPY^H5gcvFecUj4jjK6aMio~d`Q~sr(}Km$r(d0YYtrURe*wj*tA79h delta 741 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 delta 1751 zcmV;|1}OQ24&V(KcTYw#00961000Ky01W^D000e8000Jwkr*F;9tL0lgF+Dq3XF7# zPysdqBm*)FEC2)`1%na?f+ZW43Q?3VQj+XTj9m{BX=pOt>mnmXoEz@`CmS309rXCI zdjy~epaB2?008~}dG`0EsiThg2K+xADg(M4Bt5A;~fb{e5%p7Z*a> z(2TZ?s2~z6+xCrrj*4#EKI8jw?e(Q~NzVn!npyaE3k*r4U1DEser})$B%&fX5OQF7 z`~S^me|$+4r3!^mr63E5sa*>!Z>5_Wh^S4dHlqY3q7rS&-ybyN>byWOlL5l;8xb?J z)&GCL(upXLO0ZJ-_f14^RnZDA=JAN;ZSfIVu@&E=c17)fI%C4K!?OSY0l-tqd6Aogw~=K#clAp=anJG{(I0%NaNB( z|HG33hy+l8AbOSM{-?Vs)v* z_X^XA%BhkB+JoSaN}DNi%@cT5L=v1Uo`rovz0cl_yXP!#X@yYW6DiQ>JzyZFk*!N{k>w-y|WvXPlDB+3heP-l_|vpUPR~s=)@C!3Z5|ohv=be$BOvGAe%F< zIKLb+hab(#^R!y|X8zhwf>J zCEbPy14nZFw4SAPYgoxATIrwgrqwOB57wn8uc_8lz3ae#}rO2$eLO)j%@G<{{NYjy;0jgS#wY2%QX*K@?&CB7f ze`nKIXW@cEeP>s0+ju+s_cvD_P_E_wx?(G_pnvOFD~wsjCSd6aFn;zwG;iNF6O|=5 z@TacXK4UfYhugIEgnWEEyN+yHwt5YJd(Y-=72A*BNlEzitXII^|Ld2mG{eF951wQ? zZ3SFk_7&|kq*s*<50|N;lA}~iVg*oVuC?z!zM!iM-x7wyg=7J|rGAM?C)!RVCHiq* z?jZ?&7q#BY*o(f$fA@mKkc`ZX5U7tMLJrS1xRtsMELYS#x&fVs(OnVV zk$xPi3D=EO&C%5gTGUHs5$>FSgr$BlRbR00bTJn2yL}FV1ziVnhS|bDU{gxtvw>iy zI1m#iU;Yz-hOY4l(3b#=#g)I_e>SOH9}C|I>b?Xfz~qp^2$M`W!aBZ#wUZHmKlvyo z1yDULkfbTTSnUWip}CyEM4nthIt%3_W^Uz5Y`mSP!i*OkqSu1po`F<CZ612}wFtBeynm;xq$4M5pLSEuZ>OCnA)rcRyVFJKlc;NKEeg7#M+5-E`isgVY0 zU;mp@h(-)z5r;xhC<>!mWm)p_CQ>KzW4eN=+rf`f<2JL$P~@k~78m__vfXNPDa>=t zv{M?lk52JpZi~e%lU}>Ut{)XmvSc^$qb3t=3>cr1oMy&eGbN2SkGjnDW%IP;F;hJU tOe!39(bq0Hc@RaH&A$6ees#wo{2IS?Tyo6SEDDe2*VTNE2aHQ1005EsM^69% 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 {