Hi all,
first, thank you for all the input and support on this!
In summary, I think we can conclude the topic like this: We can use JS und jQuery to modernize the GUI and new functions may require JS. But our main focus remains on the CGIs. So, for example, most of the HTML generation and final input validation always happens on the server side (which I think is good practice anyway).
I'll get to work :)
Best regards Leo
Am 16.03.2021 um 16:34 schrieb Michael Tremer:
Hallo,
On 15 Mar 2021, at 21:47, Leo Hofmann hofmann@leo-andres.de wrote:
Hi,
Am 14.03.2021 um 12:44 schrieb Jonatan Schlag:
Hi,
Am 12.03.2021 um 14:41 schrieb Leo Hofmann hofmann@leo-andres.de:
Hi,
Am 10.03.2021 um 14:49 schrieb Michael Tremer: Hello,
> On 10 Mar 2021, at 12:29, Jonatan Schlag jonatan.schlag@ipfire.org wrote: Hi,
> Am 08.03.2021 um 20:21 schrieb Leo-Andres Hofmann hofmann@leo-andres.de: > > The RRD graphs are embedded in an iframe tag. Do know why? Just wondering why we put an iFrame tag around the image. Should it no be possible to reload the image without an iFrame?
Very good question. I think this is because we needed a way to change only the image and JS wasn’t an option back then. The <a> tag allowed to specify a target which changed the content of the iframe.
I would absolutely prefer to get rid of it and just use one or multiple img tags. Those would also make styling easier.
I would also prefer the image tag. But as far as I know, there is no way to change the image without javascript.
The only way I came up with is to send the values of all graphs with the request and to change to content of the img tag at the server in the Perl script. But this solution has so many culprits and couple things in a way a would like to avoid.
I could not think of a better solution either. But I think this would be even worse than the existing iframes.
> Therefore it is possible > to refresh them periodically without reloading or changing the pages. > This patch adds a graph reload javascript to the ipfire main theme. > > Signed-off-by: Leo-Andres Hofmann hofmann@leo-andres.de > --- > ⬇️ This part which is not really part of the commit message, can be put before an patch using the —compose option :-).
Yes this is brilliant :)
Thanks! This time I used -annotate to fit everything in one e-mail, I'll try -compose next time.
> Hi, > > This is more of a nice-to-have, an idea I would like to present. > As I was working on the QoS graphs, I noticed that all RRD graphs are embedded in an iframe. > I wrote a little javascript that periodically reloads these graphs. Would it not be sufficient to reload only the hourly graph? So all others have a range where I would not assume somebody to monitor them “live“.
I think the daily graph might be interesting as well. But for the other ranges I agree with you, they can be left out.
> The refresh interval is based on the graph's time range, i.e. hourly graphs are refreshed more often. > Reloading should stop in case of a network error, but I haven't fully tested this yet. > > This patch adds a checkbox to the GUI settings (default: disabled), translations, ... > If you just want to try the javascript, you can simply paste it to the html <head> in > html/themes/ipfire/include/functions.pl. Be sure to escape the '$' then. > > Best regards > Leo > > doc/language_issues.en | 1 + > doc/language_issues.es | 1 + > doc/language_issues.fr | 1 + > doc/language_issues.it | 1 + > doc/language_issues.nl | 1 + > doc/language_issues.pl | 1 + > doc/language_issues.ru | 1 + > doc/language_issues.tr | 1 + > doc/language_missings | 7 ++ > html/cgi-bin/gui.cgi | 16 ++++ > html/html/themes/ipfire/include/functions.pl | 7 ++ > .../themes/ipfire/include/js/reloadGraphs.js | 81 +++++++++++++++++++ > langs/de/cgi-bin/de.pl | 1 + > langs/en/cgi-bin/en.pl | 1 + > 14 files changed, 121 insertions(+) > create mode 100644 html/html/themes/ipfire/include/js/reloadGraphs.js > > diff --git a/doc/language_issues.en b/doc/language_issues.en > index 7819541c2..9edc57d19 100644 > --- a/doc/language_issues.en > +++ b/doc/language_issues.en > @@ -1446,6 +1446,7 @@ WARNING: untranslated string: password not set = Password not set. > WARNING: untranslated string: password too short = Password is too short. > WARNING: untranslated string: passwords do not match = Passwords do not match. > WARNING: untranslated string: percentage = Percentage > +WARNING: untranslated string: periodically reload graphs = Periodically refresh RRD graphs > WARNING: untranslated string: persistent = Persistent > WARNING: untranslated string: pfs yes no = Perfect Forward Secrecy (PFS) > WARNING: untranslated string: pkcs12 file password = PKCS12 File Password > diff --git a/doc/language_issues.es b/doc/language_issues.es > index 952321fbe..3d623302c 100644 > --- a/doc/language_issues.es > +++ b/doc/language_issues.es > @@ -1318,6 +1318,7 @@ WARNING: untranslated string: pakfire tree = Repository > WARNING: untranslated string: pakfire tree stable = Stable > WARNING: untranslated string: pakfire tree testing = Testing > WARNING: untranslated string: pakfire tree unstable = Unstable > +WARNING: untranslated string: periodically reload graphs = Periodically refresh RRD graphs > WARNING: untranslated string: please reboot to apply your changes = Please reboot to apply your changes > WARNING: untranslated string: pptp netconfig = My Net Config > WARNING: untranslated string: pptp peer = Peer > diff --git a/doc/language_issues.fr b/doc/language_issues.fr > index 9fe5ca21c..e3a38df4e 100644 > --- a/doc/language_issues.fr > +++ b/doc/language_issues.fr > @@ -914,6 +914,7 @@ WARNING: untranslated string: guardian logtarget_syslog = unknown string > WARNING: untranslated string: guardian no entries = unknown string > WARNING: untranslated string: guardian service = unknown string > WARNING: untranslated string: pakfire ago = ago. > +WARNING: untranslated string: periodically reload graphs = Periodically refresh RRD graphs > WARNING: untranslated string: route config changed = unknown string > WARNING: untranslated string: routing config added = unknown string > WARNING: untranslated string: routing config changed = unknown string > diff --git a/doc/language_issues.it b/doc/language_issues.it > index 29c9c7d58..a66c693b0 100644 > --- a/doc/language_issues.it > +++ b/doc/language_issues.it > @@ -1108,6 +1108,7 @@ WARNING: untranslated string: pakfire tree = Repository > WARNING: untranslated string: pakfire tree stable = Stable > WARNING: untranslated string: pakfire tree testing = Testing > WARNING: untranslated string: pakfire tree unstable = Unstable > +WARNING: untranslated string: periodically reload graphs = Periodically refresh RRD graphs > WARNING: untranslated string: please reboot to apply your changes = Please reboot to apply your changes > WARNING: untranslated string: pptp netconfig = My Net Config > WARNING: untranslated string: pptp peer = Peer > diff --git a/doc/language_issues.nl b/doc/language_issues.nl > index d6cad0dee..a2b978ccc 100644 > --- a/doc/language_issues.nl > +++ b/doc/language_issues.nl > @@ -1140,6 +1140,7 @@ WARNING: untranslated string: pakfire tree = Repository > WARNING: untranslated string: pakfire tree stable = Stable > WARNING: untranslated string: pakfire tree testing = Testing > WARNING: untranslated string: pakfire tree unstable = Unstable > +WARNING: untranslated string: periodically reload graphs = Periodically refresh RRD graphs > WARNING: untranslated string: please reboot to apply your changes = Please reboot to apply your changes > WARNING: untranslated string: pptp netconfig = My Net Config > WARNING: untranslated string: pptp peer = Peer > diff --git a/doc/language_issues.pl b/doc/language_issues.pl > index b8fba938f..7f2b72cc0 100644 > --- a/doc/language_issues.pl > +++ b/doc/language_issues.pl > @@ -1327,6 +1327,7 @@ WARNING: untranslated string: pakfire tree = Repository > WARNING: untranslated string: pakfire tree stable = Stable > WARNING: untranslated string: pakfire tree testing = Testing > WARNING: untranslated string: pakfire tree unstable = Unstable > +WARNING: untranslated string: periodically reload graphs = Periodically refresh RRD graphs > WARNING: untranslated string: please reboot to apply your changes = Please reboot to apply your changes > WARNING: untranslated string: pptp netconfig = My Net Config > WARNING: untranslated string: pptp peer = Peer > diff --git a/doc/language_issues.ru b/doc/language_issues.ru > index d507911f1..f988580cf 100644 > --- a/doc/language_issues.ru > +++ b/doc/language_issues.ru > @@ -1322,6 +1322,7 @@ WARNING: untranslated string: pakfire tree = Repository > WARNING: untranslated string: pakfire tree stable = Stable > WARNING: untranslated string: pakfire tree testing = Testing > WARNING: untranslated string: pakfire tree unstable = Unstable > +WARNING: untranslated string: periodically reload graphs = Periodically refresh RRD graphs > WARNING: untranslated string: please reboot to apply your changes = Please reboot to apply your changes > WARNING: untranslated string: pptp netconfig = My Net Config > WARNING: untranslated string: pptp peer = Peer > diff --git a/doc/language_issues.tr b/doc/language_issues.tr > index 04343d527..dc0fd98f0 100644 > --- a/doc/language_issues.tr > +++ b/doc/language_issues.tr > @@ -1021,6 +1021,7 @@ WARNING: untranslated string: pakfire tree = Repository > WARNING: untranslated string: pakfire tree stable = Stable > WARNING: untranslated string: pakfire tree testing = Testing > WARNING: untranslated string: pakfire tree unstable = Unstable > +WARNING: untranslated string: periodically reload graphs = Periodically refresh RRD graphs > WARNING: untranslated string: please reboot to apply your changes = Please reboot to apply your changes > WARNING: untranslated string: processor vulnerability mitigations = Processor Vulnerability Mitigations > WARNING: untranslated string: ptr = PTR > diff --git a/doc/language_missings b/doc/language_missings > index f10c4f242..89808f3b5 100644 > --- a/doc/language_missings > +++ b/doc/language_missings > @@ -669,6 +669,7 @@ > < pakfire tree stable > < pakfire tree testing > < pakfire tree unstable > +< periodically reload graphs > < please reboot to apply your changes > < pptp netconfig > < pptp peer > @@ -922,6 +923,7 @@ > < dhcp valid range required when deny known clients checked > < g.dtm > < g.lite > +< periodically reload graphs > < token > < token not set > < upload fcdsl.o > @@ -1198,6 +1200,7 @@ > < pakfire tree stable > < pakfire tree testing > < pakfire tree unstable > +< periodically reload graphs > < please reboot to apply your changes > < pptp netconfig > < pptp peer > @@ -1632,6 +1635,7 @@ > < pakfire tree stable > < pakfire tree testing > < pakfire tree unstable > +< periodically reload graphs > < please reboot to apply your changes > < pptp netconfig > < pptp peer > @@ -2407,6 +2411,7 @@ > < pakfire tree stable > < pakfire tree testing > < pakfire tree unstable > +< periodically reload graphs > < please reboot to apply your changes > < pptp netconfig > < pptp peer > @@ -3297,6 +3302,7 @@ > < pakfire tree stable > < pakfire tree testing > < pakfire tree unstable > +< periodically reload graphs > < please reboot to apply your changes > < pptp netconfig > < pptp peer > @@ -3660,6 +3666,7 @@ > < pakfire tree stable > < pakfire tree testing > < pakfire tree unstable > +< periodically reload graphs > < please reboot to apply your changes > < processor vulnerability mitigations > < ptr > diff --git a/html/cgi-bin/gui.cgi b/html/cgi-bin/gui.cgi > index f06b0f923..a5255dbce 100644 > --- a/html/cgi-bin/gui.cgi > +++ b/html/cgi-bin/gui.cgi > @@ -37,6 +37,7 @@ my $errormessage=''; > > > $cgiparams{'SPEED'} = 'off'; > +$cgiparams{'RELOADGRAPHS'} = 'off'; > $cgiparams{'WINDOWWITHHOSTNAME'} = 'off'; > $cgiparams{'REFRESHINDEX'} = 'off'; > $cgiparams{'ACTION'} = ''; > @@ -88,6 +89,7 @@ if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}") > $mainsettings{'WINDOWWITHHOSTNAME'} = $cgiparams{'WINDOWWITHHOSTNAME'}; > $mainsettings{'PPPUPDOWNBEEP'} = $cgiparams{'PPPUPDOWNBEEP'}; > $mainsettings{'SPEED'} = $cgiparams{'SPEED'}; > + $mainsettings{'RELOADGRAPHS'} = $cgiparams{'RELOADGRAPHS'}; > $mainsettings{'THEME'} = $cgiparams{'theme'}; > $mainsettings{'REFRESHINDEX'} = $cgiparams{'REFRESHINDEX'}; > &General::writehash("${General::swroot}/main/settings", %mainsettings); > @@ -125,6 +127,11 @@ if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}") > # by manually setting the var to off > $cgiparams{'SPEED'} = 'on'; > } > + if($mainsettings{'RELOADGRAPHS'}) { > + $cgiparams{'RELOADGRAPHS'} = $mainsettings{'RELOADGRAPHS'}; > + } else { > + $cgiparams{'RELOADGRAPHS'} = 'off'; > + } > } > > # Default settings > @@ -134,6 +141,7 @@ if ($cgiparams{'ACTION'} eq "$Lang::tr{'restore defaults'}") > $cgiparams{'PPPUPDOWNBEEP'} = 'on'; > $cgiparams{'REFRESHINDEX'} = 'off'; > $cgiparams{'SPEED'} = 'on'; > + $cgiparams{'RELOADGRAPHS'} = 'off'; > $cgiparams{'THEME'} = 'ipfire'; > } > > @@ -153,6 +161,10 @@ $checked{'SPEED'}{'off'} = ''; > $checked{'SPEED'}{'on'} = ''; > $checked{'SPEED'}{$cgiparams{'SPEED'}} = "checked='checked'"; > > +$checked{'RELOADGRAPHS'}{'off'} = ''; > +$checked{'RELOADGRAPHS'}{'on'} = ''; > +$checked{'RELOADGRAPHS'}{$cgiparams{'RELOADGRAPHS'}} = "checked='checked'"; > + > &Header::openpage($Lang::tr{'gui settings'}, 1, ''); > &Header::openbigbox('100%', 'left', '', $errormessage); > > @@ -179,6 +191,10 @@ print <<END > <td><input type='checkbox' name='SPEED' $checked{'SPEED'}{'on'} /></td> > <td>$Lang::tr{'show ajax speedmeter in footer'}</td> > </tr> > +<tr> > + <td><input type='checkbox' name='RELOADGRAPHS' $checked{'RELOADGRAPHS'}{'on'} /></td> > + <td>$Lang::tr{'periodically reload graphs'}</td> > +</tr> > <tr> > <td> </td> > <td>$Lang::tr{'languagepurpose'}</td>
Does this actually need configuration or can we not simply enable this for everyone?
What is the downside? If the browser has JS disabled, simply nothing would happen.
I don't see any disadvantages, I just thought that some users might not like it.
Would a solution be to add a button to toogle instead? So a button next to each graph to enable something like a live mode? This would not change any existing behaviour.
I added a button to the top row. I think that looks good :)
> diff --git a/html/html/themes/ipfire/include/functions.pl b/html/html/themes/ipfire/include/functions.pl > index 9aec77497..7f3401119 100644 > --- a/html/html/themes/ipfire/include/functions.pl > +++ b/html/html/themes/ipfire/include/functions.pl > @@ -147,6 +147,13 @@ END > ; > } > > +if ($settings{'RELOADGRAPHS'} eq 'on') { > +print <<END > + <script src="/themes/ipfire/include/js/reloadGraphs.js"></script> > +END > +; > +} > + > print <<END > </head> > <body> > diff --git a/html/html/themes/ipfire/include/js/reloadGraphs.js b/html/html/themes/ipfire/include/js/reloadGraphs.js > new file mode 100644 > index 000000000..c0c8bec9e > --- /dev/null > +++ b/html/html/themes/ipfire/include/js/reloadGraphs.js > @@ -0,0 +1,81 @@ > +/*############################################################################# > +# # > +# IPFire.org - A linux based firewall # > +# Copyright (C) 2007-2021 IPFire Team info@ipfire.org # > +# # > +# This program is free software: you can redistribute it and/or modify # > +# it under the terms of the GNU General Public License as published by # > +# the Free Software Foundation, either version 3 of the License, or # > +# (at your option) any later version. # > +# # > +# This program is distributed in the hope that it will be useful, # > +# but WITHOUT ANY WARRANTY; without even the implied warranty of # > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # > +# GNU General Public License for more details. # > +# # > +# You should have received a copy of the GNU General Public License # > +# along with this program. If not, see http://www.gnu.org/licenses/. # > +# # > +#############################################################################*/ > + > +var graphs_reloadTimers = new Map(); > + > +//graph onload event: graph is now loaded, start reload timer > +function graphs_onloadEvent(graphObj, startTimer = true) { > + if(! graphObj) { > + return; //graph iframe object is missing > + } > + > + //get graph parameters from iframe url: [url]?[graph name]?[time range] > + let url = graphObj.contentWindow.location.href; > + if((! url) || (url === 'about:blank')) { > + url = graphObj.src; > + } > + url = url.split('?', 3); > + let graphRange = url.pop(); > + let graphName = url.pop(); > + > + if((! graphName) || (! graphRange)) { > + return; //url parameters are missing > + } > + > + //clear pending reload timeout to prevent multiple timer starts > + if(graphs_reloadTimers.has(graphName)) { > + clearTimeout(graphs_reloadTimers.get(graphName)); > + graphs_reloadTimers.delete(graphName); > + } > + > + if(startTimer) { > + //determine reload interval > + let interval = 60; //default: 60s > + if(graphRange === 'hour') { > + interval = 10; > + } else if(graphRange === 'month' || graphRange === 'year') { Do not think that’s this makes any sense here. Should not change a pixel in this graphs :-). Why is day not listed here ?
Daily graphs would use the default (60s). I made that up on a sunday evening, there is certainly room for improvement here :)
No need to apologise here :-). Thanks for clarification.
> + interval = 180; > + } > + > + //start timeout and store timer id > + let timer = setTimeout(function(graphFrame, timerRef) { > + graphs_reloadTimers.delete(timerRef); //clear expired timer > + > + //reload graph iframe, ignore cache > + graphFrame.contentWindow.location.reload(true); > + }, interval * 1000, graphObj, graphName); > + graphs_reloadTimers.set(graphName, timer); > + } > +} > + Would it no be easier to attach this directly to a graph so inside the function which creates the graph, should be makegraphs() or something like that?
Yes, but I think this was the easiest way to do it without changing the existing iframe. If we remove the iframe, I would do it as you suggested.
> +//document.ready, must fire before iframes load > +$(function() { > + //attach onload event to graphs > + $('iframe.graph').each(function() { > + $(this).on({ > + load: function() { > + graphs_onloadEvent(this); > + }, > + error: function() { //stop reload on error > + graphs_onloadEvent(this, false); > + } > + }); > + }); > +}); > diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl > index b3c2a69da..00e6b9853 100644 > --- a/langs/de/cgi-bin/de.pl > +++ b/langs/de/cgi-bin/de.pl > @@ -2007,6 +2007,7 @@ > 'pc add' => 'PC hinzufügen', > 'pdc options' => 'PDC Optionen', > 'percentage' => 'Prozent', > +'periodically reload graphs' => 'RRD Graphen periodisch neu laden', > 'persistent' => 'Dauerhaft', > 'pfs yes no' => 'Perfect Forward Secrecy (PFS)', > 'phase1 group' => 'Phase1 Gruppe', > diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl > index 9767be178..ed9e4996a 100644 > --- a/langs/en/cgi-bin/en.pl > +++ b/langs/en/cgi-bin/en.pl > @@ -2037,6 +2037,7 @@ > 'pc add' => 'Add workstation', > 'pdc options' => 'PDC options', > 'percentage' => 'Percentage', > +'periodically reload graphs' => 'Periodically refresh RRD graphs', > 'persistent' => 'Persistent', > 'pfs yes no' => 'Perfect Forward Secrecy (PFS)', > 'phase1 group' => 'Phase1 Group', > -- > 2.27.0.windows.1 > Some generic thoughts. Would it not be better to remove the iFrame and make the links for hour/day/month/year firing some JavaScripts which reloads/changes the graphs? And then when we click hour start this script to reload the graphs periodically?
Agreed.
I very much like the idea and I think this is an opportunity to clean up a little bit more. I will let you two sort out the technical things and how often is best to reload :)
As I mentioned above, I would also prefer to revise that. But I think users withouth JS enabled will then no longer be able to change the graph range.
What is you attitude towards JS in general? I think for such "bonus" features like interactive graphs we can require JS and break compatibility, would you agree?
So the actual content of this mail in one big block:
First thanks for all input, things seem to be a little bit more complicated right now, but at least we can create a stable solution when we find a lot of problems before 🙂.
Regarding JavaScript in general, I first thought that this is a good question which needs an answer but after some thinking I came up with the fact that the web interface is already not working without JavaScript enabled. The zone configuration page needs JavaScript enabled, otherwise the change to VLAN does not work, as we cannot enable the field without JavaScript (tested today )
As far as I know, however, this is the only page which requires javascript. So if we should vote against JS, not much work has been done yet.
No, technically every page uses JS because we have the speedometer at the top.
Besides that, we have the zone configuration, firewall and probably some other smaller places with some embedded JS.
So I do not really have a problem here when we add JavaScript for Features, as this is somehow the only way to change the DOM. I do not know If it is a good idea to use JavaScript only for “bonus” features, because also validation of input fields is when it comes to more complex values, only possible with JavaScript. I would not call this a “bonus” feature. In the end we will maybe end up with two web interface which increases maintain work.
But I would like to have a general decision here to avoid talking about this over and over again. @all maybe something for the next telephone conference? Or should we made a decision right here?
I agree!
Another fact which came to my mind is that our jquery version is heavily outdated and I think it makes sense to update this lib before we add further JavaScript. Otherwise an update might break scripts and causes more trouble as when we develop the scripts with a current version.
Would you be willing to do the update? I don't know how to do that, but of course would like to use the new features.
So I suggest the following plan:
- Decision making concerning JavaScript (next steps only with positive decision)
- Updating jquery
- Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
- Adding a button for live mode
I'm not sure if I should ask, but I feel like I've already opened Pandora's (graph) box here. Is there a reason why every CGI also creates it's own graphs and has additional parameter handling for that?
No, I would like to have one CGI script that has a parameter which graph we want and what interval and that is it.
The graph stuff was quite different and we changed a lot of it when we introduced collectd.
Wouldn't it make more sense if the graphs were generated by an independent script? For instance: "getrrdimg.pl?category=qos&graph=red0&range=hour"
Yes! Absolutely. Do we want to do this after we have done the UI makeover?
I suggest an Update every 15 sec for “hour” graphs and every 360 sec for daily. Could we add this as constants to make a change easy? And another idea: would it not be useful to have a basic value so 15 sec update interval for one hour and then just multiple this value when it comes to day, month etc? Would make introducing other time frames easier.
Thanks for your thoughts and for your time (especially Leo)
Greetings Jonatan
Thanks for the nice patch. It is easy to review :-)
Greetings Jonatan
-Michael
Greetings, Leo
<rrd-live-update.png>