GUI: Periodically reload RRD graphs

Message ID 20210308192125.1114-1-hofmann@leo-andres.de
State Superseded
Headers
Series GUI: Periodically reload RRD graphs |

Commit Message

Leo-Andres Hofmann March 8, 2021, 7:21 p.m. UTC
  The RRD graphs are embedded in an iframe tag. 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>
---

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.
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
  

Comments

Jonatan Schlag March 10, 2021, 12:29 p.m. UTC | #1
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?

> 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 :-).
> 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“.
> 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>&nbsp;</td>
>     <td>$Lang::tr{'languagepurpose'}</td>
> 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 ? 
> +            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?
> +//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?


Thanks for the nice patch. It is easy to review :-)

Greetings Jonatan
  
Michael Tremer March 10, 2021, 1:49 p.m. UTC | #2
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.

>> 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 :)

>> 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“.
>> 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>&nbsp;</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.

>> 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 ? 
>> +            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?
>> +//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 :)

> Thanks for the nice patch. It is easy to review :-)
> 
> Greetings Jonatan


-Michael
  
Leo-Andres Hofmann March 12, 2021, 1:41 p.m. UTC | #3
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.

>
>>> 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>&nbsp;</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.

>
>>> 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 :)
>>> +            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?

>
>> Thanks for the nice patch. It is easy to review :-)
>>
>> Greetings Jonatan
>
> -Michael
Greetings,
Leo
  
Jonatan Schlag March 14, 2021, 11:44 a.m. UTC | #4
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. 
> 
>> 
>>>> 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>&nbsp;</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.
> 
>> 
>>>> 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 )

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?

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.  


So I suggest the following plan:

1. Decision making concerning JavaScript (next steps only with positive decision)
2. Updating jquery
3. Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
4. Adding a button for live mode

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
  
Bernhard Bitsch March 15, 2021, 4:13 p.m. UTC | #5
Hi,

another thing that could be changed with the display of the RRD graphs.
At the moment the output of rrd_graph is embedded directly into the web page. In case of an error this output is empty.
The RRDtol function delivers an error, which could be put into an alternative image.
I've tried this some times ago and could post this solution as part of a revised patch.

best,
Bernhard

> Gesendet: Sonntag, 14. März 2021 um 12:44 Uhr
> Von: "Jonatan Schlag" <jonatan.schlag@ipfire.org>
> An: "Leo Hofmann" <hofmann@leo-andres.de>
> Cc: "development" <development@lists.ipfire.org>
> Betreff: Re: [PATCH] GUI: Periodically reload RRD graphs
>
> 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. 
> > 
> >> 
> >>>> 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.
> > 
> >> 
> >>>> 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 )
> 
> 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?
> 
> 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.  
> 
> 
> So I suggest the following plan:
> 
> 1. Decision making concerning JavaScript (next steps only with positive decision)
> 2. Updating jquery
> 3. Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
> 4. Adding a button for live mode
> 
> 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
>
  
Leo-Andres Hofmann March 15, 2021, 9:47 p.m. UTC | #6
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>&nbsp;</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.
>
> 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:
>
> 1. Decision making concerning JavaScript (next steps only with positive decision)
> 2. Updating jquery
> 3. Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
> 4. 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?
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"

>
> 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
  
Adolf Belka March 16, 2021, 8:37 a.m. UTC | #7
Hi all,

On 15/03/2021 22:47, Leo Hofmann 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>&nbsp;</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.
>>
>> 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.

I am willing to pick up the update of jquery.

That is the sort of thing that I can support well on and let you guys 
get on with the stuff that I can't easily do.

Regards,

Adolf

>>
>>
>> So I suggest the following plan:
>>
>> 1. Decision making concerning JavaScript (next steps only with 
>> positive decision)
>> 2. Updating jquery
>> 3. Removing the iFrame and using JS to change the images when 
>> somebody clicks on hour, day, etc
>> 4. 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?
> 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"
>
>>
>> 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
  
Michael Tremer March 16, 2021, 12:29 p.m. UTC | #8
Hello,

> On 12 Mar 2021, at 13:41, Leo Hofmann <hofmann@leo-andres.de> wrote:
> 
> 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.

We could simply hide those that we do not want to show.

However, I do not know if it would be possible to reload them then.

> 
>> 
>>>> 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.

No, this was absolutely fine. There might be a reason to have some text in that email that should not be part of the comment message (what has changed compared to an earlier version of a patch for example). I thought this was fitting.

>> 
>>>> 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>&nbsp;</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.
> 
>> 
>>>> 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 :)
>>>> +            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?

Hmm, this is a very good question. I do not have any problem to make JS mandatory. Anything else is putting your head into the sand. Browsers have removed options to disable it years ago.

-Michael

>> 
>>> Thanks for the nice patch. It is easy to review :-)
>>> 
>>> Greetings Jonatan
>> 
>> -Michael
> Greetings,
> Leo
  
Michael Tremer March 16, 2021, 3:30 p.m. UTC | #9
Hi,

> On 14 Mar 2021, at 11:44, Jonatan Schlag <jonatan.schlag@ipfire.org> wrote:
> 
> 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. 
>> 
>>> 
>>>>> 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>&nbsp;</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.

What is wrong with changing existing behaviour?

I think adding more UI elements that users will unlikely click is wasting space.

What harm does it do if this is always on?

>> 
>>> 
>>>>> 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 )

Yes, there is no al

Although IPFire is quite modern under the hood, the UI looks very dated and we should not contribute more to that.

> 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. 

We considered JS a bonus before, but changing the zone configuration is not a “bonus” or even “niche” feature.

> 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 do not think that we have heard any arguments against. I do not see why we should drag this out for longer than needed.

If there is more to discuss which would make the conversation difficult on the list I am happy to put it on the agenda, but I do not see that and would therefore prefer to have everything discussed on the list.

> 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.  
> 
> 
> So I suggest the following plan:
> 
> 1. Decision making concerning JavaScript (next steps only with positive decision)
> 2. Updating jquery
> 3. Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
> 4. Adding a button for live mode
> 
> I suggest an Update every 15 sec for “hour” graphs and every 360 sec for daily. 

15 seconds is insane. Some devices need about a second to generate the graph. With multiple graphs on the page this would create a lot of load.

The RRD databases have a “step” of 30 seconds. So updating more often than that would show you the same graph.

What is the rationale for such frequent updates? There won’t be a lot of change to see?!

> 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
  
Michael Tremer March 16, 2021, 3:30 p.m. UTC | #10
Hello,

> On 15 Mar 2021, at 16:13, Bernhard Bitsch <Bernhard.Bitsch@gmx.de> wrote:
> 
> Hi,
> 
> another thing that could be changed with the display of the RRD graphs.
> At the moment the output of rrd_graph is embedded directly into the web page. In case of an error this output is empty.
> The RRDtol function delivers an error, which could be put into an alternative image.
> I've tried this some times ago and could post this solution as part of a revised patch.

Yes, please post the patch.

-Michael

> 
> best,
> Bernhard
> 
>> Gesendet: Sonntag, 14. März 2021 um 12:44 Uhr
>> Von: "Jonatan Schlag" <jonatan.schlag@ipfire.org>
>> An: "Leo Hofmann" <hofmann@leo-andres.de>
>> Cc: "development" <development@lists.ipfire.org>
>> Betreff: Re: [PATCH] GUI: Periodically reload RRD graphs
>> 
>> 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. 
>>> 
>>>> 
>>>>>> 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.
>>> 
>>>> 
>>>>>> 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 )
>> 
>> 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?
>> 
>> 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.  
>> 
>> 
>> So I suggest the following plan:
>> 
>> 1. Decision making concerning JavaScript (next steps only with positive decision)
>> 2. Updating jquery
>> 3. Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
>> 4. Adding a button for live mode
>> 
>> 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
>>
  
Michael Tremer March 16, 2021, 3:34 p.m. UTC | #11
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>&nbsp;</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:
>> 
>> 1. Decision making concerning JavaScript (next steps only with positive decision)
>> 2. Updating jquery
>> 3. Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
>> 4. 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>
  
Michael Tremer March 16, 2021, 3:35 p.m. UTC | #12
So happy to see the teamwork here :)

> On 16 Mar 2021, at 08:37, Adolf Belka <adolf.belka@ipfire.org> wrote:
> 
> Hi all,
> 
> On 15/03/2021 22:47, Leo Hofmann 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>&nbsp;</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.
>>> 
>>> 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.
> 
> I am willing to pick up the update of jquery.
> 
> That is the sort of thing that I can support well on and let you guys get on with the stuff that I can't easily do.
> 
> Regards,
> 
> Adolf
> 
>>> 
>>> 
>>> So I suggest the following plan:
>>> 
>>> 1. Decision making concerning JavaScript (next steps only with positive decision)
>>> 2. Updating jquery
>>> 3. Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
>>> 4. 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?
>> 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"
>> 
>>> 
>>> 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
> 
> -- 
> Sent from my laptop
  
Leo-Andres Hofmann March 18, 2021, 8:20 p.m. UTC | #13
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>&nbsp;</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:
>>>
>>> 1. Decision making concerning JavaScript (next steps only with positive decision)
>>> 2. Updating jquery
>>> 3. Removing the iFrame and using JS to change the images when somebody clicks on hour, day, etc
>>> 4. 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>
  

Patch

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>&nbsp;</td>
     <td>$Lang::tr{'languagepurpose'}</td>
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') {
+			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);
+	}
+}
+
+//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',