diff --git a/Gemfile b/Gemfile
index e831ac8..832f5ad 100644
--- a/Gemfile
+++ b/Gemfile
@@ -12,6 +12,10 @@ gemspec
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.
+# Lock minitest to 5.x until Rails 7.1+ adds Minitest 6.0 support
+# Minitest 6.0.0 was released Dec 2024 with breaking API changes
+gem 'minitest', '~> 5.0'
+
group :development do
gem 'gem-release'
gem 'json'
diff --git a/app/assets/javascripts/kanaui/kiddo/kiddo_initialize.js b/app/assets/javascripts/kanaui/kiddo/kiddo_initialize.js
index 85b8332..4a1ccef 100644
--- a/app/assets/javascripts/kanaui/kiddo/kiddo_initialize.js
+++ b/app/assets/javascripts/kanaui/kiddo/kiddo_initialize.js
@@ -1,4 +1,26 @@
(function (d3, $, window, document, undefined) {
+ function errorMessage(error) {
+ if (error && error.responseText) {
+ try {
+ var response = JSON.parse(error.responseText);
+ if (response.message) {
+ return response.message;
+ }
+ } catch (ex) {
+ return error.responseText;
+ }
+ }
+
+ return error && error.message ? error.message : String(error);
+ }
+
+ function renderError(message) {
+ var escapedMessage = $("
").text(message).html();
+ $("#chartAnchor").prepend(
+ '' + escapedMessage + "
"
+ );
+ }
+
$(document).ready(function () {
if ($("#chartAnchor").length == 0) {
return;
@@ -10,7 +32,8 @@
var renderer = new Kiddo.Renderer("#chartAnchor");
if (error) {
- ajaxErrorAlert(error);
+ var message = errorMessage(error);
+ renderError(message);
return renderer.noData();
}
diff --git a/app/assets/stylesheets/kanaui/kanaui.css b/app/assets/stylesheets/kanaui/kanaui.css
index fc3cd73..b5a4bfa 100644
--- a/app/assets/stylesheets/kanaui/kanaui.css
+++ b/app/assets/stylesheets/kanaui/kanaui.css
@@ -329,11 +329,25 @@
/* app/views/kanaui/reports/index.html.erb */
+.kanaui-flash-container {
+ margin: 1rem 0 1.5rem;
+ position: relative;
+ z-index: 1;
+}
+
+.kanaui-flash-container .alert {
+ margin-bottom: 0.75rem;
+}
+
.kanaui-reports-index .configured-reports {
max-width: 80rem;
width: 100%;
}
+.kanaui-reports-index .kanaui-report-notice {
+ margin-bottom: 1rem;
+}
+
.kanaui-reports-index .configured-reports .configured-reports-header {
display: flex;
align-items: start;
diff --git a/app/controllers/kanaui/dashboard_controller.rb b/app/controllers/kanaui/dashboard_controller.rb
index bdfd1c5..20d4ec6 100644
--- a/app/controllers/kanaui/dashboard_controller.rb
+++ b/app/controllers/kanaui/dashboard_controller.rb
@@ -19,9 +19,13 @@ def index
@reports = JSON.parse(raw_reports)
@report = current_report(@reports) || {}
- # If no report name is provided, redirect to the default (second) report
- if @raw_name.blank? && @reports.is_a?(Array) && @reports[1].present?
- default_name = @reports[1]['reportName']
+ # If no report name is provided, redirect to a default report.
+ # Prefer the historical default (second report) when present, but fall back
+ # to the first report so a single configured report still renders the
+ # dashboard controls and chart area.
+ default_report = @reports[1] || @reports[0] if @reports.is_a?(Array)
+ if @raw_name.blank? && default_report.present?
+ default_name = default_report['reportName']
query_params = { start_date: @start_date,
end_date: @end_date,
name: default_name,
diff --git a/app/controllers/kanaui/engine_controller.rb b/app/controllers/kanaui/engine_controller.rb
index 26dc810..92f18ba 100644
--- a/app/controllers/kanaui/engine_controller.rb
+++ b/app/controllers/kanaui/engine_controller.rb
@@ -27,8 +27,22 @@ def options_for_klient
end
rescue_from(KillBillClient::API::ResponseError) do |killbill_exception|
- flash[:error] = "Error while communicating with the Kill Bill server: #{as_string(killbill_exception)}"
- redirect_to dashboard_index_path
+ error_message = I18n.t('kanaui.errors.killbill_communication', error: as_string(killbill_exception))
+
+ if json_request?
+ render json: { message: error_message }, status: killbill_exception.response.code.to_i
+ else
+ flash[:error] = error_message
+ redirect_to dashboard_index_path
+ end
+ end
+
+ def json_request?
+ request.format.json? || params[:format] == 'json' || dashboard_reports_json_request?
+ end
+
+ def dashboard_reports_json_request?
+ controller_name == 'dashboard' && action_name == 'reports' && params[:format].blank?
end
def as_string(e)
diff --git a/app/controllers/kanaui/reports_controller.rb b/app/controllers/kanaui/reports_controller.rb
index b103616..0dd1e9b 100644
--- a/app/controllers/kanaui/reports_controller.rb
+++ b/app/controllers/kanaui/reports_controller.rb
@@ -4,6 +4,7 @@ module Kanaui
class ReportsController < Kanaui::EngineController
def index
@reports = JSON.parse(Kanaui::DashboardHelper::DashboardApi.available_reports(options_for_klient)).map(&:deep_symbolize_keys)
+ @report_notice = report_notice_from_flash
end
def new
@@ -13,8 +14,7 @@ def new
def create
Kanaui::DashboardHelper::DashboardApi.create_report(report_from_params.to_json, options_for_klient)
- flash[:notice] = 'Report successfully created'
- redirect_to action: :index
+ redirect_to_index_with_notice(:created)
end
def edit
@@ -26,26 +26,35 @@ def edit
def update
Kanaui::DashboardHelper::DashboardApi.update_report(params.require(:id), report_from_params.to_json, options_for_klient)
- flash[:notice] = 'Report successfully updated'
- redirect_to action: :index
+ redirect_to_index_with_notice(:updated)
end
def refresh
Kanaui::DashboardHelper::DashboardApi.refresh_report(params.require(:id), options_for_klient)
- flash[:notice] = 'Report refresh successfully scheduled'
- redirect_to action: :index
+ redirect_to_index_with_notice(:refresh_scheduled)
end
def destroy
Kanaui::DashboardHelper::DashboardApi.delete_report(params.require(:id), options_for_klient)
- flash[:notice] = 'Report successfully deleted'
- redirect_to action: :index
+ redirect_to_index_with_notice(:deleted)
end
private
+ def report_notice_from_flash
+ notice_key = flash[:report_notice].presence&.to_s
+ return nil unless %w[created updated refresh_scheduled deleted].include?(notice_key)
+
+ I18n.t("kanaui.reports.notices.#{notice_key}", default: nil)
+ end
+
+ def redirect_to_index_with_notice(notice_key)
+ flash[:report_notice] = notice_key
+ redirect_to action: :index
+ end
+
def report_from_params
{
reportName: params[:report_name],
diff --git a/app/views/kanaui/dashboard/index.html.erb b/app/views/kanaui/dashboard/index.html.erb
index ba9ea43..910b94d 100644
--- a/app/views/kanaui/dashboard/index.html.erb
+++ b/app/views/kanaui/dashboard/index.html.erb
@@ -261,7 +261,7 @@
<%= params[:name] -%>
<% end %>
- <%= link_to 'SQL query', kanaui_engine.reports_path(params.to_h.merge(:sql_only => true)) %>
+ <%= link_to t('kanaui.dashboard.advanced_controls.sql_query'), kanaui_engine.reports_path(params.to_h.merge(:sql_only => true)) %>
diff --git a/app/views/kanaui/layouts/kanaui_application.html.erb b/app/views/kanaui/layouts/kanaui_application.html.erb
index e060dfb..db880d1 100644
--- a/app/views/kanaui/layouts/kanaui_application.html.erb
+++ b/app/views/kanaui/layouts/kanaui_application.html.erb
@@ -11,24 +11,20 @@
<%- # :alert used by devise -%>
- <% [:error, :alert].each do |key| %>
- <% if flash[key] %>
-
+ <% if flash[:error] || flash[:alert] || flash[:notice] %>
+
+ <% [:error, :alert].each do |key| %>
+ <% if flash[key] %>
+
<%= flash[key] %>
+ <% end %>
<% end %>
- <% end %>
- <% if flash[:notice] %>
-
-
-
<%= flash[:notice] %>
-
-
+ <% if flash[:notice] %>
+
<%= flash[:notice] %>
+ <% end %>
+
<% end %>
<%= yield %>
-
+