pg_reports 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +19 -1
- data/app/views/layouts/pg_reports/application.html.erb +7 -5
- data/app/views/pg_reports/dashboard/_fake_source_data.html.erb +43 -0
- data/app/views/pg_reports/dashboard/show.html.erb +64 -58
- data/lib/pg_reports/configuration.rb +12 -0
- data/lib/pg_reports/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ebdc855958933d677530a6bee64fe5534e3b13244e4b851ee3cd06b37e1df10b
|
|
4
|
+
data.tar.gz: 1fae6baba2619b57b10ad86ef37678a34b279c49a7cf0f014810f4b167c2ae80
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7b2960a2f1df123331f8cd8d41d258fcd61f45b118451bac7859e890a5fde822266e7ab77e60a5820bf1856548ebf3ec2fff77a3f7938dc8913eca53cb087582
|
|
7
|
+
data.tar.gz: 8bfeeff753903a9a29329221108628ae2119759f859dd01e2c1395a9ae317a956556fb115bfa28b046b859e784ea42fc0b51df7fee56b7a6a6aef1674335a96a
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.2] - 2026-01-28
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `fake_source_data` configuration option - enable via `PG_REPORTS_FAKE_SOURCE_DATA=true` env variable or in initializer
|
|
13
|
+
- Support for short controller#action format in source links (e.g., `posts#index` → `app/controllers/posts_controller.rb`)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Fake source data moved to separate partial file for cleaner code organization
|
|
18
|
+
- IDE link click handling improved with event delegation in capture phase
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Source badge clicks now work correctly without triggering row expansion
|
|
23
|
+
- Fallback fonts now use proper sans-serif system font stack when `load_external_fonts` is disabled
|
|
24
|
+
|
|
25
|
+
## [0.2.1] - 2026-01-28
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- Cursor (WSL) IDE support
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- Removed test data from production code
|
|
34
|
+
- Copy Query button now works correctly with special characters
|
|
35
|
+
|
|
8
36
|
## [0.2.0] - 2026-01-28
|
|
9
37
|
|
|
10
38
|
### Added
|
|
@@ -17,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
17
45
|
- VS Code - direct path for native Linux
|
|
18
46
|
- RubyMine
|
|
19
47
|
- IntelliJ IDEA
|
|
48
|
+
- Cursor (WSL) - for Windows Subsystem for Linux
|
|
20
49
|
- Cursor
|
|
21
50
|
- IDE settings modal to choose default IDE (skip menu and open directly)
|
|
22
51
|
- Save records for comparison - save query results to compare before/after optimizations
|
data/README.md
CHANGED
|
@@ -18,7 +18,7 @@ A comprehensive PostgreSQL monitoring and analysis library for Rails application
|
|
|
18
18
|
- 🌐 **Web Dashboard** - Beautiful dark-themed UI with sortable tables and expandable rows
|
|
19
19
|
- 📨 **Telegram Integration** - Send reports directly to Telegram
|
|
20
20
|
- 📥 **Export** - Download reports in TXT, CSV, or JSON format
|
|
21
|
-
- 🔗 **IDE Integration** - Open source locations in VS Code,
|
|
21
|
+
- 🔗 **IDE Integration** - Open source locations in VS Code, Cursor, RubyMine, or IntelliJ (with WSL support)
|
|
22
22
|
- 📌 **Comparison Mode** - Save records to compare before/after optimization
|
|
23
23
|
- 📊 **EXPLAIN ANALYZE** - Run query plans directly from the dashboard
|
|
24
24
|
- 🗑️ **Migration Generator** - Generate Rails migrations to drop unused indexes
|
|
@@ -116,6 +116,12 @@ PgReports.configure do |config|
|
|
|
116
116
|
end
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
# External fonts (Google Fonts)
|
|
120
|
+
# Default: false (no external requests)
|
|
121
|
+
config.load_external_fonts = ENV["PG_REPORTS_LOAD_EXTERNAL_FONTS"] == "true"
|
|
122
|
+
# or simply:
|
|
123
|
+
# config.load_external_fonts = true
|
|
124
|
+
|
|
119
125
|
end
|
|
120
126
|
```
|
|
121
127
|
|
|
@@ -280,6 +286,7 @@ Click on source locations in reports to open the file directly in your IDE. Supp
|
|
|
280
286
|
- **VS Code** - direct path for native Linux/macOS
|
|
281
287
|
- **RubyMine**
|
|
282
288
|
- **IntelliJ IDEA**
|
|
289
|
+
- **Cursor (WSL)** - for Windows Subsystem for Linux
|
|
283
290
|
- **Cursor**
|
|
284
291
|
|
|
285
292
|
Use the ⚙️ button to set your default IDE and skip the selection menu.
|
|
@@ -332,6 +339,17 @@ PgReports.configure do |config|
|
|
|
332
339
|
end
|
|
333
340
|
```
|
|
334
341
|
|
|
342
|
+
### External Fonts
|
|
343
|
+
|
|
344
|
+
By default, PgReports does **not** load external fonts.
|
|
345
|
+
|
|
346
|
+
```ruby
|
|
347
|
+
PgReports.configure do |config|
|
|
348
|
+
# Enable loading Google Fonts (optional)
|
|
349
|
+
config.load_external_fonts = true
|
|
350
|
+
end
|
|
351
|
+
```
|
|
352
|
+
|
|
335
353
|
## Telegram Integration
|
|
336
354
|
|
|
337
355
|
1. Create a bot via [@BotFather](https://t.me/BotFather)
|
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
<meta name="pg-reports-root" content="<%= request.script_name.presence || PgReports::Engine.routes.url_helpers.root_path %>">
|
|
7
7
|
<title>PgReports Dashboard</title>
|
|
8
8
|
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='6' fill='%234f46e5'/%3E%3Crect x='5' y='18' width='5' height='9' rx='1' fill='%23fff'/%3E%3Crect x='13.5' y='12' width='5' height='15' rx='1' fill='%23fff'/%3E%3Crect x='22' y='6' width='5' height='21' rx='1' fill='%23fff'/%3E%3C/svg%3E">
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
<% if PgReports.config.load_external_fonts %>
|
|
10
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
11
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
12
|
+
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
13
|
+
<% end %>
|
|
12
14
|
<style>
|
|
13
15
|
:root {
|
|
14
16
|
--bg-primary: #0f1114;
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
body {
|
|
39
|
-
font-family: 'Plus Jakarta Sans',
|
|
41
|
+
font-family: <%= PgReports.config.load_external_fonts ? "'Plus Jakarta Sans', " : "" %>-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
|
|
40
42
|
background: var(--bg-primary);
|
|
41
43
|
color: var(--text-primary);
|
|
42
44
|
min-height: 100vh;
|
|
@@ -344,7 +346,7 @@
|
|
|
344
346
|
.results-table {
|
|
345
347
|
width: 100%;
|
|
346
348
|
border-collapse: collapse;
|
|
347
|
-
font-family: 'JetBrains Mono', monospace;
|
|
349
|
+
font-family: <%= PgReports.config.load_external_fonts ? "'JetBrains Mono', " : "" %>SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
348
350
|
font-size: 0.8rem;
|
|
349
351
|
}
|
|
350
352
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<%# Fake source data for IDE link testing - enable via PG_REPORTS_FAKE_SOURCE_DATA=true %>
|
|
2
|
+
<script>
|
|
3
|
+
// Known controller methods with line numbers (for IDE link testing)
|
|
4
|
+
const knownControllerMethods = {
|
|
5
|
+
'PostsController#show': { file: 'app/controllers/posts_controller.rb', line: 33 },
|
|
6
|
+
'PostsController#index': { file: 'app/controllers/posts_controller.rb', line: 19 },
|
|
7
|
+
'PostsController#create': { file: 'app/controllers/posts_controller.rb', line: 43 },
|
|
8
|
+
'PostsController#update': { file: 'app/controllers/posts_controller.rb', line: 62 },
|
|
9
|
+
'PostsController#destroy': { file: 'app/controllers/posts_controller.rb', line: 76 }
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// Fake source values for testing IDE links
|
|
13
|
+
const fakeSourceValues = [
|
|
14
|
+
'PostsController#show',
|
|
15
|
+
'PostsController#index',
|
|
16
|
+
'PostsController#create',
|
|
17
|
+
'PostsController#update',
|
|
18
|
+
'PostsController#destroy',
|
|
19
|
+
'app/controllers/posts_controller.rb:33',
|
|
20
|
+
'app/controllers/posts_controller.rb:19',
|
|
21
|
+
'app/models/post.rb:45:in `find_by_slug`'
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
// Inject fake source values into data for testing
|
|
25
|
+
function injectFakeSourceData(data) {
|
|
26
|
+
if (!data.data || data.data.length === 0) return;
|
|
27
|
+
|
|
28
|
+
// Add 'source' column if not present
|
|
29
|
+
if (!data.columns.includes('source')) {
|
|
30
|
+
data.columns.push('source');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Inject fake source values
|
|
34
|
+
data.data.forEach((row, idx) => {
|
|
35
|
+
if (!row.source || row.source === '' || row.source === null) {
|
|
36
|
+
row.source = fakeSourceValues[idx % fakeSourceValues.length];
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Flag to indicate fake source data is enabled
|
|
42
|
+
window.PG_REPORTS_FAKE_SOURCE_DATA = true;
|
|
43
|
+
</script>
|
|
@@ -74,6 +74,10 @@
|
|
|
74
74
|
<input type="radio" name="default-ide" value="intellij" onchange="setDefaultIde('intellij')">
|
|
75
75
|
<span>IntelliJ IDEA</span>
|
|
76
76
|
</label>
|
|
77
|
+
<label class="ide-option">
|
|
78
|
+
<input type="radio" name="default-ide" value="cursor-wsl" onchange="setDefaultIde('cursor-wsl')">
|
|
79
|
+
<span>Cursor (WSL)</span>
|
|
80
|
+
</label>
|
|
77
81
|
<label class="ide-option">
|
|
78
82
|
<input type="radio" name="default-ide" value="cursor" onchange="setDefaultIde('cursor')">
|
|
79
83
|
<span>Cursor</span>
|
|
@@ -1212,6 +1216,10 @@
|
|
|
1212
1216
|
}
|
|
1213
1217
|
</style>
|
|
1214
1218
|
|
|
1219
|
+
<% if PgReports.config.fake_source_data %>
|
|
1220
|
+
<%= render 'pg_reports/dashboard/fake_source_data' %>
|
|
1221
|
+
<% end %>
|
|
1222
|
+
|
|
1215
1223
|
<script>
|
|
1216
1224
|
let currentReportData = null;
|
|
1217
1225
|
const category = '<%= @category %>';
|
|
@@ -1564,44 +1572,6 @@
|
|
|
1564
1572
|
return '';
|
|
1565
1573
|
}
|
|
1566
1574
|
|
|
1567
|
-
// TEMP: Known controller methods with line numbers (for IDE link testing)
|
|
1568
|
-
const knownControllerMethods = {
|
|
1569
|
-
'PostsController#show': { file: 'app/controllers/posts_controller.rb', line: 33 },
|
|
1570
|
-
'PostsController#index': { file: 'app/controllers/posts_controller.rb', line: 19 },
|
|
1571
|
-
'PostsController#create': { file: 'app/controllers/posts_controller.rb', line: 43 },
|
|
1572
|
-
'PostsController#update': { file: 'app/controllers/posts_controller.rb', line: 62 },
|
|
1573
|
-
'PostsController#destroy': { file: 'app/controllers/posts_controller.rb', line: 76 }
|
|
1574
|
-
};
|
|
1575
|
-
|
|
1576
|
-
// TEMP: Fake source values for testing IDE links
|
|
1577
|
-
const fakeSourceValues = [
|
|
1578
|
-
'PostsController#show',
|
|
1579
|
-
'PostsController#index',
|
|
1580
|
-
'PostsController#create',
|
|
1581
|
-
'PostsController#update',
|
|
1582
|
-
'PostsController#destroy',
|
|
1583
|
-
'app/controllers/posts_controller.rb:33',
|
|
1584
|
-
'app/controllers/posts_controller.rb:19',
|
|
1585
|
-
'app/models/post.rb:45:in `find_by_slug`'
|
|
1586
|
-
];
|
|
1587
|
-
|
|
1588
|
-
// TEMP: Inject fake source values into data for testing
|
|
1589
|
-
function injectFakeSourceData(data) {
|
|
1590
|
-
if (!data.data || data.data.length === 0) return;
|
|
1591
|
-
|
|
1592
|
-
// Add 'source' column if not present
|
|
1593
|
-
if (!data.columns.includes('source')) {
|
|
1594
|
-
data.columns.push('source');
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
// Inject fake source values
|
|
1598
|
-
data.data.forEach((row, idx) => {
|
|
1599
|
-
if (!row.source || row.source === '' || row.source === null) {
|
|
1600
|
-
row.source = fakeSourceValues[idx % fakeSourceValues.length];
|
|
1601
|
-
}
|
|
1602
|
-
});
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
1575
|
// Parse source location and generate IDE link
|
|
1606
1576
|
function parseSourceLocation(source) {
|
|
1607
1577
|
if (!source || source === 'null' || source === '') return null;
|
|
@@ -1623,45 +1593,52 @@
|
|
|
1623
1593
|
lineNumber = parseInt(fileLineMatch[3], 10);
|
|
1624
1594
|
}
|
|
1625
1595
|
|
|
1626
|
-
// Try to match Controller#action pattern
|
|
1596
|
+
// Try to match Controller#action pattern (e.g., PostsController#index)
|
|
1627
1597
|
const controllerMatch = source.match(/^(\w+Controller)#(\w+)/);
|
|
1628
1598
|
if (controllerMatch) {
|
|
1629
1599
|
methodName = `${controllerMatch[1]}#${controllerMatch[2]}`;
|
|
1630
1600
|
|
|
1631
|
-
//
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
lineNumber = knownMethod.line;
|
|
1601
|
+
// Check known methods first for testing (if fake data is enabled)
|
|
1602
|
+
if (typeof knownControllerMethods !== 'undefined' && knownControllerMethods[methodName]) {
|
|
1603
|
+
filePath = knownControllerMethods[methodName].file;
|
|
1604
|
+
lineNumber = knownControllerMethods[methodName].line;
|
|
1636
1605
|
} else {
|
|
1637
|
-
//
|
|
1606
|
+
// Derive file path from controller name
|
|
1638
1607
|
const controllerName = controllerMatch[1].replace(/Controller$/, '').toLowerCase();
|
|
1639
1608
|
filePath = `app/controllers/${controllerName}_controller.rb`;
|
|
1640
1609
|
}
|
|
1641
1610
|
}
|
|
1642
1611
|
|
|
1612
|
+
// Try to match short controller#action pattern (e.g., posts#index, dashboard#show)
|
|
1613
|
+
if (!filePath) {
|
|
1614
|
+
const shortMatch = source.match(/^(\w+)#(\w+)$/);
|
|
1615
|
+
if (shortMatch) {
|
|
1616
|
+
const controllerName = shortMatch[1].toLowerCase();
|
|
1617
|
+
methodName = `${shortMatch[1]}#${shortMatch[2]}`;
|
|
1618
|
+
filePath = `app/controllers/${controllerName}_controller.rb`;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1643
1622
|
return { filePath, lineNumber, methodName, original: source };
|
|
1644
1623
|
}
|
|
1645
1624
|
|
|
1646
|
-
//
|
|
1647
|
-
const
|
|
1625
|
+
// Rails.root path for IDE links
|
|
1626
|
+
const railsRootPath = '<%= Rails.root.to_s %>';
|
|
1627
|
+
const wslDistro = 'Ubuntu';
|
|
1648
1628
|
|
|
1649
1629
|
// Generate IDE URLs
|
|
1650
1630
|
function generateIdeUrls(filePath, lineNumber) {
|
|
1651
1631
|
if (!filePath) return [];
|
|
1652
1632
|
|
|
1653
|
-
//
|
|
1633
|
+
// Convert relative paths to absolute paths using Rails.root
|
|
1654
1634
|
let absolutePath = filePath;
|
|
1655
1635
|
if (!filePath.startsWith('/')) {
|
|
1656
|
-
absolutePath = `${
|
|
1636
|
+
absolutePath = `${railsRootPath}/${filePath}`;
|
|
1657
1637
|
}
|
|
1658
1638
|
|
|
1659
1639
|
const line = lineNumber || 1;
|
|
1660
1640
|
const urls = [];
|
|
1661
1641
|
|
|
1662
|
-
// TEMP: WSL distro name for VS Code Remote
|
|
1663
|
-
const wslDistro = 'Ubuntu';
|
|
1664
|
-
|
|
1665
1642
|
// VSCode (WSL Remote format)
|
|
1666
1643
|
urls.push({
|
|
1667
1644
|
name: 'VS Code (WSL)',
|
|
@@ -1685,7 +1662,13 @@
|
|
|
1685
1662
|
url: `idea://open?file=${absolutePath}&line=${line}`
|
|
1686
1663
|
});
|
|
1687
1664
|
|
|
1688
|
-
// Cursor (
|
|
1665
|
+
// Cursor (WSL Remote format)
|
|
1666
|
+
urls.push({
|
|
1667
|
+
name: 'Cursor (WSL)',
|
|
1668
|
+
url: `cursor://vscode-remote/wsl+${wslDistro}${absolutePath}:${line}`
|
|
1669
|
+
});
|
|
1670
|
+
|
|
1671
|
+
// Cursor (direct path)
|
|
1689
1672
|
urls.push({
|
|
1690
1673
|
name: 'Cursor',
|
|
1691
1674
|
url: `cursor://file${absolutePath}:${line}`
|
|
@@ -1700,7 +1683,8 @@
|
|
|
1700
1683
|
'vscode': 1,
|
|
1701
1684
|
'rubymine': 2,
|
|
1702
1685
|
'intellij': 3,
|
|
1703
|
-
'cursor': 4
|
|
1686
|
+
'cursor-wsl': 4,
|
|
1687
|
+
'cursor': 5
|
|
1704
1688
|
};
|
|
1705
1689
|
|
|
1706
1690
|
// Build source badge HTML with IDE links
|
|
@@ -1731,12 +1715,12 @@
|
|
|
1731
1715
|
|
|
1732
1716
|
let dropdownHtml = `
|
|
1733
1717
|
<div class="ide-dropdown">
|
|
1734
|
-
<span class="source-badge clickable"
|
|
1718
|
+
<span class="source-badge clickable" data-dropdown-id="${dropdownId}" title="${escapeHtml(parsed.original)}">${escapeHtml(parsed.original)}</span>
|
|
1735
1719
|
<div class="ide-dropdown-menu" id="${dropdownId}">
|
|
1736
1720
|
`;
|
|
1737
1721
|
|
|
1738
1722
|
for (const ide of ideUrls) {
|
|
1739
|
-
dropdownHtml += `<a href="${ide.url}"
|
|
1723
|
+
dropdownHtml += `<a href="${ide.url}">${ide.name}</a>`;
|
|
1740
1724
|
}
|
|
1741
1725
|
|
|
1742
1726
|
dropdownHtml += '</div></div>';
|
|
@@ -1763,6 +1747,26 @@
|
|
|
1763
1747
|
}
|
|
1764
1748
|
}
|
|
1765
1749
|
|
|
1750
|
+
// Event delegation for source badge clicks
|
|
1751
|
+
document.addEventListener('click', function(e) {
|
|
1752
|
+
const badge = e.target.closest('.source-badge.clickable[data-dropdown-id]');
|
|
1753
|
+
if (badge) {
|
|
1754
|
+
e.stopPropagation();
|
|
1755
|
+
e.preventDefault();
|
|
1756
|
+
const dropdownId = badge.dataset.dropdownId;
|
|
1757
|
+
toggleIdeDropdown(dropdownId, badge);
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// Allow clicks on IDE dropdown menu links
|
|
1762
|
+
const ideLink = e.target.closest('.ide-dropdown-menu a');
|
|
1763
|
+
if (ideLink) {
|
|
1764
|
+
e.stopPropagation();
|
|
1765
|
+
// Let the link navigate normally
|
|
1766
|
+
return;
|
|
1767
|
+
}
|
|
1768
|
+
}, true); // Use capture phase to intercept before row click
|
|
1769
|
+
|
|
1766
1770
|
function buildDetailRow(row, columns, rowIndex, thresholds, problemFields) {
|
|
1767
1771
|
let html = '<div class="row-detail">';
|
|
1768
1772
|
const hasQuery = columns.includes('query') && row.query;
|
|
@@ -1866,8 +1870,10 @@
|
|
|
1866
1870
|
if (loadingEl) loadingEl.style.display = 'none';
|
|
1867
1871
|
|
|
1868
1872
|
if (data.success) {
|
|
1869
|
-
//
|
|
1870
|
-
injectFakeSourceData
|
|
1873
|
+
// Inject fake source data for IDE link testing (if enabled)
|
|
1874
|
+
if (typeof injectFakeSourceData === 'function') {
|
|
1875
|
+
injectFakeSourceData(data);
|
|
1876
|
+
}
|
|
1871
1877
|
|
|
1872
1878
|
currentReportData = data;
|
|
1873
1879
|
const thresholds = data.thresholds || {};
|
|
@@ -27,6 +27,12 @@ module PgReports
|
|
|
27
27
|
# Dashboard settings
|
|
28
28
|
attr_accessor :dashboard_auth # Proc for dashboard authentication
|
|
29
29
|
|
|
30
|
+
# Assets / privacy settings
|
|
31
|
+
attr_accessor :load_external_fonts # When true, loads Google Fonts in the dashboard layout
|
|
32
|
+
|
|
33
|
+
# Development/testing settings
|
|
34
|
+
attr_accessor :fake_source_data # Inject fake source data for IDE link testing
|
|
35
|
+
|
|
30
36
|
def initialize
|
|
31
37
|
# Telegram
|
|
32
38
|
@telegram_bot_token = ENV.fetch("PG_REPORTS_TELEGRAM_TOKEN", nil)
|
|
@@ -52,6 +58,12 @@ module PgReports
|
|
|
52
58
|
|
|
53
59
|
# Dashboard
|
|
54
60
|
@dashboard_auth = nil
|
|
61
|
+
|
|
62
|
+
# Assets / privacy
|
|
63
|
+
@load_external_fonts = ActiveModel::Type::Boolean.new.cast(ENV.fetch("PG_REPORTS_LOAD_EXTERNAL_FONTS", false))
|
|
64
|
+
|
|
65
|
+
# Development/testing
|
|
66
|
+
@fake_source_data = ENV.fetch("PG_REPORTS_FAKE_SOURCE_DATA", "false") == "true"
|
|
55
67
|
end
|
|
56
68
|
|
|
57
69
|
def connection
|
data/lib/pg_reports/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pg_reports
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eldar Avatov
|
|
@@ -107,6 +107,7 @@ files:
|
|
|
107
107
|
- README.md
|
|
108
108
|
- app/controllers/pg_reports/dashboard_controller.rb
|
|
109
109
|
- app/views/layouts/pg_reports/application.html.erb
|
|
110
|
+
- app/views/pg_reports/dashboard/_fake_source_data.html.erb
|
|
110
111
|
- app/views/pg_reports/dashboard/index.html.erb
|
|
111
112
|
- app/views/pg_reports/dashboard/show.html.erb
|
|
112
113
|
- config/locales/en.yml
|