From 948872b72718181b2c18b29f908c4370c7400f63 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 31 Aug 2018 01:26:56 +0000 Subject: [PATCH 01/19] Initial prototype of interface --- src/css/style.less | 21 ++++++++++++ src/js/yunohost/controllers/diagnosis.js | 41 ++++++++++++++++++++++++ src/views/diagnosis/diagnosis_show.ms | 26 +++++++++++++++ src/views/home.ms | 4 +++ 4 files changed, 92 insertions(+) create mode 100644 src/js/yunohost/controllers/diagnosis.js create mode 100644 src/views/diagnosis/diagnosis_show.ms diff --git a/src/css/style.less b/src/css/style.less index 201309b9..a665a1db 100644 --- a/src/css/style.less +++ b/src/css/style.less @@ -810,3 +810,24 @@ input[type='radio'].nice-radio { margin: 1%; } } + +/* Just to be able to override list-group-item with alert-success's background and border colors */ +.alert-success-yo { + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-warning-yo { + background-color: #fcf8e3; + border-color: #faebcc; +} + +.alert-danger-yo { + background-color: #f2dede; + border-color: #ebccd1; +} + +.alert-info-yo { + background-color: #d9edf7; + border-color: #bce8f1; +} diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js new file mode 100644 index 00000000..0cbb5e84 --- /dev/null +++ b/src/js/yunohost/controllers/diagnosis.js @@ -0,0 +1,41 @@ +(function() { + // Get application context + var app = Sammy.apps['#main']; + var store = app.store; + + // ********* + // Diagnosis + // ********* + + // Server monitoring + app.get('#/diagnosis', function (c) { + + // Why this method ? + c.api('/diagnosis/show', function(data) { + console.log(data); + c.view('diagnosis/diagnosis_show', data); + for (var i = 0 ; i < data.reports.length ; i++) + { + for (var j = 0 ; j < data.reports[i].reports.length ; j++) + { + var type_ = data.reports[i].reports[j].report[0]; + type_ = type_.toLowerCase(); + var icon = ""; + if (type_ == "success") { + icon = "check-circle"; + } + else if (type_ == "warning") { + icon = "warning"; + } + else if (type_ == "error") { + icon = "times"; + } + data.reports[i].reports[j].report[0] = type_; + data.reports[i].reports[j].report.push(icon); + }; + }; + }, 'GET'); + + }); + +})(); diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms new file mode 100644 index 00000000..22325be1 --- /dev/null +++ b/src/views/diagnosis/diagnosis_show.ms @@ -0,0 +1,26 @@ +
+ {{t 'home'}} + {{t 'diagnosis'}} +
+ +
+ +{{#reports}} +
+
+

{{ description }}

+
+
+
    + {{#reports}} +
  • + {{#if report.[2]}} + + {{/if}} + {{report.[1]}} +
  • + {{/reports}} +
+
+
+{{/reports}} diff --git a/src/views/home.ms b/src/views/home.ms index 2206cb28..526237c2 100644 --- a/src/views/home.ms +++ b/src/views/home.ms @@ -23,6 +23,10 @@

{{t 'tools'}}

+ + +

{{t 'diagnosis'}}

+

{{t 'backup'}}

From 75ab8a3d7630e1714e0df06cfbd15d3c63dd1492 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Fri, 31 Aug 2018 13:53:13 +0000 Subject: [PATCH 02/19] Add recheck / details and ignore button to the view --- src/js/yunohost/controllers/diagnosis.js | 12 +++++++++--- src/views/diagnosis/diagnosis_show.ms | 15 +++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index 0cbb5e84..d757d52c 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -12,28 +12,34 @@ // Why this method ? c.api('/diagnosis/show', function(data) { - console.log(data); - c.view('diagnosis/diagnosis_show', data); for (var i = 0 ; i < data.reports.length ; i++) { + // Convert timestamp to datetime + data.reports[i].time = new Date(data.reports[i].timestamp*1000); for (var j = 0 ; j < data.reports[i].reports.length ; j++) { var type_ = data.reports[i].reports[j].report[0]; type_ = type_.toLowerCase(); var icon = ""; + var issue = false; + if (type_ == "success") { icon = "check-circle"; } else if (type_ == "warning") { icon = "warning"; + issue = true; } else if (type_ == "error") { icon = "times"; + issue = true; } data.reports[i].reports[j].report[0] = type_; - data.reports[i].reports[j].report.push(icon); + data.reports[i].reports[j].icon = icon; + data.reports[i].reports[j].issue = issue; }; }; + c.view('diagnosis/diagnosis_show', data); }, 'GET'); }); diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index 22325be1..9cb53b12 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -8,16 +8,23 @@ {{#reports}}
    +

    Last time ran : {{formatRelative time}}

    {{#reports}} -
  • - {{#if report.[2]}} - +
  • + {{#if icon}} + {{/if}} {{report.[1]}} + {{#if issue}} + {{t 'ignore'}} + {{t 'details'}} + {{/if}} +
  • {{/reports}}
From dbf8c8af8560c239df8195ac4f56730e844ef349 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sat, 1 Sep 2018 00:12:35 +0000 Subject: [PATCH 03/19] Implement button to rerun the diagnosis --- src/js/yunohost/controllers/diagnosis.js | 17 ++++++++++++++++- src/locales/en.json | 3 +++ src/views/diagnosis/diagnosis_show.ms | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index d757d52c..06cc52b0 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -31,6 +31,7 @@ issue = true; } else if (type_ == "error") { + type_ = "danger"; icon = "times"; issue = true; } @@ -39,7 +40,21 @@ data.reports[i].reports[j].issue = issue; }; }; - c.view('diagnosis/diagnosis_show', data); + c.view('diagnosis/diagnosis_show', data, function() { + $(".rerun-diagnosis").click(function() { + var category = $(this).attr("category"); + c.api('/diagnosis/run', function(data) { + // This is a copy-pasta of some of the + // redirect/refresh code of sammy.js + // because for some reason calling the function did not work >.> + var to = "#/diagnosis"; + c.trigger('redirect', {to: to}); + c.app.last_location = c.path; + c.app.setLocation(to); + c.app.trigger('location-changed'); + }, 'POST', {"categories": [category], "force":true}); + }); + }); }, 'GET'); }); diff --git a/src/locales/en.json b/src/locales/en.json index 1a98285d..42519ccf 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -110,6 +110,7 @@ "default": "Default", "delete": "Delete", "description": "Description", + "details": "Details", "domain_dns_conf_is_just_a_recommendation": "This page shows you the *recommended* configuration. It does *not* configure the DNS for you. It is your responsability to configure your DNS zone in your DNS registrar according to this recommendation.", "diagnosis": "Diagnosis", "diagnosis_hide_private": "Show diagnostic information without private data", @@ -177,6 +178,7 @@ "hook_data_mail_desc": "Raw emails stored on the server", "hostname": "Hostname", "id": "ID", + "ignore": "Ignore", "inactive": "Inactive", "infos": "Info", "install": "Install", @@ -288,6 +290,7 @@ "read": "Read", "read_more": "Read more", "reception": "Reception", + "rerun_diagnosis": "Rerun diagnosis", "refresh_app_list": "Refresh list", "remove_access": "Remove access", "request_adoption": "waiting adoption", diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index 9cb53b12..d4df400f 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -9,7 +9,7 @@
    From 2a41bee642f9ec7b1adc6aca8ad18202c3643b29 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 22 May 2019 18:28:40 +0200 Subject: [PATCH 04/19] Fix --force usage --- src/js/yunohost/controllers/diagnosis.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index 06cc52b0..51492f46 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -43,7 +43,7 @@ c.view('diagnosis/diagnosis_show', data, function() { $(".rerun-diagnosis").click(function() { var category = $(this).attr("category"); - c.api('/diagnosis/run', function(data) { + c.api('/diagnosis/run?force', function(data) { // This is a copy-pasta of some of the // redirect/refresh code of sammy.js // because for some reason calling the function did not work >.> @@ -52,7 +52,7 @@ c.app.last_location = c.path; c.app.setLocation(to); c.app.trigger('location-changed'); - }, 'POST', {"categories": [category], "force":true}); + }, 'POST', {"categories": [category]}); }); }); }, 'GET'); From f5b3f392d11d28e88191e415a9e0ae055656a808 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 31 Jul 2019 19:02:14 +0200 Subject: [PATCH 05/19] Update / fix JS and template following evolution of the API --- src/js/yunohost/controllers/diagnosis.js | 86 ++++++++++++------------ src/views/diagnosis/diagnosis_show.ms | 35 +++++----- 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index 51492f46..6c583daf 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -11,50 +11,50 @@ app.get('#/diagnosis', function (c) { // Why this method ? - c.api('/diagnosis/show', function(data) { - for (var i = 0 ; i < data.reports.length ; i++) - { - // Convert timestamp to datetime - data.reports[i].time = new Date(data.reports[i].timestamp*1000); - for (var j = 0 ; j < data.reports[i].reports.length ; j++) - { - var type_ = data.reports[i].reports[j].report[0]; - type_ = type_.toLowerCase(); - var icon = ""; - var issue = false; + c.api('/diagnosis/show?full', function(data) { + for (var i = 0 ; i < data.reports.length ; i++) + { + // Convert timestamp to datetime + data.reports[i].time = new Date(data.reports[i].timestamp*1000); + for (var j = 0 ; j < data.reports[i].items.length ; j++) + { + var type_ = data.reports[i].items[j].status; + type_ = type_.toLowerCase(); + var icon = ""; + var issue = false; - if (type_ == "success") { - icon = "check-circle"; - } - else if (type_ == "warning") { - icon = "warning"; - issue = true; - } - else if (type_ == "error") { - type_ = "danger"; - icon = "times"; - issue = true; - } - data.reports[i].reports[j].report[0] = type_; - data.reports[i].reports[j].icon = icon; - data.reports[i].reports[j].issue = issue; - }; - }; - c.view('diagnosis/diagnosis_show', data, function() { - $(".rerun-diagnosis").click(function() { - var category = $(this).attr("category"); - c.api('/diagnosis/run?force', function(data) { - // This is a copy-pasta of some of the - // redirect/refresh code of sammy.js - // because for some reason calling the function did not work >.> - var to = "#/diagnosis"; - c.trigger('redirect', {to: to}); - c.app.last_location = c.path; - c.app.setLocation(to); - c.app.trigger('location-changed'); - }, 'POST', {"categories": [category]}); - }); - }); + if (type_ == "success") { + icon = "check-circle"; + } + else if (type_ == "warning") { + icon = "warning"; + issue = true; + } + else if (type_ == "error") { + type_ = "danger"; + icon = "times"; + issue = true; + } + data.reports[i].items[j].status = type_; + data.reports[i].items[j].icon = icon; + data.reports[i].items[j].issue = issue; + }; + }; + c.view('diagnosis/diagnosis_show', data, function() { + $(".rerun-diagnosis").click(function() { + var category = $(this).attr("category"); + c.api('/diagnosis/run?force', function(data) { + // This is a copy-pasta of some of the + // redirect/refresh code of sammy.js + // because for some reason calling the function did not work >.> + var to = "#/diagnosis"; + c.trigger('redirect', {to: to}); + c.app.last_location = c.path; + c.app.setLocation(to); + c.app.trigger('location-changed'); + }, 'POST', {"categories": [category]}); + }); + }); }, 'GET'); }); diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index d4df400f..7a99bb02 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -9,25 +9,26 @@
    -
      -

      Last time ran : {{formatRelative time}}

      - {{#reports}} -
    • - {{#if icon}} - - {{/if}} - {{report.[1]}} - {{#if issue}} - {{t 'ignore'}} - {{t 'details'}} - {{/if}} - -
    • - {{/reports}} -
    +
      +

      Last time ran : {{formatRelative time}}

      + {{#items}} +
    • + {{#if icon}} + + {{/if}} + {{summary}} + {{#if issue}} + {{t 'ignore'}} + {{/if}} + {{#if details}} + {{t 'details'}} + {{/if}} +
    • + {{/items}} +
    {{/reports}} From 473a64f33c0ab51a5fa3c0fd5787921f2a8b0588 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 31 Jul 2019 19:36:21 +0200 Subject: [PATCH 06/19] Implement button 'details' to show/hide details --- src/views/diagnosis/diagnosis_show.ms | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index 7a99bb02..6641006d 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -24,7 +24,12 @@ {{t 'ignore'}} {{/if}} {{#if details}} - {{t 'details'}} + +
    +
      + {{#details}}
    • {{.}}
    • {{/details}} +
    +
    {{/if}} {{/items}} From 142facec09cccced808d00c28977e65f65392274 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 1 Aug 2019 15:10:36 +0200 Subject: [PATCH 07/19] Add a badge summarizing number of issues per category --- src/js/yunohost/controllers/diagnosis.js | 5 +++++ src/views/diagnosis/diagnosis_show.ms | 7 +++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index 6c583daf..94203674 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -16,6 +16,8 @@ { // Convert timestamp to datetime data.reports[i].time = new Date(data.reports[i].timestamp*1000); + data.reports[i].warnings = 0; + data.reports[i].errors = 0; for (var j = 0 ; j < data.reports[i].items.length ; j++) { var type_ = data.reports[i].items[j].status; @@ -29,16 +31,19 @@ else if (type_ == "warning") { icon = "warning"; issue = true; + data.reports[i].warnings++; } else if (type_ == "error") { type_ = "danger"; icon = "times"; issue = true; + data.reports[i].errors++; } data.reports[i].items[j].status = type_; data.reports[i].items[j].icon = icon; data.reports[i].items[j].issue = issue; }; + data.reports[i].noIssues = data.reports[i].warnings + data.reports[i].errors ? false : true; }; c.view('diagnosis/diagnosis_show', data, function() { $(".rerun-diagnosis").click(function() { diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index 6641006d..e5c40f91 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -8,8 +8,11 @@ {{#reports}}
    -

    {{ description }}

    - {{t 'rerun_diagnosis'}} +

    {{ description }}

    + {{#if noIssues}}Everything good!{{/if}} + {{#if errors}}{{ errors }} errors{{/if}} + {{#if warnings}}{{ warnings }} warnings{{/if}} + {{t 'rerun_diagnosis'}}
      From 54d26ea6a001fb26f75183f91f7bd925a1bf24a5 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 1 Aug 2019 15:27:57 +0200 Subject: [PATCH 08/19] Add collapsability + collapse blocks with no issues by default --- src/views/diagnosis/diagnosis_show.ms | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index e5c40f91..cc9663df 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -8,13 +8,15 @@ {{#reports}}
      -

      {{ description }}

      +

      + {{ description }} +

      {{#if noIssues}}Everything good!{{/if}} {{#if errors}}{{ errors }} errors{{/if}} {{#if warnings}}{{ warnings }} warnings{{/if}} {{t 'rerun_diagnosis'}}
      -
      +

        Last time ran : {{formatRelative time}}

        {{#items}} From a2b7adb64ceceb83bcadd3d52dc9da145e8bacb3 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 1 Aug 2019 17:09:56 +0200 Subject: [PATCH 09/19] Fix hackish button stuff + responsiveness --- src/css/style.less | 18 ++++++++++++++++++ src/views/diagnosis/diagnosis_show.ms | 6 +++--- src/views/tools/tools_migrations.ms | 4 ++-- src/views/update/update.ms | 4 ++-- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/css/style.less b/src/css/style.less index a665a1db..e2d846d8 100644 --- a/src/css/style.less +++ b/src/css/style.less @@ -811,6 +811,24 @@ input[type='radio'].nice-radio { } } +/* Inline button in panel headers or in list group items */ + +.list-group-item > .btn.pull-right { + line-height: 1em; + margin-top: -2px; +} + +@media screen and (max-width: @screen-xs-min) { + .btn.pull-right, .btn-toolbar.pull-right, .btn-toolbar.pull-right > .btn { + margin: 0; + margin-top: 5px; + display: block; + float: none !important; + } +} + + + /* Just to be able to override list-group-item with alert-success's background and border colors */ .alert-success-yo { background-color: #dff0d8; diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index cc9663df..07d64cef 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -17,7 +17,7 @@ {{t 'rerun_diagnosis'}}
      -
        +

          Last time ran : {{formatRelative time}}

          {{#items}}
        • @@ -26,10 +26,10 @@ {{/if}} {{summary}} {{#if issue}} - {{t 'ignore'}} + {{t 'ignore'}} {{/if}} {{#if details}} - +
            {{#details}}
          • {{.}}
          • {{/details}} diff --git a/src/views/tools/tools_migrations.ms b/src/views/tools/tools_migrations.ms index 8a2b678e..9f9a5296 100644 --- a/src/views/tools/tools_migrations.ms +++ b/src/views/tools/tools_migrations.ms @@ -11,8 +11,8 @@

            {{t 'migrations_pending'}} {{#if pending_migrations}} {{/if}}

            diff --git a/src/views/update/update.ms b/src/views/update/update.ms index 62a44b50..2c0aada1 100644 --- a/src/views/update/update.ms +++ b/src/views/update/update.ms @@ -37,9 +37,9 @@
            {{#apps}}
            - {{t 'system_upgrade_btn'}}

            {{label}} {{id}}

            -

            {{t 'from_to' current_version new_version}}

            + {{t 'from_to' current_version new_version}} + {{t 'system_upgrade_btn'}}
            {{/apps}}
            From c283b50186ac01304154336d7cfb8bd52496e9ca Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 1 Aug 2019 19:22:42 +0200 Subject: [PATCH 10/19] Add a button to share the diagnosis results --- src/views/diagnosis/diagnosis_show.ms | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index 07d64cef..aa5b6081 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -3,6 +3,12 @@ {{t 'diagnosis'}}
          + +
          {{#reports}} From 0e80393ef49179aeaf40814bb0781d5259489796 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 1 Aug 2019 19:36:03 +0200 Subject: [PATCH 11/19] i18n stuff --- src/locales/en.json | 4 ++++ src/views/diagnosis/diagnosis_show.ms | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 42519ccf..11accfb9 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -141,6 +141,7 @@ "download": "Download", "enable": "Enable", "enabled": "Enabled", + "errors": "%s errors", "error_modify_something": "You should modify something", "error_occured": "An error occurred, try again", "error_retrieve_feed": "Could not retrieve feed: %s. You might have a plugin prevent your browser from performing this request (or the website is down).", @@ -149,6 +150,7 @@ "error_server_unexpected": "Unexpected server error (%s)", "error_connection_interrupted": "The server closed the connection instead of answering it, has nginx been restarted by error? (Error code/message: %s)", "everyone_has_access": "Everyone has access.", + "everything_good": "Everything good!", "experimental_warning": "Warning: this feature is experimental and not consider stable, you shouldn't be using it except if you know what you are doing.", "filesystem": "Filesystem", "firewall": "Firewall", @@ -195,6 +197,7 @@ "ipv6": "IPv6", "label": "Label", "label_for_manifestname": "Label for %s", + "last_ran": "Last time ran:", "level": "level", "license": "License", "loading": "Loading …", @@ -390,6 +393,7 @@ "versions": "Versions", "version": "Version", "view_user_profile": "View %s's profile", + "warnings": "%s warnings", "warning_first_user": "You probably need to create a user first.", "write": "Write", "wrong_password": "Wrong password", diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index aa5b6081..8cb707b2 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -17,14 +17,14 @@

          {{ description }}

          - {{#if noIssues}}Everything good!{{/if}} - {{#if errors}}{{ errors }} errors{{/if}} - {{#if warnings}}{{ warnings }} warnings{{/if}} + {{#if noIssues}}{{t 'everything_good'}}{{/if}} + {{#if errors}}{{t 'errors' errors }}{{/if}} + {{#if warnings}}{{t 'warnings' warnings }}{{/if}} {{t 'rerun_diagnosis'}}
        -

        Last time ran : {{formatRelative time}}

        +

        {{t 'last_ran' }} {{formatRelative time day="numeric" month="long" year="numeric" hour="numeric" minute="numeric" }}

        {{#items}}
      • {{#if icon}} From c73f9cea1d6f304fd222cfb669cf89cd2d875f0f Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 13 Oct 2019 18:47:10 +0200 Subject: [PATCH 12/19] Handle ignored stuff display + add unignore button --- src/css/style.less | 6 ++++++ src/js/yunohost/controllers/diagnosis.js | 10 ++++++++++ src/locales/en.json | 2 ++ src/views/diagnosis/diagnosis_show.ms | 9 +++++++-- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/css/style.less b/src/css/style.less index e2d846d8..520d2ee5 100644 --- a/src/css/style.less +++ b/src/css/style.less @@ -849,3 +849,9 @@ input[type='radio'].nice-radio { background-color: #d9edf7; border-color: #bce8f1; } + +.alert-ignored-yo { + background-color: ghostwhite; + border-color: lightgrey; + color: grey; +} diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index 94203674..adecaa97 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -18,16 +18,26 @@ data.reports[i].time = new Date(data.reports[i].timestamp*1000); data.reports[i].warnings = 0; data.reports[i].errors = 0; + data.reports[i].ignored = 0; for (var j = 0 ; j < data.reports[i].items.length ; j++) { var type_ = data.reports[i].items[j].status; type_ = type_.toLowerCase(); + var ignored = data.reports[i].items[j].ignored; var icon = ""; var issue = false; if (type_ == "success") { icon = "check-circle"; } + else if (ignored == true) { + icon = type_; + if (type_ == "error") { + icon = "times" + } + type_ = "ignored"; + data.reports[i].ignored++; + } else if (type_ == "warning") { icon = "warning"; issue = true; diff --git a/src/locales/en.json b/src/locales/en.json index 11accfb9..7f4d3fbb 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -181,6 +181,7 @@ "hostname": "Hostname", "id": "ID", "ignore": "Ignore", + "ignored": "%s ignored", "inactive": "Inactive", "infos": "Info", "install": "Install", @@ -362,6 +363,7 @@ "transmission": "Transmission", "udp": "UDP", "unauthorized": "Unauthorized", + "unignore": "Unignore", "uninstall": "Uninstall", "unknown_action": "Unknown action %s", "unknown_argument": "Unknown argument: %s", diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index 8cb707b2..aece8b5c 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -20,9 +20,10 @@ {{#if noIssues}}{{t 'everything_good'}}{{/if}} {{#if errors}}{{t 'errors' errors }}{{/if}} {{#if warnings}}{{t 'warnings' warnings }}{{/if}} + {{#if ignored}}{{t 'ignored' ignored }}{{/if}} {{t 'rerun_diagnosis'}}
      -
      +

        {{t 'last_ran' }} {{formatRelative time day="numeric" month="long" year="numeric" hour="numeric" minute="numeric" }}

        {{#items}} @@ -31,8 +32,12 @@ {{/if}} {{summary}} + {{#if ignored}} + {{t 'unignore'}} + {{else}} {{#if issue}} - {{t 'ignore'}} + {{t 'ignore'}} + {{/if}} {{/if}} {{#if details}} From 08adb4f9f38eabb3b262904ad7f2706930294e56 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Sun, 13 Oct 2019 23:01:56 +0200 Subject: [PATCH 13/19] Implement ignore/unignore buttons --- src/js/yunohost/controllers/diagnosis.js | 38 +++++++++++++++++------- src/js/yunohost/helpers.js | 12 ++++++++ src/views/diagnosis/diagnosis_show.ms | 4 +-- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index adecaa97..1521fe03 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -7,10 +7,8 @@ // Diagnosis // ********* - // Server monitoring app.get('#/diagnosis', function (c) { - // Why this method ? c.api('/diagnosis/show?full', function(data) { for (var i = 0 ; i < data.reports.length ; i++) { @@ -52,6 +50,12 @@ data.reports[i].items[j].status = type_; data.reports[i].items[j].icon = icon; data.reports[i].items[j].issue = issue; + // We want filter_args to be something like "dnsrecords,domain=yolo.test,category=xmpp" + data.reports[i].items[j].filter_args = data.reports[i].id; + for (prop in data.reports[i].items[j].meta) { + console.log(prop) + data.reports[i].items[j].filter_args = data.reports[i].items[j].filter_args + ","+prop+"="+data.reports[i].items[j].meta[prop]; + } }; data.reports[i].noIssues = data.reports[i].warnings + data.reports[i].errors ? false : true; }; @@ -59,14 +63,7 @@ $(".rerun-diagnosis").click(function() { var category = $(this).attr("category"); c.api('/diagnosis/run?force', function(data) { - // This is a copy-pasta of some of the - // redirect/refresh code of sammy.js - // because for some reason calling the function did not work >.> - var to = "#/diagnosis"; - c.trigger('redirect', {to: to}); - c.app.last_location = c.path; - c.app.setLocation(to); - c.app.trigger('location-changed'); + c.force_redirect("#/diagnosis"); }, 'POST', {"categories": [category]}); }); }); @@ -74,4 +71,25 @@ }); + diagnosis_add_ignore_filter = function(filter_args) { + c.api('/diagnosis/ignore', function(data) { + store.clear('slide'); + c.force_redirect("#/diagnosis"); + }, + 'POST', + {'add_filter': filter_args.split(',') } + ); + }; + + diagnosis_remove_ignore_filter = function(filter_args) { + c.api('/diagnosis/ignore', function(data) { + store.clear('slide'); + c.force_redirect("#/diagnosis"); + }, + 'POST', + {'remove_filter': filter_args.split(',') } + ); + }; + + })(); diff --git a/src/js/yunohost/helpers.js b/src/js/yunohost/helpers.js index d572807a..89dd28c0 100644 --- a/src/js/yunohost/helpers.js +++ b/src/js/yunohost/helpers.js @@ -480,6 +480,18 @@ $('div.loader').remove(); }); }); + }, + + force_redirect: function(to) { + c = this; + // This is a copy-pasta of some of the redirect/refresh code of + // sammy.js because for some reason calling the origina + // redirect/refresh function in some context does not work >.> + // (e.g. if you're already on the page) + c.trigger('redirect', {to: to}); + c.app.last_location = c.path; + c.app.setLocation(to); + c.app.trigger('location-changed'); } }); diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index aece8b5c..c34f75e5 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -33,10 +33,10 @@ {{/if}} {{summary}} {{#if ignored}} - {{t 'unignore'}} + {{t 'unignore'}} {{else}} {{#if issue}} - {{t 'ignore'}} + {{t 'ignore'}} {{/if}} {{/if}} {{#if details}} From 3e29dbb9c3eadeaaf71b468274a91b72ed4470ff Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 6 Nov 2019 21:50:08 +0100 Subject: [PATCH 14/19] Use buttons instead of clumsy links --- src/js/yunohost/controllers/diagnosis.js | 148 +++++++++++------------ src/views/diagnosis/diagnosis_show.ms | 6 +- 2 files changed, 76 insertions(+), 78 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index 1521fe03..d08cf03f 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -8,88 +8,86 @@ // ********* app.get('#/diagnosis', function (c) { + c.api('GET', '/diagnosis/show?full', {}, function(data) { - c.api('/diagnosis/show?full', function(data) { - for (var i = 0 ; i < data.reports.length ; i++) - { - // Convert timestamp to datetime - data.reports[i].time = new Date(data.reports[i].timestamp*1000); - data.reports[i].warnings = 0; - data.reports[i].errors = 0; - data.reports[i].ignored = 0; - for (var j = 0 ; j < data.reports[i].items.length ; j++) + // Prepare data to be displayed ... + for (var i = 0 ; i < data.reports.length ; i++) { - var type_ = data.reports[i].items[j].status; - type_ = type_.toLowerCase(); - var ignored = data.reports[i].items[j].ignored; - var icon = ""; - var issue = false; + // Convert timestamp to datetime + data.reports[i].time = new Date(data.reports[i].timestamp*1000); + data.reports[i].warnings = 0; + data.reports[i].errors = 0; + data.reports[i].ignored = 0; + for (var j = 0 ; j < data.reports[i].items.length ; j++) + { + var type_ = data.reports[i].items[j].status; + type_ = type_.toLowerCase(); + var ignored = data.reports[i].items[j].ignored; + var icon = ""; + var issue = false; - if (type_ == "success") { - icon = "check-circle"; - } - else if (ignored == true) { - icon = type_; - if (type_ == "error") { - icon = "times" + if (type_ == "success") { + icon = "check-circle"; } - type_ = "ignored"; - data.reports[i].ignored++; - } - else if (type_ == "warning") { - icon = "warning"; - issue = true; - data.reports[i].warnings++; - } - else if (type_ == "error") { - type_ = "danger"; - icon = "times"; - issue = true; - data.reports[i].errors++; - } - data.reports[i].items[j].status = type_; - data.reports[i].items[j].icon = icon; - data.reports[i].items[j].issue = issue; - // We want filter_args to be something like "dnsrecords,domain=yolo.test,category=xmpp" - data.reports[i].items[j].filter_args = data.reports[i].id; - for (prop in data.reports[i].items[j].meta) { - console.log(prop) - data.reports[i].items[j].filter_args = data.reports[i].items[j].filter_args + ","+prop+"="+data.reports[i].items[j].meta[prop]; - } + else if (ignored == true) { + icon = type_; + if (type_ == "error") { + icon = "times" + } + type_ = "ignored"; + data.reports[i].ignored++; + } + else if (type_ == "warning") { + icon = "warning"; + issue = true; + data.reports[i].warnings++; + } + else if (type_ == "error") { + type_ = "danger"; + icon = "times"; + issue = true; + data.reports[i].errors++; + } + data.reports[i].items[j].status = type_; + data.reports[i].items[j].icon = icon; + data.reports[i].items[j].issue = issue; + // We want filter_args to be something like "dnsrecords,domain=yolo.test,category=xmpp" + data.reports[i].items[j].filter_args = data.reports[i].id; + for (prop in data.reports[i].items[j].meta) { + console.log(prop) + data.reports[i].items[j].filter_args = data.reports[i].items[j].filter_args + ","+prop+"="+data.reports[i].items[j].meta[prop]; + } + }; + data.reports[i].noIssues = data.reports[i].warnings + data.reports[i].errors ? false : true; }; - data.reports[i].noIssues = data.reports[i].warnings + data.reports[i].errors ? false : true; - }; - c.view('diagnosis/diagnosis_show', data, function() { - $(".rerun-diagnosis").click(function() { - var category = $(this).attr("category"); - c.api('/diagnosis/run?force', function(data) { - c.force_redirect("#/diagnosis"); - }, 'POST', {"categories": [category]}); + + // Render and display the view + c.view('diagnosis/diagnosis_show', data, function() { + + // Configure 'rerun diagnosis' button behavior + $("button[data-action='rerun-diagnosis']").click(function() { + var category = $(this).data("category"); + c.api('POST', '/diagnosis/run?force', {"categories": [category]}, function(data) { + c.refresh(); + }); + }); + + // Configure 'ignore' / 'unignore' buttons behavior + $("button[data-action='ignore']").click(function() { + var filter_args = $(this).data("filter-args"); + c.api('POST', '/diagnosis/ignore', {'add_filter': filter_args.split(',') }, function(data) { + c.refresh(); + }) + }); + + $("button[data-action='unignore']").click(function() { + var filter_args = $(this).data("filter-args"); + c.api('POST', '/diagnosis/ignore', {'remove_filter': filter_args.split(',') }, function(data) { + c.refresh(); + }) + }); }); }); - }, 'GET'); - }); - diagnosis_add_ignore_filter = function(filter_args) { - c.api('/diagnosis/ignore', function(data) { - store.clear('slide'); - c.force_redirect("#/diagnosis"); - }, - 'POST', - {'add_filter': filter_args.split(',') } - ); - }; - - diagnosis_remove_ignore_filter = function(filter_args) { - c.api('/diagnosis/ignore', function(data) { - store.clear('slide'); - c.force_redirect("#/diagnosis"); - }, - 'POST', - {'remove_filter': filter_args.split(',') } - ); - }; - - })(); diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index c34f75e5..f48ea67e 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -21,7 +21,7 @@ {{#if errors}}{{t 'errors' errors }}{{/if}} {{#if warnings}}{{t 'warnings' warnings }}{{/if}} {{#if ignored}}{{t 'ignored' ignored }}{{/if}} - {{t 'rerun_diagnosis'}} +
        @@ -33,10 +33,10 @@ {{/if}} {{summary}} {{#if ignored}} - {{t 'unignore'}} + {{else}} {{#if issue}} - {{t 'ignore'}} + {{/if}} {{/if}} {{#if details}} From 426b9df9b1c579687b52c3546ac68165793c9120 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 6 Nov 2019 22:02:31 +0100 Subject: [PATCH 15/19] Rounded labels are nice bruh :[ --- src/css/style.less | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/css/style.less b/src/css/style.less index ac55e857..3c8322c2 100644 --- a/src/css/style.less +++ b/src/css/style.less @@ -101,10 +101,6 @@ button { color: transparent; } -.label { - border-radius: 1px; -} - /* * The top heading of the doc * From b84d94861125f9f8d25eef5659f7f8d26db5370e Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 6 Nov 2019 22:11:34 +0100 Subject: [PATCH 16/19] Button for the 'share with yunopaste' thing --- src/js/yunohost/controllers/diagnosis.js | 8 ++++++++ src/views/diagnosis/diagnosis_show.ms | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index d08cf03f..807e2cb9 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -64,6 +64,14 @@ // Render and display the view c.view('diagnosis/diagnosis_show', data, function() { + // Configure share with yunopaste button + $("button[data-action='share']").click(function() { + c.api('GET', '/diagnosis/show?share', {}, function(data) { + c.hideLoader(); + window.open(data.url, '_blank'); + }); + }); + // Configure 'rerun diagnosis' button behavior $("button[data-action='rerun-diagnosis']").click(function() { var category = $(this).data("category"); diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index f48ea67e..4a904b48 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -4,9 +4,9 @@
      From 3c9c3fc9261827900aac2cfe3f28fba04d0a8fb6 Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 6 Nov 2019 22:19:07 +0100 Subject: [PATCH 17/19] Remove the old legacy diagnosis thing --- src/js/yunohost/controllers/tools.js | 15 --------------- src/locales/en.json | 7 ------- src/views/tools/tools_diagnosis.ms | 25 ------------------------- src/views/tools/tools_list.ms | 4 ---- 4 files changed, 51 deletions(-) delete mode 100644 src/views/tools/tools_diagnosis.ms diff --git a/src/js/yunohost/controllers/tools.js b/src/js/yunohost/controllers/tools.js index 4e62c693..c8d9acaa 100644 --- a/src/js/yunohost/controllers/tools.js +++ b/src/js/yunohost/controllers/tools.js @@ -251,21 +251,6 @@ }); }); - // Diagnosis - app.get('#/tools/diagnosis(/:private)?', function (c) { - // See http://sammyjs.org/docs/routes for splat documentation - var private = (c.params.splat[0] == 'private'); - - var endurl = (private) ? '?private' : ''; - c.api('GET', '/diagnosis'+endurl, {}, function(diagnosis) { - c.view('tools/tools_diagnosis', { - 'diagnosis' : JSON.stringify(diagnosis, undefined, 4), - 'raw' : diagnosis, - 'private' : private - }); - }); - }); - // Migrations app.get('#/tools/migrations', function (c) { c.api('GET', '/migrations?pending', {}, function(pending_migrations) { diff --git a/src/locales/en.json b/src/locales/en.json index a585514e..5469611f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -91,9 +91,6 @@ "details": "Details", "domain_dns_conf_is_just_a_recommendation": "This page shows you the *recommended* configuration. It does *not* configure the DNS for you. It is your responsability to configure your DNS zone in your DNS registrar according to this recommendation.", "diagnosis": "Diagnosis", - "diagnosis_hide_private": "Show diagnostic information without private data", - "diagnosis_view_private": "Show diagnostic information including private data", - "diagnosis_with_private": "Diagnosis with private data", "disable": "Disable", "disabled": "Disabled", "dns": "DNS", @@ -230,10 +227,6 @@ "passwords_dont_match": "Passwords don't match", "passwords_too_short": "Password is too short", "path": "Path", - "diagnosis": "Diagnosis", - "diagnosis_with_private": "Diagnosis with private data", - "diagnosis_view_private": "Show diagnosis with private data", - "diagnosis_hide_private": "Show diagnosis without private data", "logs": "Logs", "logs_operation": "Operations made on system with YunoHost", "logs_history": "History of command run on system", diff --git a/src/views/tools/tools_diagnosis.ms b/src/views/tools/tools_diagnosis.ms deleted file mode 100644 index ab94de03..00000000 --- a/src/views/tools/tools_diagnosis.ms +++ /dev/null @@ -1,25 +0,0 @@ - - -
      - -
      -
      -

      {{t 'diagnosis'}}

      -
      -
      -
      {{ diagnosis }}
      - {{#if private}} - {{t 'diagnosis_hide_private'}} - {{else}} - {{t 'diagnosis_view_private'}} - {{/if}} - -
      -
      diff --git a/src/views/tools/tools_list.ms b/src/views/tools/tools_list.ms index 91923dd3..b35411a0 100644 --- a/src/views/tools/tools_list.ms +++ b/src/views/tools/tools_list.ms @@ -6,10 +6,6 @@
      - - -

      {{t 'diagnosis'}}

      -

      {{t 'logs'}}

      From e39d00956bdb69c39e6236735a1ddb1ca6d8976d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Wed, 6 Nov 2019 23:47:23 +0100 Subject: [PATCH 18/19] Use the new diagnosis system to display the version number --- src/js/yunohost/controllers/diagnosis.js | 1 - src/js/yunohost/events.js | 11 ++++------- src/js/yunohost/main.js | 7 ++++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/js/yunohost/controllers/diagnosis.js b/src/js/yunohost/controllers/diagnosis.js index 807e2cb9..6fb48f7b 100644 --- a/src/js/yunohost/controllers/diagnosis.js +++ b/src/js/yunohost/controllers/diagnosis.js @@ -54,7 +54,6 @@ // We want filter_args to be something like "dnsrecords,domain=yolo.test,category=xmpp" data.reports[i].items[j].filter_args = data.reports[i].id; for (prop in data.reports[i].items[j].meta) { - console.log(prop) data.reports[i].items[j].filter_args = data.reports[i].items[j].filter_args + ","+prop+"="+data.reports[i].items[j].meta[prop]; } }; diff --git a/src/js/yunohost/events.js b/src/js/yunohost/events.js index 5cfb10c4..a6cde272 100644 --- a/src/js/yunohost/events.js +++ b/src/js/yunohost/events.js @@ -69,13 +69,10 @@ c.flash('fail', y18n.t('error_retrieve_feed', [securityFeed])); }); - c.api("GET", "/diagnosis", {}, function(data) { - versions = data.packages; - $('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost.version, versions.yunohost.repo])); - if (data.security["CVE-2017-5754"].vulnerable) { - c.flash('danger', y18n.t('meltdown')); - } - c.hideLoader(); + c.api("GET", "/diagnosis/show?full", {}, function(data) { + basesystem = data.reports.filter(function(r) { return r.id == "basesystem"; })[0]; + version_info = basesystem.items.filter(function(i) { return (i.meta && i.meta.test && i.meta.test == "ynh_versions"); })[0]; + $('#yunohost-version').html(y18n.t('footer_version', [version_info.data.main_version, version_info.data.repo])); }); }); }); diff --git a/src/js/yunohost/main.js b/src/js/yunohost/main.js index 5219715b..72615a31 100644 --- a/src/js/yunohost/main.js +++ b/src/js/yunohost/main.js @@ -181,9 +181,10 @@ sam.store.set('url', window.location.hostname + '/yunohost/api'); if (sam.store.get('connected')) { - this.api('GET', '/diagnosis', {}, function(diagnosis) { - versions = diagnosis.packages; - $('#yunohost-version').html(y18n.t('footer_version', [versions.yunohost.version, versions.yunohost.repo])); + this.api('GET', '/diagnosis/show?full', {}, function(data) { + basesystem = data.reports.filter(function(r) { return r.id == "basesystem"; })[0]; + version_info = basesystem.items.filter(function(i) { return (i.meta && i.meta.test && i.meta.test == "ynh_versions"); })[0]; + $('#yunohost-version').html(y18n.t('footer_version', [version_info.data.main_version, version_info.data.repo])); }); } From baad22b35af6ad68777a38148675e8ff73599c1d Mon Sep 17 00:00:00 2001 From: Alexandre Aubin Date: Thu, 7 Nov 2019 00:06:32 +0100 Subject: [PATCH 19/19] Add experimental disclaimer on top of diagnosis report for now --- src/locales/en.json | 1 + src/views/diagnosis/diagnosis_show.ms | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/locales/en.json b/src/locales/en.json index 5469611f..a46d196e 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -91,6 +91,7 @@ "details": "Details", "domain_dns_conf_is_just_a_recommendation": "This page shows you the *recommended* configuration. It does *not* configure the DNS for you. It is your responsability to configure your DNS zone in your DNS registrar according to this recommendation.", "diagnosis": "Diagnosis", + "diagnosis_experimental_disclaimer": "Be aware that the diagnosis feature is still experimental and being polished, and it may not be fully reliable.", "disable": "Disable", "disabled": "Disabled", "dns": "DNS", diff --git a/src/views/diagnosis/diagnosis_show.ms b/src/views/diagnosis/diagnosis_show.ms index 4a904b48..820ac417 100644 --- a/src/views/diagnosis/diagnosis_show.ms +++ b/src/views/diagnosis/diagnosis_show.ms @@ -11,6 +11,8 @@
      +
      {{t 'diagnosis_experimental_disclaimer'}}
      + {{#reports}}