From ac8026304f76ef65a29afad3a37c9935949c0955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Wed, 19 Dec 2018 05:54:52 +0100 Subject: [PATCH 01/50] Closes #677 - helper functions for the url parsing and rendering --- module/helper.py | 95 +++++++++++++++++++ module/htdocs/css/shinken-layout.css | 2 +- .../views/_eltdetail_information.tpl | 50 ++++++++-- module/plugins/eltdetail/views/eltdetail.tpl | 2 +- .../problems/views/_problems_eltdetail.tpl | 27 +++++- .../etc/arbiter/objects/hosts/localhost.cfg | 13 ++- .../etc/arbiter/objects/hosts/localhost2.cfg | 28 +++++- .../etc/arbiter/objects/hosts/localhost.cfg | 13 ++- .../etc/arbiter/objects/hosts/localhost2.cfg | 28 +++++- 9 files changed, 230 insertions(+), 28 deletions(-) diff --git a/module/helper.py b/module/helper.py index 7f5b571f..0931a64f 100644 --- a/module/helper.py +++ b/module/helper.py @@ -45,6 +45,7 @@ from shinken.misc.sorter import hst_srv_sort from shinken.misc.perfdata import PerfDatas +from shinken.macroresolver import MacroResolver # pylint: disable=no-self-use @@ -749,5 +750,99 @@ def get_contact_avatar(self, contact, size=24, with_name=True, with_link=True): return s + def render_url(self, obj, items, css=''): + """Returns formatted HTML for an element URL + + """ + result = [] + for (icon, title, url) in items: + if not url: + # Nothing to do here! + continue + + # Replace MACROS in url, title and description + if hasattr(obj, 'get_data_for_checks'): + if url: + url = MacroResolver().resolve_simple_macros_in_string( + url, obj.get_data_for_checks()) + if title: + title = MacroResolver().resolve_simple_macros_in_string( + title, obj.get_data_for_checks()) + + link = 'href="%s" target="_blank" ' % url + if not url: + link = 'href="#" ' + + if icon: + icon = '' % icon + else: + icon = '' + + if not title: + result.append('%s %s' % (link, icon, url)) + else: + result.append('%s %s' % (link, css, icon, title)) + + return result + + def get_element_urls(self, obj, property, title=None, icon=None, css=''): + """"Return list of element notes urls + + The notes_url or actions_url fields are containing a simple url or a string in which + individual url are separated with a | character. + + Each url must contain an URI string and may also contain an icon and a title: + + action_url URL1,ICON1,ALT1|URL2,ICON2,ALT2|URL3,ICON3,ALT3 + + As documented in Shinken: + * URLx are the url you want to use + * ICONx are the images you want to display the link as. It can be either a local + file, relative to the folder webui/plugins/eltdetail/htdocs/ or an url. + * ALTx are the alternative texts you want to display when the ICONx file is missing, + or not set. + + The UI do not use any icon file but the font-awesome icons font. As such, ICONx information + is the name of an icon in the font awesome icons list. + + The ALTx information is the text label used for the hyperlink or button on the page. + + """ + if not obj or not hasattr(obj, property): + return [] + + # We build a list of: title, icon, description, url + notes = [] + + # Several notes are defined in the notes attribute with | character + for item in getattr(obj, property).split('|'): + # An element is: url[,icon][,title] - icon and title are optional + try: + (url, icon, title) = item.split(',') + except ValueError: + try: + (url, icon) = item.split(',') + except ValueError: + url = item + + notes.append((icon, title, url)) + + return self.render_url(obj, notes, css=css) + + def get_element_notes(self, obj, title=None, icon=None, css=''): + """"See the comment of get_element_urls""" + return self.get_element_urls(obj, 'notes', + title=title, icon=icon, css=css) + + def get_element_notes_url(self, obj, title=None, icon=None, css=''): + """"See the comment of get_element_urls""" + return self.get_element_urls(obj, 'notes_url', + title=title, icon=icon, css=css) + + def get_element_actions_url(self, obj, title=None, icon=None, css=''): + """"See the comment of get_element_urls""" + return self.get_element_urls(obj, 'action_url', + title=title, icon=icon, css=css) + helper = Helper() diff --git a/module/htdocs/css/shinken-layout.css b/module/htdocs/css/shinken-layout.css index 5fb593ae..cc7e3fe5 100644 --- a/module/htdocs/css/shinken-layout.css +++ b/module/htdocs/css/shinken-layout.css @@ -41,7 +41,7 @@ body { } .page-header { - margin-top:5px; + margin-top:15px; } .breadcrumb { diff --git a/module/plugins/eltdetail/views/_eltdetail_information.tpl b/module/plugins/eltdetail/views/_eltdetail_information.tpl index 2e7963eb..70dc680b 100644 --- a/module/plugins/eltdetail/views/_eltdetail_information.tpl +++ b/module/plugins/eltdetail/views/_eltdetail_information.tpl @@ -223,17 +223,49 @@
- %if elt.notes_url or elt.action_url or elt.notes: + %if elt.notes or elt.notes_url: - %if elt.notes != '': -

{{ elt.notes }}

+ + %if elt.notes: + + %end + + %if elt.notes_url: + + %end + %end + + %if elt.action_url: + + + %end + + %elt_type = elt.__class__.my_type + %tags = elt.get_service_tags() if elt_type=='service' else elt.get_host_tags() + %if tags: + %tag='stag' if elt_type=='service' else 'htag' + + %end diff --git a/module/plugins/eltdetail/views/eltdetail.tpl b/module/plugins/eltdetail/views/eltdetail.tpl index b28d0e05..f38aa149 100644 --- a/module/plugins/eltdetail/views/eltdetail.tpl +++ b/module/plugins/eltdetail/views/eltdetail.tpl @@ -23,7 +23,7 @@ Invalid element name %breadcrumb += [[elt.display_name, '/service/'+helper.get_uri_name(elt)]] %end -%js=['js/jquery.sparkline.min.js', 'js/shinken-charts.js', 'availability/js/justgage.js', 'availability/js/raphael-2.1.4.min.js', 'cv_host/js/flot/jquery.flot.min.js', 'cv_host/js/flot/jquery.flot.tickrotor.js', 'cv_host/js/flot/jquery.flot.resize.min.js', 'cv_host/js/flot/jquery.flot.pie.min.js', 'cv_host/js/flot/jquery.flot.categories.min.js', 'cv_host/js/flot/jquery.flot.time.min.js', 'cv_host/js/flot/jquery.flot.stack.min.js', 'cv_host/js/flot/jquery.flot.valuelabels.js', 'eltdetail/js/custom_views.js', 'eltdetail/js/eltdetail.js', 'logs/js/history.js'] +%js=['js/jquery.sparkline.min.js', 'js/shinken-charts.js', 'cv_host/js/flot/jquery.flot.min.js', 'cv_host/js/flot/jquery.flot.tickrotor.js', 'cv_host/js/flot/jquery.flot.resize.min.js', 'cv_host/js/flot/jquery.flot.pie.min.js', 'cv_host/js/flot/jquery.flot.categories.min.js', 'cv_host/js/flot/jquery.flot.time.min.js', 'cv_host/js/flot/jquery.flot.stack.min.js', 'cv_host/js/flot/jquery.flot.valuelabels.js', 'eltdetail/js/custom_views.js', 'eltdetail/js/eltdetail.js', 'logs/js/history.js'] %if app.logs_module.is_available(): %js=js + ['availability/js/justgage.js', 'availability/js/raphael-2.1.4.min.js'] %end diff --git a/module/plugins/problems/views/_problems_eltdetail.tpl b/module/plugins/problems/views/_problems_eltdetail.tpl index e776a5e5..f1b9f9dd 100644 --- a/module/plugins/problems/views/_problems_eltdetail.tpl +++ b/module/plugins/problems/views/_problems_eltdetail.tpl @@ -71,11 +71,28 @@ %end
- %if pb.notes or pb.notes_url: -
- {{ pb.notes }}
- {{ pb.notes_url }} -
+ %if pb.notes: + + %end + + %if pb.notes_url: + + %end + + %if pb.action_url: + %end %if pb.perf_data: diff --git a/test/test-configurations/alignak/etc/arbiter/objects/hosts/localhost.cfg b/test/test-configurations/alignak/etc/arbiter/objects/hosts/localhost.cfg index 3c635283..6faf7f90 100644 --- a/test/test-configurations/alignak/etc/arbiter/objects/hosts/localhost.cfg +++ b/test/test-configurations/alignak/etc/arbiter/objects/hosts/localhost.cfg @@ -10,6 +10,15 @@ define host{ contact_groups admins # GPS - _LOC_LAT 45.054700 - _LOC_LNG 5.080856 + _LOC_LAT 45.054700 + _LOC_LNG 5.080856 + + tags +fred + + notes simple note... only text but may be formated + + notes_url http://www.my-KB.fr?host=$HOSTADDRESS$ + + action_url http://www.my-KB.fr?host=$HOSTNAME$ + } diff --git a/test/test-configurations/alignak/etc/arbiter/objects/hosts/localhost2.cfg b/test/test-configurations/alignak/etc/arbiter/objects/hosts/localhost2.cfg index 890ff6e6..bf2d973c 100644 --- a/test/test-configurations/alignak/etc/arbiter/objects/hosts/localhost2.cfg +++ b/test/test-configurations/alignak/etc/arbiter/objects/hosts/localhost2.cfg @@ -9,8 +9,6 @@ define host{ contact_groups admins - tags +fred - _satellites arbiter-master$(arbiter)$$(arbiter-master)$$(7770)$,\ scheduler-master$(scheduler)$$(scheduler-master)$$(7768)$,\ scheduler-second$(scheduler)$$(scheduler-second)$$(17768)$,\ @@ -21,6 +19,28 @@ define host{ receiver-master$(receiver)$$(receiver-master)$$(7773)$ # GPS - _LOC_LAT 45.054700 - _LOC_LNG 5.080856 + _LOC_LAT 45.054700 + _LOC_LNG 5.080856 + + tags +fred + + notes simple note... only text but may be formated\ + |Title::note with only title...\ + |Title,,file::note with a title and an icon...\ + |Title,,file::note with a title and an icon and an url...,,http://my-url.fr\ + |KB5126,,tag::Lorem ipsum dolor sit amet, consectetur adipiscing elit. \ + Proin et leo gravida, lobortis nunc nec, imperdiet odio. Vivamus quam velit, scelerisque \ + nec egestas et, semper ut massa. Vestibulum id tincidunt lacus. Ut in arcu at ex egestas \ + vestibulum eu non sapien. Nulla facilisi. \ + Aliquam non blandit tellus, non luctus tortor. \ + Mauris tortor libero, egestas quis rhoncus in, sollicitudin et tortor.,,http://my-url.fr\ + + notes_url http://www.my-KB.fr?host=$HOSTADDRESS$|http://www.my-KB.fr?host=$HOSTNAME$ + + action_url http://www.google.fr|url1::http://www.google.fr|\ + My KB,,tag::http://www.my-KB.fr?host=$HOSTNAME$|\ + Last URL,,tag::Lorem ipsum dolor sit amet, consectetur adipiscing elit. \ + Proin et leo gravida, lobortis nunc nec, imperdiet odio. Vivamus quam velit, scelerisque \ + nec egestas et, semper ut massa.,,http://www.my-KB.fr?host=$HOSTADDRESS$ + } diff --git a/test/test-configurations/shinken/etc/arbiter/objects/hosts/localhost.cfg b/test/test-configurations/shinken/etc/arbiter/objects/hosts/localhost.cfg index 3c635283..6faf7f90 100644 --- a/test/test-configurations/shinken/etc/arbiter/objects/hosts/localhost.cfg +++ b/test/test-configurations/shinken/etc/arbiter/objects/hosts/localhost.cfg @@ -10,6 +10,15 @@ define host{ contact_groups admins # GPS - _LOC_LAT 45.054700 - _LOC_LNG 5.080856 + _LOC_LAT 45.054700 + _LOC_LNG 5.080856 + + tags +fred + + notes simple note... only text but may be formated + + notes_url http://www.my-KB.fr?host=$HOSTADDRESS$ + + action_url http://www.my-KB.fr?host=$HOSTNAME$ + } diff --git a/test/test-configurations/shinken/etc/arbiter/objects/hosts/localhost2.cfg b/test/test-configurations/shinken/etc/arbiter/objects/hosts/localhost2.cfg index 890ff6e6..bf2d973c 100644 --- a/test/test-configurations/shinken/etc/arbiter/objects/hosts/localhost2.cfg +++ b/test/test-configurations/shinken/etc/arbiter/objects/hosts/localhost2.cfg @@ -9,8 +9,6 @@ define host{ contact_groups admins - tags +fred - _satellites arbiter-master$(arbiter)$$(arbiter-master)$$(7770)$,\ scheduler-master$(scheduler)$$(scheduler-master)$$(7768)$,\ scheduler-second$(scheduler)$$(scheduler-second)$$(17768)$,\ @@ -21,6 +19,28 @@ define host{ receiver-master$(receiver)$$(receiver-master)$$(7773)$ # GPS - _LOC_LAT 45.054700 - _LOC_LNG 5.080856 + _LOC_LAT 45.054700 + _LOC_LNG 5.080856 + + tags +fred + + notes simple note... only text but may be formated\ + |Title::note with only title...\ + |Title,,file::note with a title and an icon...\ + |Title,,file::note with a title and an icon and an url...,,http://my-url.fr\ + |KB5126,,tag::Lorem ipsum dolor sit amet, consectetur adipiscing elit. \ + Proin et leo gravida, lobortis nunc nec, imperdiet odio. Vivamus quam velit, scelerisque \ + nec egestas et, semper ut massa. Vestibulum id tincidunt lacus. Ut in arcu at ex egestas \ + vestibulum eu non sapien. Nulla facilisi. \ + Aliquam non blandit tellus, non luctus tortor. \ + Mauris tortor libero, egestas quis rhoncus in, sollicitudin et tortor.,,http://my-url.fr\ + + notes_url http://www.my-KB.fr?host=$HOSTADDRESS$|http://www.my-KB.fr?host=$HOSTNAME$ + + action_url http://www.google.fr|url1::http://www.google.fr|\ + My KB,,tag::http://www.my-KB.fr?host=$HOSTNAME$|\ + Last URL,,tag::Lorem ipsum dolor sit amet, consectetur adipiscing elit. \ + Proin et leo gravida, lobortis nunc nec, imperdiet odio. Vivamus quam velit, scelerisque \ + nec egestas et, semper ut massa.,,http://www.my-KB.fr?host=$HOSTADDRESS$ + } From daa73649ea5ccf6a007ef73f8313ce7cc2ae944d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Wed, 16 Jan 2019 15:03:01 +0100 Subject: [PATCH 02/50] Closes #677 - update views (element, problems, custom) --- module/plugins/cv_host/views/cv_host.tpl | 68 +++++++++++++------ .../views/_eltdetail_information.tpl | 10 +-- .../problems/views/_problems_eltdetail.tpl | 10 +-- 3 files changed, 53 insertions(+), 35 deletions(-) diff --git a/module/plugins/cv_host/views/cv_host.tpl b/module/plugins/cv_host/views/cv_host.tpl index 0cb4fe60..05fca06a 100644 --- a/module/plugins/cv_host/views/cv_host.tpl +++ b/module/plugins/cv_host/views/cv_host.tpl @@ -36,8 +36,8 @@ // Red : '#dc4950', '#e05e65' // Orange : '#F1B16E', '#EC9054' // Grey : '#dddddd', '#666666' - var main_colors = {'UNKNOWN' : '#c1bad9', 'OK' : '#A6CE8D', 'UP' : '#A6CE8D', 'WARNING' : '#F1B16E', 'CRITICAL' : '#dc4950', 'DOWN' : '#dc4950', 'ACK' : '#dddddd', 'DOWNTIME' : '#666666'}; - var huge_colors = {'UNKNOWN' : '#a79fcb', 'OK' : '#81BA6B', 'UP' : '#81BA6B', 'WARNING' : '#EC9054', 'CRITICAL' : '#e05e65', 'DOWN' : '#e05e65', 'ACK' : '#666666', 'DOWNTIME' : '#dddddd'}; + var main_colors = {'UNKNOWN' : '#c1bad9', 'OK' : '#A6CE8D', 'UP' : '#A6CE8D', 'WARNING' : '#F1B16E', 'UNREACHABLE' : '#F1B16E', 'CRITICAL' : '#dc4950', 'DOWN' : '#dc4950', 'ACK' : '#dddddd', 'DOWNTIME' : '#666666'}; + var huge_colors = {'UNKNOWN' : '#a79fcb', 'OK' : '#81BA6B', 'UP' : '#81BA6B', 'WARNING' : '#EC9054', 'UNREACHABLE' : '#F1B16E', 'CRITICAL' : '#e05e65', 'DOWN' : '#e05e65', 'ACK' : '#666666', 'DOWNTIME' : '#dddddd'}; var global_state = "{{all_states['host']}}"; var main_color = main_colors[global_state]; @@ -117,32 +117,58 @@
Tags:
- %for t in sorted(elt.get_host_tags()): - - - - %end + %if elt.get_host_tags(): + %for t in sorted(elt.get_host_tags()): + + + + %end + %else: + (none) + %end
+ %end -
Groups:
- %if len(elt.hostgroups) > 0: + %if elt.notes or elt.notes_url: +
Notes:
- %i=0 - %for hg in elt.hostgroups: - {{',' if i != 0 else ''}} - {{hg.alias if hg.alias else hg.get_name()}} - %i=i+1 + %if elt.notes: +

{{! elt.notes}}

+ %end + + %if elt.notes_url: +
    + %for note in app.helper.get_element_notes_url(elt, icon="external-link-square", css='class="btn btn-info btn-xs"'): +
  • {{! note}}
  • + %end +
+ %end +
%end + + %if elt.action_url: +
Actions:
+
+
    + %for action in app.helper.get_element_actions_url(elt, title="", icon="cogs", css='class="btn btn-warning btn-xs"'): +
  • {{! action}}
  • + %end +
- %else: -
(none)
%end - %if elt.notes or elt.notes_url: -
- {{ elt.notes }}
- {{ elt.notes_url }} -
+
Groups:
+ %if elt.hostgroups: +
+ %i=0 + %for hg in elt.hostgroups: + {{',' if i != 0 else ''}} + {{hg.alias if hg.alias else hg.get_name()}} + %i=i+1 + %end +
+ %else: +
(none)
%end
diff --git a/module/plugins/eltdetail/views/_eltdetail_information.tpl b/module/plugins/eltdetail/views/_eltdetail_information.tpl index 70dc680b..efbf6ef5 100644 --- a/module/plugins/eltdetail/views/_eltdetail_information.tpl +++ b/module/plugins/eltdetail/views/_eltdetail_information.tpl @@ -227,16 +227,12 @@ %if elt.notes: - +

{{! elt.notes}}

%end %if elt.notes_url: @@ -246,7 +242,7 @@ %if elt.action_url: diff --git a/module/plugins/problems/views/_problems_eltdetail.tpl b/module/plugins/problems/views/_problems_eltdetail.tpl index f1b9f9dd..0a1ec8f9 100644 --- a/module/plugins/problems/views/_problems_eltdetail.tpl +++ b/module/plugins/problems/views/_problems_eltdetail.tpl @@ -72,16 +72,12 @@ %if pb.notes: - +

{{! pb.notes}}

%end %if pb.notes_url: @@ -89,7 +85,7 @@ %if pb.action_url: From 517d0ead14ff3025e432a662ddc51e868df0acd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Mon, 14 Jan 2019 06:45:35 +0100 Subject: [PATCH 03/50] Display contacts notification status in contacts list --- module/plugins/contacts/views/contacts.tpl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/module/plugins/contacts/views/contacts.tpl b/module/plugins/contacts/views/contacts.tpl index 954dd0b4..3f250b49 100644 --- a/module/plugins/contacts/views/contacts.tpl +++ b/module/plugins/contacts/views/contacts.tpl @@ -18,6 +18,7 @@ Name Alias Business impact + Notifications Email Notification way @@ -40,6 +41,15 @@ {{ contact.alias if contact.alias != "none" else "" }} {{ contact.min_business_impact }} + + %if not contact.host_notifications_enabled and not contact.service_notifications_enabled: + None + %else: + + {{ 'hosts' if contact.host_notifications_enabled else '' }} - {{ 'services' if contact.service_notifications_enabled else ''}} + + %end + %if contact.email != "none": {{contact.email}} From 16bdc5ea0d19f04c0cb517ff2e1debaa3e287ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Wed, 16 Jan 2019 07:16:40 +0100 Subject: [PATCH 04/50] Element view, add hosts groups which host is member of --- .../views/_eltdetail_information.tpl | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/module/plugins/eltdetail/views/_eltdetail_information.tpl b/module/plugins/eltdetail/views/_eltdetail_information.tpl index efbf6ef5..0387633f 100644 --- a/module/plugins/eltdetail/views/_eltdetail_information.tpl +++ b/module/plugins/eltdetail/views/_eltdetail_information.tpl @@ -443,17 +443,18 @@ - %# Could be displayed here - %#
Member of:
- %#%if elt_service.servicegroups: - %#
- %#%for sg in elt_service.servicegroups: - %#{{sg.alias}} ({{sg.get_name()}}) - %#%end - %#
- %#%else: - %#
(none)
- %#%end + %if getattr(elt, 'hostgroups', None): + + + + %end From cd665f52377a4e53c75b93f4123ad66b4fe9c7ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20MOHIER?= Date: Fri, 11 Jan 2019 07:05:13 +0100 Subject: [PATCH 05/50] Fix #708 - actions bar on small devices --- module/htdocs/css/shinken-layout.css | 16 ++- .../views/_problems_actions-navbar.tpl | 126 +++++++++--------- module/plugins/problems/views/problems.tpl | 6 +- module/views/header_element.tpl | 10 +- 4 files changed, 85 insertions(+), 73 deletions(-) diff --git a/module/htdocs/css/shinken-layout.css b/module/htdocs/css/shinken-layout.css index cc7e3fe5..4e4d2fab 100644 --- a/module/htdocs/css/shinken-layout.css +++ b/module/htdocs/css/shinken-layout.css @@ -446,8 +446,16 @@ footer nav { background: none; text-align: center; } + #nav-actions { + position: fixed; + top: 0; + left: 50%; + transform: translateX(-50%); - #action-menu ul { + margin: 0; padding: 0; + } + + #nav-actions ul, #action-menu ul { list-style: none; } @@ -461,7 +469,11 @@ footer nav { font-size: 16px; } - #action-menu li a { + #nav-actions li { + display: inline; + } + + #nav-actions li a, #action-menu li a { display: inline; } } diff --git a/module/plugins/problems/views/_problems_actions-navbar.tpl b/module/plugins/problems/views/_problems_actions-navbar.tpl index 54557d09..37a30847 100644 --- a/module/plugins/problems/views/_problems_actions-navbar.tpl +++ b/module/plugins/problems/views/_problems_actions-navbar.tpl @@ -1,62 +1,64 @@ - -%if app.can_action(): -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -%s = app.datamgr.get_services_synthesis(user=user, elts=all_pbs) -%h = app.datamgr.get_hosts_synthesis(user=user, elts=all_pbs) -%if s and s['nb_ack']: -
  • - -
  • -%end -%if s and s['nb_downtime']: -
  • - -
  • -%end -%end + diff --git a/module/plugins/problems/views/problems.tpl b/module/plugins/problems/views/problems.tpl index b3ab9aa1..2f7bef55 100644 --- a/module/plugins/problems/views/problems.tpl +++ b/module/plugins/problems/views/problems.tpl @@ -208,8 +208,6 @@ Next check {{helper.print_duration(pb.next_chk)}} %end - + - +%include('_problems_actions-navbar.tpl') diff --git a/module/views/header_element.tpl b/module/views/header_element.tpl index c4008bd4..262eb4f3 100644 --- a/module/views/header_element.tpl +++ b/module/views/header_element.tpl @@ -79,7 +79,7 @@ may be used by the layout page refresh. --> -
  • +
  • - + -
  • +
  • %if refresh: -
  • +