UX: Snapshots enhancements

UX: Snapshots enhancements

  • Add a column for SQL count in the snapshots list view
  • Add ‘Best Time’ column in the snapshot groups list
  • Give more exposure to snapshot custom_fields by having a dedicated column for each field in the UI
  • Add config to prevent certain custom_fields from having a column in UI
diff --git a/README.md b/README.md
index d980f4b..ec03248 100644
--- a/README.md
+++ b/README.md
@@ -384,6 +384,7 @@ enable_advanced_debugging_tools|`false`|Enables sensitive debugging tools that c
 assets_url|`nil`|See the "Register MiniProfiler's assets in the Rails assets pipeline" section above.
 snapshot_every_n_requests|`-1`|Determines how frequently snapshots are taken. See the "Snapshots Sampling" above for more details.
 snapshots_limit|`1000`|Determines how many snapshots Mini Profiler is allowed to keep.
+snapshot_hidden_custom_fields|`[]`|Each snapshot custom field will have a dedicated column in the UI by default. Use this config to exclude certain custom fields from having their own columns.
 
 ### Using MiniProfiler with `Rack::Deflate` middleware
 
diff --git a/lib/html/includes.css b/lib/html/includes.css
index 8c3d30e..debc851 100644
--- a/lib/html/includes.css
+++ b/lib/html/includes.css
@@ -439,7 +439,9 @@
     background: #6a737c;
     color: #ffffff; }
   .mp-snapshots .snapshots-table th, .mp-snapshots .snapshots-table td {
-    padding: 5px;
+    padding: 5px 10px;
     box-sizing: border-box; }
+    .mp-snapshots .snapshots-table th:not(.request-group), .mp-snapshots .snapshots-table td:not(.request-group) {
+      text-align: center; }
   .mp-snapshots .snapshots-table th {
     border-right: 1px solid #ffffff; }
diff --git a/lib/html/includes.js b/lib/html/includes.js
index 87bd60c..cf2a0b4 100644
--- a/lib/html/includes.js
+++ b/lib/html/includes.js
@@ -679,7 +679,20 @@ var MiniProfiler = (function() {
     if (data.page === "overview") {
       temp.innerHTML = MiniProfiler.templates.snapshotsGroupsList(data);
     } else if (data.group_name) {
-      temp.innerHTML = MiniProfiler.templates.snapshotsList(data);
+      var allCustomFieldsNames = [];
+      data.list.forEach(function (snapshot) {
+        Object.keys(snapshot.custom_fields).forEach(function (k) {
+          if (allCustomFieldsNames.indexOf(k) === -1 &&
+            options.hiddenCustomFields.indexOf(k.toLowerCase()) === -1) {
+            allCustomFieldsNames.push(k);
+          }
+        });
+      });
+      allCustomFieldsNames.sort();
+      temp.innerHTML = MiniProfiler.templates.snapshotsList({
+        data: data,
+        allCustomFieldsNames: allCustomFieldsNames
+      });
     }
     Array.from(temp.children).forEach(function (child) {
       document.body.appendChild(child);
@@ -994,6 +1007,7 @@ var MiniProfiler = (function() {
           sessionStorage["rack-mini-profiler-start-hidden"] === "true";
         var htmlContainer = script.getAttribute("data-html-container");
         var cssUrl = script.getAttribute("data-css-url");
+        var hiddenCustomFields = script.getAttribute("data-hidden-custom-fields").toLowerCase().split(",");
         return {
           ids: ids,
           path: path,
@@ -1011,7 +1025,8 @@ var MiniProfiler = (function() {
           startHidden: startHidden,
           collapseResults: collapseResults,
           htmlContainer: htmlContainer,
-          cssUrl: cssUrl
+          cssUrl: cssUrl,
+          hiddenCustomFields: hiddenCustomFields
         };
       })();
 
diff --git a/lib/html/includes.scss b/lib/html/includes.scss
index b98ea06..375f341 100644
--- a/lib/html/includes.scss
+++ b/lib/html/includes.scss
@@ -637,8 +637,11 @@ $zindex: 2147483640; // near 32bit max 2147483647
       color: #ffffff;
     }
     th, td {
-      padding: 5px;
+      padding: 5px 10px;
       box-sizing: border-box;
+      &:not(.request-group) {
+        text-align: center;
+      }
     }
     th {
       border-right: 1px solid #ffffff;
diff --git a/lib/html/includes.tmpl b/lib/html/includes.tmpl
index 97d323f..1f1b69c 100644
--- a/lib/html/includes.tmpl
+++ b/lib/html/includes.tmpl
@@ -241,13 +241,17 @@
         <tr>
           <th>Requests Group</th>
           <th>Worst Time (ms)</th>
+          <th>Best Time (ms)</th>
+          <th>No. of Snapshots</th>
         </tr>
       </thead>
       <tbody>
         {{~ it.list :row}}
           <tr>
-            <td><a href="{{= row.url }}">{{= row.name }}</a></td>
+            <td class="request-group"><a href="{{= row.url }}">{{= row.name }}</a></td>
             <td>{{= MiniProfiler.formatDuration(row.worst_score) }}</td>
+            <td>{{= MiniProfiler.formatDuration(row.best_score) }}</td>
+            <td>{{= row.snapshots_count }}</td>
           </tr>
         {{~}}
       </tbody>
@@ -258,23 +262,33 @@
 </script>
 
 <script id="snapshotsList" type="text/x-dot-tmpl">
-  {{? it.list && it.list.length }}
-    <h2>Snapshots for {{= it.group_name }}</h2>
+  {{ var data = it.data; }}
+  {{ var customFieldsNames = it.allCustomFieldsNames; }}
+  {{? data.list && data.list.length }}
+    <h2>Snapshots for {{= data.group_name }}</h2>
     <table class="snapshots-table">
       <thead>
         <tr>
           <th>ID</th>
           <th>Duration (ms)</th>
+          <th>SQL Count</th>
+          {{~ customFieldsNames :name }}
+            <th>{{= name }}</th>
+          {{~}}
           <th>Age</th>
         </tr>
       </thead>
       <tbody>
-        {{~ it.list :row}}
+        {{~ data.list :row}}
           <tr>
             <td><a href="{{= row.url }}">
               {{= row.id }}
             </a></td>
             <td>{{= MiniProfiler.formatDuration(row.duration) }}</td>
+            <td>{{= row.sql_count }}</td>
+            {{~ customFieldsNames :name }}
+              <td>{{= row.custom_fields[name] || "" }}</td>
+            {{~}}
             <td>
               {{? row.timestamp }}
                 {{= MiniProfiler.timestampToRelative(row.timestamp) }}
@@ -285,6 +299,6 @@
       </tbody>
     </table>
   {{??}}
-    <h2>No snapshots for {{= it.group_name }}</h2>
+    <h2>No snapshots for {{= data.group_name }}</h2>
   {{?}}
 </script>
diff --git a/lib/html/profile_handler.js b/lib/html/profile_handler.js
index d147c26..9c6f104 100644
--- a/lib/html/profile_handler.js
+++ b/lib/html/profile_handler.js
@@ -1 +1 @@
-<script async type="text/javascript" id="mini-profiler" src="{url}" data-css-url="{cssUrl}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-horizontal-position="{horizontalPosition}" data-vertical-position="{verticalPosition}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-total-sql-count="{showTotalSqlCount}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}" data-collapse-results="{collapseResults}" data-html-container="{htmlContainer}"></script>
+<script async type="text/javascript" id="mini-profiler" src="{url}" data-css-url="{cssUrl}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-horizontal-position="{horizontalPosition}" data-vertical-position="{verticalPosition}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-total-sql-count="{showTotalSqlCount}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}" data-collapse-results="{collapseResults}" data-html-container="{htmlContainer}" data-hidden-custom-fields="{hiddenCustomFields}"></script>
diff --git a/lib/html/vendor.js b/lib/html/vendor.js
index d79c794..0e2718d 100644
--- a/lib/html/vendor.js
+++ b/lib/html/vendor.js
@@ -27,11 +27,11 @@ var out=' <tr class="profiler-gap-info';if(it.g.duration < 4){out+=' profiler-tr
 }
 MiniProfiler.templates["snapshotsGroupsList"] = function anonymous(it
 ) {

[... diff too long, it was truncated ...]

GitHub sha: 03d3f955

2 Likes