Browse Source

Change icon CSS class prefix to work around Fanboy's filter list

Problem: if you use uBlock Origin, and enable the
"Fanboy's Social" filter list, Healthchecks does not show
Telegram or WhatsApp icons. This is because the filter list
contains "##.icon-telegram" and "##.icon-whatsapp" entries.

This commit changes the CSS class prefix to "ic-". So we're
now using icon classes like "ic-telegram" and "ic-whatsapp".

As a bonus, we save 2 bytes in HTML per displayed icon :-)
pull/476/head
Pēteris Caune 4 years ago
parent
commit
67560c96e1
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
23 changed files with 87 additions and 87 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +1
    -1
      hc/api/admin.py
  3. +1
    -1
      hc/front/tests/test_channels.py
  4. +3
    -3
      hc/front/tests/test_my_checks.py
  5. +4
    -4
      static/css/base.css
  6. +1
    -1
      static/css/channels.css
  7. +45
    -46
      static/css/icomoon.css
  8. +1
    -1
      static/css/settings.css
  9. BIN
      static/fonts/icomoon.ttf
  10. BIN
      static/fonts/icomoon.woff
  11. +4
    -4
      static/js/checks.js
  12. +1
    -1
      static/js/details.js
  13. +1
    -1
      static/js/snippet-copy.js
  14. +2
    -2
      templates/accounts/project.html
  15. +1
    -1
      templates/base.html
  16. +1
    -1
      templates/front/channels.html
  17. +2
    -2
      templates/front/details.html
  18. +2
    -2
      templates/front/details_events.html
  19. +1
    -1
      templates/front/last_ping_cell.html
  20. +2
    -2
      templates/front/log.html
  21. +8
    -8
      templates/front/my_checks_desktop.html
  22. +1
    -1
      templates/front/projects.html
  23. +4
    -4
      templates/front/welcome.html

+ 1
- 0
CHANGELOG.md View File

@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file.
## Bug Fixes ## Bug Fixes
- Fix unwanted HTML escaping in SMS and WhatsApp notifications - Fix unwanted HTML escaping in SMS and WhatsApp notifications
- Fix a crash when adding an integration for an empty Trello account - Fix a crash when adding an integration for an empty Trello account
- Change icon CSS class prefix to 'ic-' to work around Fanboy's filter list
## v1.18.0 - 2020-12-09 ## v1.18.0 - 2020-12-09


+ 1
- 1
hc/api/admin.py View File

@ -199,7 +199,7 @@ class ChannelsAdmin(admin.ModelAdmin):
if obj.kind == "email" and not obj.email_verified: if obj.kind == "email" and not obj.email_verified:
note = " (not verified)" note = " (not verified)"
return f'<span class="icon-{ obj.kind }"></span> &nbsp; {obj.kind}{note}'
return f'<span class="ic-{ obj.kind }"></span> &nbsp; {obj.kind}{note}'
def ok(self, obj): def ok(self, obj):
return False if obj.last_error else True return False if obj.last_error else True


+ 1
- 1
hc/front/tests/test_channels.py View File

@ -119,5 +119,5 @@ class ChannelsTestCase(BaseTestCase):
r = self.client.get(self.channels_url) r = self.client.get(self.channels_url)
self.assertNotContains(r, "Add Integration", status_code=200) self.assertNotContains(r, "Add Integration", status_code=200)
self.assertNotContains(r, "icon-delete")
self.assertNotContains(r, "ic-delete")
self.assertNotContains(r, "edit_webhook") self.assertNotContains(r, "edit_webhook")

+ 3
- 3
hc/front/tests/test_my_checks.py View File

@ -55,7 +55,7 @@ class MyChecksTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url) r = self.client.get(self.url)
self.assertContains(r, "icon-up")
self.assertContains(r, "ic-up")
def test_it_shows_red_check(self): def test_it_shows_red_check(self):
self.check.last_ping = timezone.now() - td(days=3) self.check.last_ping = timezone.now() - td(days=3)
@ -64,7 +64,7 @@ class MyChecksTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url) r = self.client.get(self.url)
self.assertContains(r, "icon-down")
self.assertContains(r, "ic-down")
def test_it_shows_amber_check(self): def test_it_shows_amber_check(self):
self.check.last_ping = timezone.now() - td(days=1, minutes=30) self.check.last_ping = timezone.now() - td(days=1, minutes=30)
@ -73,7 +73,7 @@ class MyChecksTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url) r = self.client.get(self.url)
self.assertContains(r, "icon-grace")
self.assertContains(r, "ic-grace")
def test_it_hides_add_check_button(self): def test_it_hides_add_check_button(self):
self.profile.check_limit = 0 self.profile.check_limit = 0


+ 4
- 4
static/css/base.css View File

@ -99,10 +99,10 @@ body {
width: 24px; width: 24px;
} }
.status.icon-up, .status.icon-started { color: #5cb85c; }
.status.icon-new, .status.icon-paused { color: #CCC; }
.status.icon-grace { color: #f0ad4e; }
.status.icon-down { color: #d9534f; }
.status.ic-up, .status.ic-started { color: #5cb85c; }
.status.ic-new, .status.ic-paused { color: #CCC; }
.status.ic-grace { color: #f0ad4e; }
.status.ic-down { color: #d9534f; }
.label.label-start { .label.label-start {
background-color: #FFF; background-color: #FFF;


+ 1
- 1
static/css/channels.css View File

@ -228,7 +228,7 @@ table.channels-table > tbody > tr > th {
margin-bottom: 0; margin-bottom: 0;
} }
.page-channels .icon-delete {
.page-channels .ic-delete {
font-size: 16px; font-size: 16px;
} }


+ 45
- 46
static/css/icomoon.css View File

@ -1,15 +1,14 @@
@font-face { @font-face {
font-family: 'icomoon'; font-family: 'icomoon';
src: url('../fonts/icomoon.eot?y9u69e');
src: url('../fonts/icomoon.eot?y9u69e#iefix') format('embedded-opentype'),
url('../fonts/icomoon.ttf?y9u69e') format('truetype'),
url('../fonts/icomoon.woff?y9u69e') format('woff'),
url('../fonts/icomoon.svg?y9u69e#icomoon') format('svg');
src:
url('../fonts/icomoon.ttf?ed2ba') format('truetype'),
url('../fonts/icomoon.woff?ed2ba') format('woff'),
url('../fonts/icomoon.svg?ed2ba#icomoon') format('svg');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
[class^="icon-"], [class*=" icon-"] {
[class^="ic-"], [class*=" ic-"] {
/* use !important to prevent issues with browser extensions that change fonts */ /* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important; font-family: 'icomoon' !important;
speak: never; speak: never;
@ -24,147 +23,147 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-signal:before {
.ic-signal:before {
content: "\e91c"; content: "\e91c";
color: #2592e9; color: #2592e9;
} }
.icon-linenotify:before {
.ic-linenotify:before {
content: "\e91b"; content: "\e91b";
color: #00c300; color: #00c300;
} }
.icon-call:before {
.ic-call:before {
content: "\e91a"; content: "\e91a";
color: #e81a34; color: #e81a34;
} }
.icon-spike:before {
.ic-spike:before {
content: "\e919"; content: "\e919";
color: #007bff; color: #007bff;
} }
.icon-zulip:before {
.ic-zulip:before {
content: "\e918"; content: "\e918";
color: #1e9459; color: #1e9459;
} }
.icon-pd:before {
.ic-pd:before {
content: "\e90b"; content: "\e90b";
color: #04ac38; color: #04ac38;
} }
.icon-shell:before {
.ic-shell:before {
content: "\e917"; content: "\e917";
} }
.icon-msteams:before {
.ic-msteams:before {
content: "\e916"; content: "\e916";
color: #4e56be; color: #4e56be;
} }
.icon-opsgenie:before {
.ic-opsgenie:before {
content: "\e910"; content: "\e910";
color: #2684ff; color: #2684ff;
} }
.icon-mattermost:before {
.ic-mattermost:before {
content: "\e907"; content: "\e907";
color: #045acc; color: #045acc;
} }
.icon-pagerteam:before {
.ic-pagerteam:before {
content: "\e914"; content: "\e914";
color: #cd2a00; color: #cd2a00;
} }
.icon-apprise:before {
.ic-apprise:before {
content: "\e915"; content: "\e915";
color: #236b6b; color: #236b6b;
} }
.icon-matrix:before {
.ic-matrix:before {
content: "\e900"; content: "\e900";
} }
.icon-started:before {
.ic-started:before {
content: "\e038"; content: "\e038";
} }
.icon-pagertree:before {
.ic-pagertree:before {
content: "\e90d"; content: "\e90d";
color: #33ade2; color: #33ade2;
} }
.icon-po:before {
.ic-po:before {
content: "\e90e"; content: "\e90e";
color: #249df1; color: #249df1;
} }
.icon-victorops:before {
.ic-victorops:before {
content: "\e90f"; content: "\e90f";
color: #f9af4a; color: #f9af4a;
} }
.icon-email:before {
.ic-email:before {
content: "\e90a"; content: "\e90a";
color: #4f5d73; color: #4f5d73;
} }
.icon-webhook:before {
.ic-webhook:before {
content: "\e908"; content: "\e908";
color: #c73a63; color: #c73a63;
} }
.icon-sms:before {
.ic-sms:before {
content: "\e904"; content: "\e904";
color: #95c144; color: #95c144;
} }
.icon-pushbullet:before {
.ic-pushbullet:before {
content: "\e909"; content: "\e909";
color: #67bf79; color: #67bf79;
} }
.icon-discord:before {
.ic-discord:before {
content: "\e90c"; content: "\e90c";
color: #7289da; color: #7289da;
} }
.icon-hipchat:before {
.ic-hipchat:before {
content: "\e901"; content: "\e901";
color: #0052cc; color: #0052cc;
} }
.icon-slack:before {
.ic-slack:before {
content: "\e905"; content: "\e905";
color: #56b68b; color: #56b68b;
} }
.icon-telegram:before {
.ic-telegram:before {
content: "\e906"; content: "\e906";
color: #2ca5e0; color: #2ca5e0;
} }
.icon-trello:before {
.ic-trello:before {
content: "\e911"; content: "\e911";
color: #0079bf; color: #0079bf;
} }
.icon-whatsapp:before {
.ic-whatsapp:before {
content: "\e902"; content: "\e902";
color: #25d366; color: #25d366;
} }
.icon-clippy:before {
.ic-clippy:before {
content: "\e903"; content: "\e903";
} }
.icon-cancel:before {
.ic-cancel:before {
content: "\e5c9"; content: "\e5c9";
} }
.icon-up:before, .icon-new:before, .icon-ok:before {
.ic-up:before, .ic-new:before, .ic-ok:before {
content: "\e86c"; content: "\e86c";
} }
.icon-grace:before {
.ic-grace:before {
content: "\e000"; content: "\e000";
} }
.icon-missing:before {
.ic-missing:before {
content: "\e001"; content: "\e001";
} }
.icon-desc:before {
.ic-desc:before {
content: "\e313"; content: "\e313";
} }
.icon-asc:before {
.ic-asc:before {
content: "\e316"; content: "\e316";
} }
.icon-dots:before {
.ic-dots:before {
content: "\e5d3"; content: "\e5d3";
} }
.icon-down:before {
.ic-down:before {
content: "\e7f7"; content: "\e7f7";
} }
.icon-paused:before {
.ic-paused:before {
content: "\e7f6"; content: "\e7f6";
} }
.icon-settings:before {
.ic-settings:before {
content: "\e912"; content: "\e912";
} }
.icon-delete:before {
.ic-delete:before {
content: "\e913"; content: "\e913";
} }
.icon-timer:before {
.ic-timer:before {
content: "\e425"; content: "\e425";
} }

+ 1
- 1
static/css/settings.css View File

@ -11,7 +11,7 @@
padding-bottom: 24px; padding-bottom: 24px;
} }
.page-project .icon-ok {
.page-project .ic-ok {
color: #5cb85c; color: #5cb85c;
} }


BIN
static/fonts/icomoon.ttf View File


BIN
static/fonts/icomoon.woff View File


+ 4
- 4
static/js/checks.js View File

@ -165,7 +165,7 @@ $(function () {
// Second click: update UI and pause the check // Second click: update UI and pause the check
btn.removeClass("confirm").tooltip("hide"); btn.removeClass("confirm").tooltip("hide");
var code = btn.closest("tr.checks-row").attr("id"); var code = btn.closest("tr.checks-row").attr("id");
$("#" + code + " span.status").attr("class", "status icon-paused");
$("#" + code + " span.status").attr("class", "status ic-paused");
var url = base + "/checks/" + code + "/pause/"; var url = base + "/checks/" + code + "/pause/";
var token = $('input[name=csrfmiddlewaretoken]').val(); var token = $('input[name=csrfmiddlewaretoken]').val();
@ -187,9 +187,9 @@ $(function () {
container: "body", container: "body",
title: function() { title: function() {
var cssClasses = this.getAttribute("class"); var cssClasses = this.getAttribute("class");
if (cssClasses.indexOf("icon-new") > -1)
if (cssClasses.indexOf("ic-new") > -1)
return "New. Has never received a ping."; return "New. Has never received a ping.";
if (cssClasses.indexOf("icon-paused") > -1)
if (cssClasses.indexOf("ic-paused") > -1)
return "Monitoring paused. Ping to resume."; return "Monitoring paused. Ping to resume.";
if (cssClasses.indexOf("sort-name") > -1) if (cssClasses.indexOf("sort-name") > -1)
@ -215,7 +215,7 @@ $(function () {
for(var i=0, el; el=data.details[i]; i++) { for(var i=0, el; el=data.details[i]; i++) {
if (lastStatus[el.code] != el.status) { if (lastStatus[el.code] != el.status) {
lastStatus[el.code] = el.status; lastStatus[el.code] = el.status;
$("#" + el.code + " span.status").attr("class", "status icon-" + el.status);
$("#" + el.code + " span.status").attr("class", "status ic-" + el.status);
} }
if (lastStarted[el.code] != el.started) { if (lastStarted[el.code] != el.started) {


+ 1
- 1
static/js/details.js View File

@ -85,7 +85,7 @@ $(function () {
success: function(data) { success: function(data) {
if (data.status_text != lastStatusText) { if (data.status_text != lastStatusText) {
lastStatusText = data.status_text; lastStatusText = data.status_text;
$("#log-status-icon").attr("class", "status icon-" + data.status);
$("#log-status-icon").attr("class", "status ic-" + data.status);
$("#log-status-text").html(data.status_text); $("#log-status-text").html(data.status_text);
$('#pause-btn').prop('disabled', data.status == "paused"); $('#pause-btn').prop('disabled', data.status == "paused");


+ 1
- 1
static/js/snippet-copy.js View File

@ -5,7 +5,7 @@ $(function() {
} }
var markup = '<button class="btn btn-default hidden-sm">' + var markup = '<button class="btn btn-default hidden-sm">' +
'<span class="icon-clippy"></span>' +
'<span class="ic-clippy"></span>' +
'</button>'; '</button>';


+ 2
- 2
templates/accounts/project.html View File

@ -110,7 +110,7 @@
{% else %} {% else %}
<form method="post"> <form method="post">
<span class="icon-ok"></span>
<span class="ic-ok"></span>
API access is enabled. API access is enabled.
{% csrf_token %} {% csrf_token %}
@ -123,7 +123,7 @@
</form> </form>
{% endif %} {% endif %}
{% else %} {% else %}
<span class="icon-cancel"></span>
<span class="ic-cancel"></span>
API access is disabled. API access is disabled.
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}


+ 1
- 1
templates/base.html View File

@ -106,7 +106,7 @@
<li {% if b %}id="broken-channels"{% endif %} {% if page == 'channels' %}class="active"{% endif %}> <li {% if b %}id="broken-channels"{% endif %} {% if page == 'channels' %}class="active"{% endif %}>
<a href="{% url 'hc-channels' project.code %}"> <a href="{% url 'hc-channels' project.code %}">
{% trans "Integrations" %} {% trans "Integrations" %}
{% if b %}<span class="icon-grace"></span>{% endif %}
{% if b %}<span class="ic-grace"></span>{% endif %}
</a> </a>
</li> </li>
{% endwith %} {% endwith %}


+ 1
- 1
templates/front/channels.html View File

@ -159,7 +159,7 @@
data-url="{% url 'hc-remove-channel' ch.code %}" data-url="{% url 'hc-remove-channel' ch.code %}"
class="btn btn-sm btn-default channel-remove" class="btn btn-sm btn-default channel-remove"
type="button"> type="button">
<span class="icon-delete"></span>
<span class="ic-delete"></span>
</button> </button>
{% endif %} {% endif %}
</td> </td>


+ 2
- 2
templates/front/details.html View File

@ -117,7 +117,7 @@
<table> <table>
<tr> <tr>
<td> <td>
<span id="log-status-icon" class="status icon-{{ check.get_status }}"></span>
<span id="log-status-icon" class="status ic-{{ check.get_status }}"></span>
</td> </td>
<td > <td >
<p id="log-status-text">{% include "front/log_status_text.html" %}</p> <p id="log-status-text">{% include "front/log_status_text.html" %}</p>
@ -215,7 +215,7 @@
</span> </span>
</th> </th>
<td> <td>
<span class="icon-{{ channel.kind }}"></span>
<span class="ic-{{ channel.kind }}"></span>
{{ channel }} {{ channel }}
</td> </td>
</tr> </tr>


+ 2
- 2
templates/front/details_events.html View File

@ -25,7 +25,7 @@
<td class="details"> <td class="details">
{% if event.delta %} {% if event.delta %}
<div class="delta"> <div class="delta">
<span class="icon-timer"></span>
<span class="ic-timer"></span>
{{ event.delta|hms }} {{ event.delta|hms }}
</div> </div>
{% endif %} {% endif %}
@ -50,7 +50,7 @@
{% if event.check_status %} {% if event.check_status %}
<tr class="missing" data-dt="{{ event.created.isoformat }}"> <tr class="missing" data-dt="{{ event.created.isoformat }}">
<td class="n-cell"> <td class="n-cell">
<span class="icon-missing"></span>
<span class="ic-missing"></span>
</td> </td>
<td class="date"></td> <td class="date"></td>
<td class="time"></td> <td class="time"></td>


+ 1
- 1
templates/front/last_ping_cell.html View File

@ -7,7 +7,7 @@
{% elif check.clamped_last_duration %} {% elif check.clamped_last_duration %}
<br /> <br />
<span class="checks-subline-duration"> <span class="checks-subline-duration">
<span class="icon-timer"></span> {{ check.clamped_last_duration|hms }}
<span class="ic-timer"></span> {{ check.clamped_last_duration|hms }}
</span> </span>
{% endif %} {% endif %}
{% else %} {% else %}


+ 2
- 2
templates/front/log.html View File

@ -66,7 +66,7 @@
<td class="details"> <td class="details">
{% if event.delta %} {% if event.delta %}
<div class="delta"> <div class="delta">
<span class="icon-timer"></span>
<span class="ic-timer"></span>
{{ event.delta|hms }} {{ event.delta|hms }}
</div> </div>
{% endif %} {% endif %}
@ -100,7 +100,7 @@
{% if event.check_status %} {% if event.check_status %}
<tr class="missing" data-dt="{{ event.created.isoformat }}"> <tr class="missing" data-dt="{{ event.created.isoformat }}">
<td class="n-cell"> <td class="n-cell">
<span class="icon-missing"></span>
<span class="ic-missing"></span>
</td> </td>
<td class="date"></td> <td class="date"></td>
<td class="time"></td> <td class="time"></td>


+ 8
- 8
templates/front/my_checks_desktop.html View File

@ -9,11 +9,11 @@
<th class="th-name"> <th class="th-name">
{% if sort == "name" %} {% if sort == "name" %}
<a href="?sort=-name" data-toggle="tooltip" class="sort-name"> <a href="?sort=-name" data-toggle="tooltip" class="sort-name">
Name<span class="icon-asc"></span>
Name<span class="ic-asc"></span>
</a> </a>
{% elif sort == "-name" %} {% elif sort == "-name" %}
<a href="?sort=created" data-toggle="tooltip" class="sort-name"> <a href="?sort=created" data-toggle="tooltip" class="sort-name">
Name<span class="icon-desc"></span>
Name<span class="ic-desc"></span>
</a> </a>
{% else %} {% else %}
<a href="?sort=name" data-toggle="tooltip" class="default sort-name"> <a href="?sort=name" data-toggle="tooltip" class="default sort-name">
@ -33,11 +33,11 @@
<th class="th-last-ping hidden-xs"> <th class="th-last-ping hidden-xs">
{% if sort == "last_ping" %} {% if sort == "last_ping" %}
<a href="?sort=created" data-toggle="tooltip" class="sort-last-ping"> <a href="?sort=created" data-toggle="tooltip" class="sort-last-ping">
Last Ping<span class="icon-desc"></span>
Last Ping<span class="ic-desc"></span>
</a> </a>
{% elif sort == "-last_ping" %} {% elif sort == "-last_ping" %}
<a href="?sort=last_ping" data-toggle="tooltip" class="sort-last-ping"> <a href="?sort=last_ping" data-toggle="tooltip" class="sort-last-ping">
Last Ping<span class="icon-asc"></span>
Last Ping<span class="ic-asc"></span>
</a> </a>
{% else %} {% else %}
<a href="?sort=-last_ping" data-toggle="tooltip" class="default sort-last-ping"> <a href="?sort=-last_ping" data-toggle="tooltip" class="default sort-last-ping">
@ -60,7 +60,7 @@
{% if check in hidden_checks %}style="display: none"{% endif %}> {% if check in hidden_checks %}style="display: none"{% endif %}>
<td class="indicator-cell"> <td class="indicator-cell">
<span class="status icon-{{ check.get_status }}" data-toggle="tooltip"></span>
<span class="status ic-{{ check.get_status }}" data-toggle="tooltip"></span>
<div class="spinner {% if check.last_start %}started{% endif %}"> <div class="spinner {% if check.last_start %}started{% endif %}">
<div class="d1"></div> <div class="d1"></div>
<div class="d2"></div> <div class="d2"></div>
@ -93,7 +93,7 @@
<div class="integrations"> <div class="integrations">
{% spaceless %} {% spaceless %}
{% for channel in channels %} {% for channel in channels %}
<span class="icon-{{ channel.kind }}{% if channel in check.channel_set.all %}{% else %} off{% endif %}"></span>
<span class="ic-{{ channel.kind }}{% if channel in check.channel_set.all %}{% else %} off{% endif %}"></span>
{% endfor %} {% endfor %}
{% endspaceless %} {% endspaceless %}
</div> </div>
@ -128,12 +128,12 @@
<td class="actions"> <td class="actions">
{% if rw %} {% if rw %}
<button class="btn btn-default pause" type="button"> <button class="btn btn-default pause" type="button">
<span class="icon-paused" />
<span class="ic-paused" />
</button> </button>
{% endif %} {% endif %}
<button title="Show Details" class="btn btn-default show-log" type="button"> <button title="Show Details" class="btn btn-default show-log" type="button">
<span class="icon-dots" />
<span class="ic-dots" />
</button> </button>
</td> </td>
</tr> </tr>


+ 1
- 1
templates/front/projects.html View File

@ -16,7 +16,7 @@
<a href="{% url 'hc-checks' project.code %}"> <a href="{% url 'hc-checks' project.code %}">
<div class="col-sm-6 col-md-4"> <div class="col-sm-6 col-md-4">
<div class="panel project {% if project.id == last_project_id %}selected{% endif %}"> <div class="panel project {% if project.id == last_project_id %}selected{% endif %}">
<div class="status icon-{{ project.overall_status }}"></div>
<div class="status ic-{{ project.overall_status }}"></div>
<h4>{{ project }}</h4> <h4>{{ project }}</h4>


+ 4
- 4
templates/front/welcome.html View File

@ -229,7 +229,7 @@
<table class="table"> <table class="table">
<tr> <tr>
<td> <td>
<span class="status icon-new"></span>
<span class="status ic-new"></span>
</td> </td>
<td> <td>
{% blocktrans trimmed %} {% blocktrans trimmed %}
@ -240,7 +240,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<span class="status icon-up"></span>
<span class="status ic-up"></span>
</td> </td>
<td> <td>
{% blocktrans trimmed %} {% blocktrans trimmed %}
@ -251,7 +251,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<span class="status icon-grace"></span>
<span class="status ic-grace"></span>
</td> </td>
<td> <td>
{% blocktrans trimmed %} {% blocktrans trimmed %}
@ -263,7 +263,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<span class="status icon-down"></span>
<span class="status ic-down"></span>
</td> </td>
<td> <td>
{% blocktrans trimmed %} {% blocktrans trimmed %}


Loading…
Cancel
Save