pg_reports 0.8.2 → 0.9.0
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 +38 -0
- data/app/controllers/pg_reports/dashboard_controller.rb +57 -6
- data/app/views/layouts/pg_reports/application.html.erb +616 -201
- data/app/views/pg_reports/dashboard/_database_selector.html.erb +2 -1
- data/app/views/pg_reports/dashboard/_show_modals.html.erb +10 -7
- data/app/views/pg_reports/dashboard/_show_scripts.html.erb +100 -51
- data/app/views/pg_reports/dashboard/_show_styles.html.erb +392 -476
- data/app/views/pg_reports/dashboard/index.html.erb +190 -388
- data/app/views/pg_reports/dashboard/show.html.erb +13 -11
- data/config/brakeman.ignore +24 -1
- data/config/locales/en.yml +53 -48
- data/config/locales/ru.yml +53 -48
- data/config/locales/uk.yml +53 -48
- data/lib/pg_reports/connection/error_translator.rb +43 -0
- data/lib/pg_reports/dashboard/reports_registry.rb +10 -0
- data/lib/pg_reports/explain_analyzer.rb +0 -3
- data/lib/pg_reports/query_monitor.rb +15 -3
- data/lib/pg_reports/version.rb +1 -1
- metadata +1 -1
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<div class="report-page">
|
|
4
4
|
<nav class="breadcrumb">
|
|
5
|
-
<%= link_to t("pg_reports.ui.navigation.
|
|
6
|
-
|
|
5
|
+
<%= link_to root_path, class: "breadcrumb-back", title: t("pg_reports.ui.navigation.back") do %>
|
|
6
|
+
<svg class="icon" aria-hidden="true"><use href="#i-arrow-left"></use></svg>
|
|
7
|
+
<span><%= t("pg_reports.ui.navigation.dashboard") %></span>
|
|
8
|
+
<% end %>
|
|
9
|
+
<span class="breadcrumb-sep">/</span>
|
|
7
10
|
<span><%= @categories[@category][:name] %></span>
|
|
8
|
-
<span>/</span>
|
|
9
|
-
<span><%= @report_info[:name] %></span>
|
|
11
|
+
<span class="breadcrumb-sep">/</span>
|
|
12
|
+
<span class="breadcrumb-current"><%= @report_info[:name] %></span>
|
|
10
13
|
|
|
11
14
|
<span class="breadcrumb-spacer"></span>
|
|
12
15
|
<%= render "target_selector" %>
|
|
@@ -35,7 +38,7 @@
|
|
|
35
38
|
<a href="#" onclick="downloadReport('json'); return false;"><%= t("pg_reports.ui.actions.download_json") %></a>
|
|
36
39
|
<% if @documentation && @documentation[:ai_prompt].present? %>
|
|
37
40
|
<div class="dropdown-divider"></div>
|
|
38
|
-
<a href="#" id="ai-prompt-btn" onclick="copyAiPrompt(this); return false;"><span class="ai-icon">AI</span
|
|
41
|
+
<a href="#" id="ai-prompt-btn" onclick="copyAiPrompt(this); return false;"><span class="ai-icon">AI</span><%= t("pg_reports.ui.actions.copy_ai_prompt") %></a>
|
|
39
42
|
<% end %>
|
|
40
43
|
</div>
|
|
41
44
|
</div>
|
|
@@ -45,10 +48,9 @@
|
|
|
45
48
|
<%= t("pg_reports.ui.actions.send_telegram") %>
|
|
46
49
|
</button>
|
|
47
50
|
<% end %>
|
|
48
|
-
<button class="btn
|
|
49
|
-
|
|
51
|
+
<button type="button" class="btn-icon" onclick="showIdeSettingsModal()" title="<%= t("pg_reports.ui.actions.ide_settings_button_title") %>" aria-label="<%= t("pg_reports.ui.actions.ide_settings_button_title") %>">
|
|
52
|
+
<svg class="icon icon-lg"><use href="#i-settings"></use></svg>
|
|
50
53
|
</button>
|
|
51
|
-
<%= link_to t("pg_reports.ui.navigation.back"), root_path, class: "btn btn-secondary" %>
|
|
52
54
|
</div>
|
|
53
55
|
</div>
|
|
54
56
|
|
|
@@ -63,7 +65,7 @@
|
|
|
63
65
|
<% if @documentation && @documentation[:what].present? %>
|
|
64
66
|
<details class="documentation-section">
|
|
65
67
|
<summary class="documentation-toggle">
|
|
66
|
-
<
|
|
68
|
+
<svg class="icon toggle-icon" aria-hidden="true"><use href="#i-chevron-right"></use></svg>
|
|
67
69
|
<span><%= t("pg_reports.ui.documentation.toggle_title") %></span>
|
|
68
70
|
</summary>
|
|
69
71
|
<div class="documentation-content">
|
|
@@ -118,7 +120,7 @@
|
|
|
118
120
|
<div class="filter-section">
|
|
119
121
|
<details class="filter-details">
|
|
120
122
|
<summary class="filter-toggle">
|
|
121
|
-
<
|
|
123
|
+
<svg class="icon toggle-icon" aria-hidden="true"><use href="#i-chevron-right"></use></svg>
|
|
122
124
|
<span><%= t("pg_reports.ui.filters.title") %></span>
|
|
123
125
|
</summary>
|
|
124
126
|
<div class="filter-content">
|
|
@@ -176,7 +178,7 @@
|
|
|
176
178
|
</div>
|
|
177
179
|
|
|
178
180
|
<div id="empty-state" class="empty-state" style="display: none;">
|
|
179
|
-
<
|
|
181
|
+
<svg class="icon empty-state-icon" aria-hidden="true"><use href="#i-check"></use></svg>
|
|
180
182
|
<p><%= t("pg_reports.ui.results.empty_message") %></p>
|
|
181
183
|
</div>
|
|
182
184
|
|
data/config/brakeman.ignore
CHANGED
|
@@ -23,6 +23,29 @@
|
|
|
23
23
|
],
|
|
24
24
|
"note": "Reviewed & accepted: user-query execution feature (execute_query count). Gated by config.allow_raw_query_execution; the query is fetched by hash from an internal registry (retrieve_query_by_hash), parameters are validated/substituted, and SecurityError checks reject dangerous input. Not arbitrary attacker-controlled SQL."
|
|
25
25
|
},
|
|
26
|
+
{
|
|
27
|
+
"warning_type": "SQL Injection",
|
|
28
|
+
"warning_code": 0,
|
|
29
|
+
"fingerprint": "52294539b2a9666f9a79f7ad52cdd1dc531a3b71e487e5134174029cd5138571",
|
|
30
|
+
"check_name": "SQL",
|
|
31
|
+
"message": "Possible SQL injection",
|
|
32
|
+
"file": "app/controllers/pg_reports/dashboard_controller.rb",
|
|
33
|
+
"line": 440,
|
|
34
|
+
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
|
35
|
+
"code": "ActiveRecord::Base.connection.execute(\"SELECT COUNT(*) FROM (#{params[:query].to_s}) AS count_query\")",
|
|
36
|
+
"render_path": null,
|
|
37
|
+
"location": {
|
|
38
|
+
"type": "method",
|
|
39
|
+
"class": "PgReports::DashboardController",
|
|
40
|
+
"method": "run_query"
|
|
41
|
+
},
|
|
42
|
+
"user_input": "params[:query]",
|
|
43
|
+
"confidence": "High",
|
|
44
|
+
"cwe_id": [
|
|
45
|
+
89
|
|
46
|
+
],
|
|
47
|
+
"note": "Reviewed & accepted: SQL Console (run_query count). Gated by config.allow_raw_query_execution; the client-typed query passes enforce_select_only! (SELECT-only, no semicolons, keyword denylist) and runs under a bounded statement_timeout. Intentional DBA tooling; same risk profile as execute_query/explain_analyze."
|
|
48
|
+
},
|
|
26
49
|
{
|
|
27
50
|
"warning_type": "Cross-Site Request Forgery",
|
|
28
51
|
"warning_code": 7,
|
|
@@ -69,6 +92,6 @@
|
|
|
69
92
|
"note": "Reviewed & accepted: EXPLAIN ANALYZE feature. Same safeguards as execute_query - query resolved by hash from internal registry, params validated, SecurityError guards. Intentional DBA tooling."
|
|
70
93
|
}
|
|
71
94
|
],
|
|
72
|
-
"updated": "2026-07-
|
|
95
|
+
"updated": "2026-07-10 19:15:00 +0300",
|
|
73
96
|
"brakeman_version": "8.0.5"
|
|
74
97
|
}
|
data/config/locales/en.yml
CHANGED
|
@@ -591,7 +591,7 @@ en:
|
|
|
591
591
|
page_title: "PgReports Dashboard"
|
|
592
592
|
navigation:
|
|
593
593
|
dashboard: "Dashboard"
|
|
594
|
-
back: "
|
|
594
|
+
back: "Back"
|
|
595
595
|
database_selector:
|
|
596
596
|
label: "Database"
|
|
597
597
|
target_selector:
|
|
@@ -599,40 +599,41 @@ en:
|
|
|
599
599
|
actions:
|
|
600
600
|
cancel: "Cancel"
|
|
601
601
|
retry: "Retry"
|
|
602
|
-
copy: "
|
|
603
|
-
copy_query: "
|
|
604
|
-
copy_code: "
|
|
602
|
+
copy: "Copy"
|
|
603
|
+
copy_query: "Copy Query"
|
|
604
|
+
copy_code: "Copy Code"
|
|
605
605
|
copy_to_clipboard_title: "Copy to clipboard"
|
|
606
|
-
copied_feedback: "
|
|
606
|
+
copied_feedback: "Copied!"
|
|
607
607
|
clear_all: "Clear All"
|
|
608
|
-
run_report: "
|
|
609
|
-
export: "
|
|
610
|
-
download_text: "
|
|
611
|
-
download_csv: "
|
|
612
|
-
download_json: "
|
|
613
|
-
download: "
|
|
608
|
+
run_report: "Run Report"
|
|
609
|
+
export: "Export"
|
|
610
|
+
download_text: "Text (.txt)"
|
|
611
|
+
download_csv: "CSV (.csv)"
|
|
612
|
+
download_json: "JSON (.json)"
|
|
613
|
+
download: "Download"
|
|
614
614
|
copy_ai_prompt: "Copy Prompt"
|
|
615
|
-
send_telegram: "
|
|
615
|
+
send_telegram: "Telegram"
|
|
616
616
|
sending: "Sending..."
|
|
617
|
-
reset_statistics: "
|
|
617
|
+
reset_statistics: "Reset Statistics"
|
|
618
618
|
resetting: "Resetting..."
|
|
619
619
|
confirm_reset: "Yes, Reset"
|
|
620
|
-
create_extension: "
|
|
620
|
+
create_extension: "Create Extension"
|
|
621
621
|
creating: "Creating..."
|
|
622
622
|
ide_settings_button_title: "IDE Settings"
|
|
623
|
-
explain_analyze: "
|
|
624
|
-
execute_query: "
|
|
623
|
+
explain_analyze: "EXPLAIN ANALYZE"
|
|
624
|
+
execute_query: "Execute Query"
|
|
625
625
|
run_query: "SQL Console"
|
|
626
|
-
create_migration_file: "
|
|
627
|
-
start_monitoring: "
|
|
628
|
-
stop_monitoring: "
|
|
626
|
+
create_migration_file: "Create File & Open in IDE"
|
|
627
|
+
start_monitoring: "Start Monitoring"
|
|
628
|
+
stop_monitoring: "Stop Monitoring"
|
|
629
629
|
starting: "Starting..."
|
|
630
630
|
stopping: "Stopping..."
|
|
631
|
-
load_history: "
|
|
631
|
+
load_history: "Load History"
|
|
632
|
+
load_history_unavailable_title: "No stored history — set config.query_monitor_log_file to keep captured queries across restarts"
|
|
632
633
|
loading: "Loading..."
|
|
633
634
|
running: "Running..."
|
|
634
|
-
save_for_comparison: "
|
|
635
|
-
saved_marker: "
|
|
635
|
+
save_for_comparison: "Save for Comparison"
|
|
636
|
+
saved_marker: "Saved"
|
|
636
637
|
status:
|
|
637
638
|
pg_stat_ready: "Active"
|
|
638
639
|
not_preloaded: "Preload required"
|
|
@@ -650,19 +651,20 @@ en:
|
|
|
650
651
|
create_extension_title: "Create pg_stat_statements extension"
|
|
651
652
|
create_extension_intro: "The pg_stat_statements extension isn't created in this database yet. Click below to create it:"
|
|
652
653
|
create_extension_note: "If the library isn't preloaded, you'll also need to add it to shared_preload_libraries and restart PostgreSQL."
|
|
653
|
-
reset_stats_title: "
|
|
654
|
+
reset_stats_title: "Reset Statistics"
|
|
654
655
|
reset_stats_confirm: "Are you sure you want to reset pg_stat_statements statistics?"
|
|
655
656
|
reset_stats_warning: "This action will clear all collected query statistics and cannot be undone."
|
|
656
|
-
ide_settings_title: "
|
|
657
|
-
problem_detected_title: "
|
|
658
|
-
query_analyzer_title: "
|
|
657
|
+
ide_settings_title: "IDE Settings"
|
|
658
|
+
problem_detected_title: "Problem Detected"
|
|
659
|
+
query_analyzer_title: "Query Analyzer"
|
|
659
660
|
query_label: "Query:"
|
|
660
661
|
parameters_label: "Parameters:"
|
|
661
|
-
migration_title: "
|
|
662
|
+
migration_title: "Drop Index Migration"
|
|
662
663
|
migration_subtitle: "Generated migration to remove the index:"
|
|
663
664
|
migration_warning: "Creating a migration will generate a migration file in your project. Running this migration will drop the index from the database, which may significantly impact application performance."
|
|
664
665
|
migration_warning_dev_only: "This operation should only be performed in a local development environment."
|
|
665
|
-
query_execution_disabled_title: "
|
|
666
|
+
query_execution_disabled_title: "Query execution is disabled"
|
|
667
|
+
migration_disabled_title: "Migration creation is disabled"
|
|
666
668
|
query_execution_disabled_intro: "To enable this feature, add to your configuration:"
|
|
667
669
|
query_execution_disabled_env_note: "...or set the following environment variable instead:"
|
|
668
670
|
run_query_title: "SQL Console"
|
|
@@ -705,25 +707,27 @@ en:
|
|
|
705
707
|
waiting_for_locks: "waiting for locks"
|
|
706
708
|
percent_used_suffix: "% used"
|
|
707
709
|
categories:
|
|
708
|
-
requires_pg_stat: "
|
|
710
|
+
requires_pg_stat: "Requires pg_stat_statements"
|
|
711
|
+
pg_stat_missing_reason: "Requires pg_stat_statements, which is not installed on \"%{database}\". Create the extension there, or switch to a database that has it."
|
|
712
|
+
pg_stat_not_preloaded_reason: "Requires pg_stat_statements. The extension exists on \"%{database}\" but is not in shared_preload_libraries, so it returns no data until PostgreSQL is restarted with it preloaded."
|
|
709
713
|
reports_count_suffix: "reports"
|
|
710
|
-
primary_only_reason: "
|
|
711
|
-
standalone_no_host_app_reason: "
|
|
714
|
+
primary_only_reason: "This category only runs on the primary database — it inspects the host application's models. Switch back to the default database to use it."
|
|
715
|
+
standalone_no_host_app_reason: "Not available in standalone mode — this category inspects the host application's models, and there is no host app when running the dashboard on its own."
|
|
712
716
|
documentation:
|
|
713
|
-
toggle_title: "
|
|
714
|
-
what_section: "
|
|
715
|
-
why_section: "
|
|
716
|
-
nuances_section: "
|
|
717
|
-
thresholds_section: "
|
|
718
|
-
threshold_warning_label: "
|
|
719
|
-
threshold_critical_label: "
|
|
717
|
+
toggle_title: "What does this report show?"
|
|
718
|
+
what_section: "What"
|
|
719
|
+
why_section: "Why It Matters"
|
|
720
|
+
nuances_section: "Nuances"
|
|
721
|
+
thresholds_section: "Thresholds"
|
|
722
|
+
threshold_warning_label: "Warning:"
|
|
723
|
+
threshold_critical_label: "Critical:"
|
|
720
724
|
threshold_inverted_note: "(lower is worse)"
|
|
721
725
|
filters:
|
|
722
|
-
title: "
|
|
726
|
+
title: "Filter Parameters"
|
|
723
727
|
current_value: "current"
|
|
724
728
|
saved:
|
|
725
|
-
title: "
|
|
726
|
-
saved_at_prefix: "
|
|
729
|
+
title: "Saved for Comparison"
|
|
730
|
+
saved_at_prefix: "Saved:"
|
|
727
731
|
click_to_expand: "Click to expand"
|
|
728
732
|
confirm_clear_all: "Remove all saved records for this report?"
|
|
729
733
|
remove_title: "Remove"
|
|
@@ -737,9 +741,9 @@ en:
|
|
|
737
741
|
execution_time_label: "Execution time:"
|
|
738
742
|
null_placeholder: "<null>"
|
|
739
743
|
sections:
|
|
740
|
-
recommendation: "
|
|
741
|
-
detected_issues: "
|
|
742
|
-
execution_plan: "
|
|
744
|
+
recommendation: "Recommendation"
|
|
745
|
+
detected_issues: "Detected Issues"
|
|
746
|
+
execution_plan: "Execution Plan"
|
|
743
747
|
line_label: "Line"
|
|
744
748
|
current_label: "Current:"
|
|
745
749
|
threshold_label: "Threshold:"
|
|
@@ -747,8 +751,8 @@ en:
|
|
|
747
751
|
warning_eq: "warning"
|
|
748
752
|
critical_eq: "critical"
|
|
749
753
|
levels:
|
|
750
|
-
critical: "
|
|
751
|
-
warning: "
|
|
754
|
+
critical: "Critical"
|
|
755
|
+
warning: "Warning"
|
|
752
756
|
errors:
|
|
753
757
|
error_prefix: "Error:"
|
|
754
758
|
unable_fetch_metrics: "Unable to fetch database statistics."
|
|
@@ -776,8 +780,9 @@ en:
|
|
|
776
780
|
run_query_failed: "Failed to run query"
|
|
777
781
|
query_required: "Please enter a query"
|
|
778
782
|
create_migration_failed: "Failed to create migration"
|
|
779
|
-
explain_disabled_toast: "
|
|
780
|
-
execute_disabled_toast: "
|
|
783
|
+
explain_disabled_toast: "EXPLAIN ANALYZE is disabled. Enable in configuration: config.allow_raw_query_execution = true"
|
|
784
|
+
execute_disabled_toast: "Query execution is disabled. Enable in configuration: config.allow_raw_query_execution = true"
|
|
785
|
+
migration_disabled_toast: "Migration creation is disabled. Enable in configuration: config.allow_raw_query_execution = true"
|
|
781
786
|
query_monitoring_error: "Query monitoring error"
|
|
782
787
|
query_hash_required: "Query hash is required"
|
|
783
788
|
query_execution_disabled: "Query execution from dashboard is disabled. Enable it in configuration with 'config.allow_raw_query_execution = true'"
|
data/config/locales/ru.yml
CHANGED
|
@@ -556,7 +556,7 @@ ru:
|
|
|
556
556
|
page_title: "PgReports — Дашборд"
|
|
557
557
|
navigation:
|
|
558
558
|
dashboard: "Дашборд"
|
|
559
|
-
back: "
|
|
559
|
+
back: "Назад"
|
|
560
560
|
database_selector:
|
|
561
561
|
label: "База данных"
|
|
562
562
|
target_selector:
|
|
@@ -564,40 +564,41 @@ ru:
|
|
|
564
564
|
actions:
|
|
565
565
|
cancel: "Отмена"
|
|
566
566
|
retry: "Повторить"
|
|
567
|
-
copy: "
|
|
568
|
-
copy_query: "
|
|
569
|
-
copy_code: "
|
|
567
|
+
copy: "Копировать"
|
|
568
|
+
copy_query: "Копировать запрос"
|
|
569
|
+
copy_code: "Копировать код"
|
|
570
570
|
copy_to_clipboard_title: "Скопировать в буфер обмена"
|
|
571
|
-
copied_feedback: "
|
|
571
|
+
copied_feedback: "Скопировано!"
|
|
572
572
|
clear_all: "Очистить всё"
|
|
573
|
-
run_report: "
|
|
574
|
-
export: "
|
|
575
|
-
download_text: "
|
|
576
|
-
download_csv: "
|
|
577
|
-
download_json: "
|
|
578
|
-
download: "
|
|
573
|
+
run_report: "Запустить отчёт"
|
|
574
|
+
export: "Экспорт"
|
|
575
|
+
download_text: "Текст (.txt)"
|
|
576
|
+
download_csv: "CSV (.csv)"
|
|
577
|
+
download_json: "JSON (.json)"
|
|
578
|
+
download: "Скачать"
|
|
579
579
|
copy_ai_prompt: "Копировать промпт"
|
|
580
|
-
send_telegram: "
|
|
580
|
+
send_telegram: "Telegram"
|
|
581
581
|
sending: "Отправка..."
|
|
582
|
-
reset_statistics: "
|
|
582
|
+
reset_statistics: "Сбросить статистику"
|
|
583
583
|
resetting: "Сброс..."
|
|
584
584
|
confirm_reset: "Да, сбросить"
|
|
585
|
-
create_extension: "
|
|
585
|
+
create_extension: "Создать расширение"
|
|
586
586
|
creating: "Создание..."
|
|
587
587
|
ide_settings_button_title: "Настройки IDE"
|
|
588
|
-
explain_analyze: "
|
|
589
|
-
execute_query: "
|
|
588
|
+
explain_analyze: "EXPLAIN ANALYZE"
|
|
589
|
+
execute_query: "Выполнить запрос"
|
|
590
590
|
run_query: "SQL-консоль"
|
|
591
|
-
create_migration_file: "
|
|
592
|
-
start_monitoring: "
|
|
593
|
-
stop_monitoring: "
|
|
591
|
+
create_migration_file: "Создать файл и открыть в IDE"
|
|
592
|
+
start_monitoring: "Запустить мониторинг"
|
|
593
|
+
stop_monitoring: "Остановить мониторинг"
|
|
594
594
|
starting: "Запуск..."
|
|
595
595
|
stopping: "Остановка..."
|
|
596
|
-
load_history: "
|
|
596
|
+
load_history: "Загрузить историю"
|
|
597
|
+
load_history_unavailable_title: "Сохранённой истории нет — задайте config.query_monitor_log_file, чтобы запросы сохранялись между перезапусками"
|
|
597
598
|
loading: "Загрузка..."
|
|
598
599
|
running: "Выполнение..."
|
|
599
|
-
save_for_comparison: "
|
|
600
|
-
saved_marker: "
|
|
600
|
+
save_for_comparison: "Сохранить для сравнения"
|
|
601
|
+
saved_marker: "Сохранено"
|
|
601
602
|
status:
|
|
602
603
|
pg_stat_ready: "Активно"
|
|
603
604
|
not_preloaded: "Требуется предзагрузка"
|
|
@@ -615,19 +616,20 @@ ru:
|
|
|
615
616
|
create_extension_title: "Создание расширения pg_stat_statements"
|
|
616
617
|
create_extension_intro: "Расширение pg_stat_statements ещё не создано в этой базе данных. Нажмите, чтобы создать его:"
|
|
617
618
|
create_extension_note: "Если библиотека не предзагружена, её также нужно добавить в shared_preload_libraries и перезапустить PostgreSQL."
|
|
618
|
-
reset_stats_title: "
|
|
619
|
+
reset_stats_title: "Сброс статистики"
|
|
619
620
|
reset_stats_confirm: "Вы уверены, что хотите сбросить статистику pg_stat_statements?"
|
|
620
621
|
reset_stats_warning: "Это действие очистит всю собранную статистику запросов и не может быть отменено."
|
|
621
|
-
ide_settings_title: "
|
|
622
|
-
problem_detected_title: "
|
|
623
|
-
query_analyzer_title: "
|
|
622
|
+
ide_settings_title: "Настройки IDE"
|
|
623
|
+
problem_detected_title: "Обнаружена проблема"
|
|
624
|
+
query_analyzer_title: "Анализатор запроса"
|
|
624
625
|
query_label: "Запрос:"
|
|
625
626
|
parameters_label: "Параметры:"
|
|
626
|
-
migration_title: "
|
|
627
|
+
migration_title: "Миграция удаления индекса"
|
|
627
628
|
migration_subtitle: "Сгенерированная миграция для удаления индекса:"
|
|
628
629
|
migration_warning: "Создание миграции сгенерирует файл миграции в вашем проекте. Запуск этой миграции удалит индекс из БД, что может значительно повлиять на производительность приложения."
|
|
629
630
|
migration_warning_dev_only: "Эту операцию следует выполнять только в локальном dev-окружении."
|
|
630
|
-
query_execution_disabled_title: "
|
|
631
|
+
query_execution_disabled_title: "Выполнение запросов отключено"
|
|
632
|
+
migration_disabled_title: "Создание миграций отключено"
|
|
631
633
|
query_execution_disabled_intro: "Чтобы включить эту функцию, добавьте в конфигурацию:"
|
|
632
634
|
query_execution_disabled_env_note: "...или вместо этого установите переменную окружения:"
|
|
633
635
|
run_query_title: "SQL-консоль"
|
|
@@ -670,25 +672,27 @@ ru:
|
|
|
670
672
|
waiting_for_locks: "ждут блокировок"
|
|
671
673
|
percent_used_suffix: "% использовано"
|
|
672
674
|
categories:
|
|
673
|
-
requires_pg_stat: "
|
|
675
|
+
requires_pg_stat: "Требуется pg_stat_statements"
|
|
676
|
+
pg_stat_missing_reason: "Требуется pg_stat_statements, но расширение не установлено в базе «%{database}». Создайте его там или переключитесь на базу, где оно есть."
|
|
677
|
+
pg_stat_not_preloaded_reason: "Требуется pg_stat_statements. Расширение есть в базе «%{database}», но отсутствует в shared_preload_libraries — данных не будет, пока PostgreSQL не перезапустят с ним."
|
|
674
678
|
reports_count_suffix: "отчётов"
|
|
675
|
-
primary_only_reason: "
|
|
676
|
-
standalone_no_host_app_reason: "
|
|
679
|
+
primary_only_reason: "Эта категория работает только на первичной базе — она проверяет модели хост-приложения. Чтобы пользоваться, переключитесь обратно на базу по умолчанию."
|
|
680
|
+
standalone_no_host_app_reason: "Недоступно в автономном режиме — эта категория проверяет модели хост-приложения, а при самостоятельном запуске дашборда хост-приложения нет."
|
|
677
681
|
documentation:
|
|
678
|
-
toggle_title: "
|
|
679
|
-
what_section: "
|
|
680
|
-
why_section: "
|
|
681
|
-
nuances_section: "
|
|
682
|
-
thresholds_section: "
|
|
683
|
-
threshold_warning_label: "
|
|
684
|
-
threshold_critical_label: "
|
|
682
|
+
toggle_title: "Что показывает этот отчёт?"
|
|
683
|
+
what_section: "Что"
|
|
684
|
+
why_section: "Почему это важно"
|
|
685
|
+
nuances_section: "Нюансы"
|
|
686
|
+
thresholds_section: "Пороги"
|
|
687
|
+
threshold_warning_label: "Warning:"
|
|
688
|
+
threshold_critical_label: "Critical:"
|
|
685
689
|
threshold_inverted_note: "(меньше — хуже)"
|
|
686
690
|
filters:
|
|
687
|
-
title: "
|
|
691
|
+
title: "Параметры фильтрации"
|
|
688
692
|
current_value: "сейчас"
|
|
689
693
|
saved:
|
|
690
|
-
title: "
|
|
691
|
-
saved_at_prefix: "
|
|
694
|
+
title: "Сохранено для сравнения"
|
|
695
|
+
saved_at_prefix: "Сохранено:"
|
|
692
696
|
click_to_expand: "Нажмите, чтобы развернуть"
|
|
693
697
|
confirm_clear_all: "Удалить все сохранённые записи для этого отчёта?"
|
|
694
698
|
remove_title: "Удалить"
|
|
@@ -702,9 +706,9 @@ ru:
|
|
|
702
706
|
execution_time_label: "Время выполнения:"
|
|
703
707
|
null_placeholder: "<null>"
|
|
704
708
|
sections:
|
|
705
|
-
recommendation: "
|
|
706
|
-
detected_issues: "
|
|
707
|
-
execution_plan: "
|
|
709
|
+
recommendation: "Рекомендация"
|
|
710
|
+
detected_issues: "Обнаруженные проблемы"
|
|
711
|
+
execution_plan: "План выполнения"
|
|
708
712
|
line_label: "Строка"
|
|
709
713
|
current_label: "Текущее:"
|
|
710
714
|
threshold_label: "Порог:"
|
|
@@ -712,8 +716,8 @@ ru:
|
|
|
712
716
|
warning_eq: "warning"
|
|
713
717
|
critical_eq: "critical"
|
|
714
718
|
levels:
|
|
715
|
-
critical: "
|
|
716
|
-
warning: "
|
|
719
|
+
critical: "Критично"
|
|
720
|
+
warning: "Внимание"
|
|
717
721
|
errors:
|
|
718
722
|
error_prefix: "Ошибка:"
|
|
719
723
|
unable_fetch_metrics: "Не удалось получить статистику БД."
|
|
@@ -741,8 +745,9 @@ ru:
|
|
|
741
745
|
run_query_failed: "Не удалось выполнить запрос"
|
|
742
746
|
query_required: "Введите запрос"
|
|
743
747
|
create_migration_failed: "Не удалось создать миграцию"
|
|
744
|
-
explain_disabled_toast: "
|
|
745
|
-
execute_disabled_toast: "
|
|
748
|
+
explain_disabled_toast: "EXPLAIN ANALYZE отключен. Включите в конфигурации: config.allow_raw_query_execution = true"
|
|
749
|
+
execute_disabled_toast: "Выполнение запросов отключено. Включите в конфигурации: config.allow_raw_query_execution = true"
|
|
750
|
+
migration_disabled_toast: "Создание миграций отключено. Включите в конфигурации: config.allow_raw_query_execution = true"
|
|
746
751
|
query_monitoring_error: "Ошибка мониторинга запросов"
|
|
747
752
|
query_hash_required: "Требуется хэш запроса"
|
|
748
753
|
query_execution_disabled: "Выполнение запросов из дашборда отключено. Включите в конфигурации: 'config.allow_raw_query_execution = true'"
|