diff --git a/app/controllers/decidim/stratified_sortitions/admin/samples_controller.rb b/app/controllers/decidim/stratified_sortitions/admin/samples_controller.rb
index 8492d83..5e8baff 100644
--- a/app/controllers/decidim/stratified_sortitions/admin/samples_controller.rb
+++ b/app/controllers/decidim/stratified_sortitions/admin/samples_controller.rb
@@ -30,6 +30,7 @@ def create
Decidim::StratifiedSortitions::Admin::ImportSample.call(@form, stratified_sortition, current_user) do
on(:ok) do
+ Decidim.traceability.perform_action!("import_sample", stratified_sortition, current_user, visibility: "all")
flash[:notice] = I18n.t("sample_imports.create.success", scope: "decidim.stratified_sortitions.admin")
redirect_to upload_sample_stratified_sortition_path(stratified_sortition)
end
@@ -46,6 +47,7 @@ def remove_multiple
Decidim::StratifiedSortitions::Admin::RemoveUploadedSamples.call(stratified_sortition) do
on(:ok) do
+ Decidim.traceability.perform_action!("remove_samples", stratified_sortition, current_user, visibility: "all")
flash[:notice] = I18n.t("sample_imports.remove_uploaded_samples.success", scope: "decidim.stratified_sortitions.admin")
redirect_to upload_sample_stratified_sortition_path(stratified_sortition)
end
diff --git a/app/controllers/decidim/stratified_sortitions/admin/stratified_sortitions_controller.rb b/app/controllers/decidim/stratified_sortitions/admin/stratified_sortitions_controller.rb
index a224f81..27cf5c7 100644
--- a/app/controllers/decidim/stratified_sortitions/admin/stratified_sortitions_controller.rb
+++ b/app/controllers/decidim/stratified_sortitions/admin/stratified_sortitions_controller.rb
@@ -142,6 +142,7 @@ def execute_stratified_sortition
@result = FairSortitionService.new(stratified_sortition).call
if @result.success?
stratified_sortition.update!(status: "executed")
+ Decidim.traceability.perform_action!("execute", stratified_sortition, current_user, visibility: "all")
flash[:notice] = I18n.t("stratified_sortitions.execute.success", scope: "decidim.stratified_sortitions.admin")
else
flash[:error] = @result.error
@@ -185,10 +186,24 @@ def export_results
SortitionResultsExportJob.perform_later(current_user, stratified_sortition, format)
+ Decidim.traceability.perform_action!("export_results", stratified_sortition, current_user, visibility: "all")
flash[:notice] = I18n.t("decidim.admin.exports.notice")
redirect_to execute_stratified_sortition_path(stratified_sortition)
end
+ def log_view_participants
+ portfolio = stratified_sortition.panel_portfolio
+
+ unless portfolio&.sampled?
+ head :unprocessable_entity
+ return
+ end
+
+ Decidim.traceability.perform_action!("view_participants", stratified_sortition, current_user, visibility: "all")
+
+ head :ok
+ end
+
private
def collection
diff --git a/app/models/decidim/stratified_sortitions/stratified_sortition.rb b/app/models/decidim/stratified_sortitions/stratified_sortition.rb
index 7885792..6e58ed7 100644
--- a/app/models/decidim/stratified_sortitions/stratified_sortition.rb
+++ b/app/models/decidim/stratified_sortitions/stratified_sortition.rb
@@ -16,6 +16,10 @@ class StratifiedSortition < ApplicationRecord
component_manifest_name "stratified_sortitions"
+ def self.log_presenter_class_for(_log)
+ Decidim::StratifiedSortitions::AdminLog::StratifiedSortitionPresenter
+ end
+
has_many :strata, class_name: "Decidim::StratifiedSortitions::Stratum", foreign_key: "decidim_stratified_sortition_id", dependent: :destroy
has_many :sample_imports, class_name: "Decidim::StratifiedSortitions::SampleImport", dependent: :destroy
has_many :sample_participants, class_name: "Decidim::StratifiedSortitions::SampleParticipant", foreign_key: "decidim_stratified_sortition_id", dependent: :destroy
diff --git a/app/packs/src/decidim/stratified_sortitions/results_tabs.js b/app/packs/src/decidim/stratified_sortitions/results_tabs.js
index 6fe4013..dea263e 100644
--- a/app/packs/src/decidim/stratified_sortitions/results_tabs.js
+++ b/app/packs/src/decidim/stratified_sortitions/results_tabs.js
@@ -33,6 +33,21 @@ document.addEventListener("DOMContentLoaded", () => {
confirmBtn.addEventListener("click", () => {
activateTab("participants-section");
+ // Log the view_participants action
+ const logUrl = confirmBtn.dataset.logUrl;
+ const csrfToken = confirmBtn.dataset.authenticityToken;
+ if (logUrl && csrfToken) {
+ fetch(logUrl, {
+ method: "POST",
+ headers: {
+ "X-CSRF-Token": csrfToken,
+ "Content-Type": "application/json",
+ },
+ }).catch(() => {
+ // Silently ignore log errors
+ });
+ }
+
// Close the modal
const modal = document.getElementById("confirm-participants-modal");
if (modal) {
diff --git a/app/presenters/decidim/stratified_sortitions/admin_log/stratified_sortition_presenter.rb b/app/presenters/decidim/stratified_sortitions/admin_log/stratified_sortition_presenter.rb
new file mode 100644
index 0000000..b98e10b
--- /dev/null
+++ b/app/presenters/decidim/stratified_sortitions/admin_log/stratified_sortition_presenter.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Decidim
+ module StratifiedSortitions
+ module AdminLog
+ # This class holds the logic to present a `Decidim::StratifiedSortitions::StratifiedSortition`
+ # for the `AdminLog` log.
+ #
+ # Usage should be automatic and you should not need to call this class
+ # directly, but here is an example:
+ #
+ # action_log = Decidim::ActionLog.last
+ # view_helpers # => this comes from the views
+ # StratifiedSortitionPresenter.new(action_log, view_helpers).present
+ class StratifiedSortitionPresenter < Decidim::Log::BasePresenter
+ private
+
+ def action_string
+ case action
+ when "create", "update", "delete", "duplicate",
+ "execute", "export_results", "view_participants",
+ "import_sample", "remove_samples"
+ "decidim.stratified_sortitions.admin_log.stratified_sortition.#{action}"
+ else
+ super
+ end
+ end
+
+ def i18n_labels_scope
+ "activemodel.attributes.stratified_sortition"
+ end
+ end
+ end
+ end
+end
diff --git a/app/views/decidim/stratified_sortitions/admin/stratified_sortitions/_confirm_participants_modal.html.erb b/app/views/decidim/stratified_sortitions/admin/stratified_sortitions/_confirm_participants_modal.html.erb
index 357c553..1ff4bce 100644
--- a/app/views/decidim/stratified_sortitions/admin/stratified_sortitions/_confirm_participants_modal.html.erb
+++ b/app/views/decidim/stratified_sortitions/admin/stratified_sortitions/_confirm_participants_modal.html.erb
@@ -11,7 +11,9 @@
-