diff --git a/app/assets/images/icons/reports-fill.svg b/app/assets/images/icons/reports-fill.svg new file mode 100644 index 00000000..33b766b0 --- /dev/null +++ b/app/assets/images/icons/reports-fill.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/components/sidebar_component.rb b/app/components/sidebar_component.rb index b779a472..9212b0ad 100644 --- a/app/components/sidebar_component.rb +++ b/app/components/sidebar_component.rb @@ -20,6 +20,8 @@ def build_admin_section path: helpers.projects_path, icon: "journal-text"), SIDEBAR_ITEM.new(name: t("new_report", scope: "components.sidebar_component.build_admin_section"), path: helpers.new_report_path, icon: "add"), + SIDEBAR_ITEM.new(name: t("reports", scope: "components.sidebar_component.build_admin_section"), + path: helpers.reports_path, icon: "reports-fill"), SIDEBAR_ITEM.new(name: t("users", scope: "components.sidebar_component.build_admin_section"), path: helpers.users_path, icon: "person-gear"), SIDEBAR_ITEM.new(name: t("regions", scope: "components.sidebar_component.build_admin_section"), diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index f1c63bd7..9473c0d7 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -1,4 +1,8 @@ class ReportsController < ApplicationController + def index + @reports = Report.order(created_at: :desc) + end + def show @report = Report.find(params[:id]) end @@ -98,6 +102,16 @@ def filter render :new end + def destroy + @report = Report.find(params[:id]) + + if @report.destroy + redirect_to reports_path, flash: { success: t(".success") } + else + redirect_to reports_path, flash: { error: @report.errors.full_messages.to_sentence } + end + end + private def load_edit_context diff --git a/app/views/reports/index.html.erb b/app/views/reports/index.html.erb new file mode 100644 index 00000000..286a207d --- /dev/null +++ b/app/views/reports/index.html.erb @@ -0,0 +1,22 @@ +
+
+

<%= t(".title") %>

+ <%= render ActionButtonComponent.new(to: new_report_path, icon: "add", colour: :primary, size: :large, turbo_stream: true) do %> + <%= t(".actions.create") %> + <% end %> +
+ <%= render ContentCardComponent.new do %> + <%= render Shared::IndexTableComponent.new(records: @reports) do |table| %> + <% table.column :id, header: t(".columns.id"), col_size: "80px" %> + <% table.column :start_date, header: t(".columns.start_date") %> + <% table.column :end_date, header: t(".columns.end_date") %> + <% table.column :actions, header: t("shared.index_table_component.actions"), col_size: "90px" do |report| %> +
+ <%= render ActionButtonComponent.new(to: report_path(report), icon: "view") %> + <%= render ActionButtonComponent.new(to: edit_report_path(report), icon: "edit", colour: :info, turbo_stream: true) %> + <%= render ActionButtonComponent.new(to: report_path(report), method: :delete, icon: "delete", colour: :error, confirm: t("reports.destroy.confirm")) %> +
+ <% end %> + <% end %> + <% end %> +
diff --git a/config/locales/en/components.en.yml b/config/locales/en/components.en.yml index b057a92e..5ef9a672 100644 --- a/config/locales/en/components.en.yml +++ b/config/locales/en/components.en.yml @@ -7,6 +7,7 @@ en: new_report: New Report projects: Projects regions: Regions + reports: Reports users: Users build_projects_section: projects: Projects diff --git a/config/locales/en/reports.en.yml b/config/locales/en/reports.en.yml index 8dc09c1d..4858e10c 100644 --- a/config/locales/en/reports.en.yml +++ b/config/locales/en/reports.en.yml @@ -1,9 +1,17 @@ --- en: + activerecord: + attributes: + report: + end_date: End date + start_date: Start date reports: create: invalid: Please provide valid dates and select at least one subproject. success: Report was successfully generated. + destroy: + confirm: Are you sure you want to delete this report? + success: Report deleted successfully. edit: add_aggregated_datum: Add Aggregated Data Box add_journal: Add Journal @@ -18,6 +26,14 @@ en: save: Save Changes selected_journals: Selected Journals title: Edit Report + index: + actions: + create: Create Report + columns: + end_date: End date + id: ID + start_date: Start date + title: Reports journal_card_component: author: Author new: diff --git a/config/locales/es/components.es.yml b/config/locales/es/components.es.yml index 80e0f14e..c77e9018 100644 --- a/config/locales/es/components.es.yml +++ b/config/locales/es/components.es.yml @@ -7,6 +7,7 @@ es: new_report: Nuevo Reporte projects: Proyectos regions: Regiones + reports: Reportes users: Usuarios build_projects_section: projects: Proyectos diff --git a/config/locales/es/reports.es.yml b/config/locales/es/reports.es.yml index 926811fb..45e1a605 100644 --- a/config/locales/es/reports.es.yml +++ b/config/locales/es/reports.es.yml @@ -1,9 +1,17 @@ --- es: + activerecord: + attributes: + report: + end_date: Fecha de fin + start_date: Fecha de inicio reports: create: invalid: Por favor proporcione fechas válidas y seleccione al menos un subproyecto. success: El reporte fue generado exitosamente. + destroy: + confirm: "¿Estás seguro que deseas eliminar este reporte?" + success: Reporte eliminado exitosamente. edit: add_aggregated_datum: Agregar Caja de Datos Agregados add_journal: Agregar Diario @@ -18,6 +26,14 @@ es: save: Guardar Cambios selected_journals: Diarios Seleccionados title: Editar Reporte + index: + actions: + create: Crear reporte + columns: + end_date: Fecha de fin + id: ID + start_date: Fecha de inicio + title: Reportes journal_card_component: author: Autor new: diff --git a/config/routes.rb b/config/routes.rb index 7eaa680c..a96acaba 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -40,7 +40,7 @@ delete "/logout", to: "sessions#destroy" # Report routes - resources :reports, only: %i[show new create edit update] do + resources :reports, only: %i[index show new create edit update destroy] do collection do get :filter end diff --git a/test/controllers/reports_controller_test.rb b/test/controllers/reports_controller_test.rb index 1bcd0b64..41e65d92 100644 --- a/test/controllers/reports_controller_test.rb +++ b/test/controllers/reports_controller_test.rb @@ -6,11 +6,13 @@ class ReportsControllerTest < ActionDispatch::IntegrationTest end [ + { route: "index", method: :get, url_helper: :reports_url, needs_report: false }, { route: "show", method: :get, url_helper: :report_url, needs_report: true }, { route: "new", method: :get, url_helper: :new_report_url, needs_report: false }, { route: "edit", method: :get, url_helper: :edit_report_url, needs_report: true }, { route: "filter", method: :get, url_helper: :filter_reports_url, needs_report: false }, - { route: "update", method: :patch, url_helper: :report_url, needs_report: true } + { route: "update", method: :patch, url_helper: :report_url, needs_report: true }, + { route: "destroy", method: :delete, url_helper: :report_url, needs_report: true } ].each do |hash| test "##{hash[:route]} redirects to login route when a user is not authenticated" do log_out_user @@ -34,6 +36,7 @@ class ReportsControllerTest < ActionDispatch::IntegrationTest end [ + { route: "index", method: :get, url_helper: :reports_url, needs_report: false }, { route: "show", method: :get, url_helper: :report_url, needs_report: true }, { route: "new", method: :get, url_helper: :new_report_url, needs_report: false }, { route: "edit", method: :get, url_helper: :edit_report_url, needs_report: true } @@ -64,6 +67,19 @@ class ReportsControllerTest < ActionDispatch::IntegrationTest assert_match aggregated_datum.additional_text, response.body end + test "#index displays all reports" do + report_a = create(:report, start_date: Date.new(2025, 1, 1), end_date: Date.new(2025, 1, 31)) + report_b = create(:report, start_date: Date.new(2025, 2, 1), end_date: Date.new(2025, 2, 28)) + + get reports_path + assert_response :success + + assert_select "div", text: report_a.id.to_s + assert_select "div", text: report_b.id.to_s + assert_select "div", text: report_a.start_date.to_s + assert_select "div", text: report_b.start_date.to_s + end + test "#filter displays projects when valid dates are provided" do subproject = create(:subproject) create(:log_entry, subproject: subproject, created_at: 1.day.ago) @@ -226,4 +242,15 @@ class ReportsControllerTest < ActionDispatch::IntegrationTest assert_equal [report_journal.id], report.journal_ids assert_equal [retained_datum.id], report.aggregated_data.ids end + + test "#destroy deletes report when user is an admin" do + report = create(:report) + + assert_difference("Report.count", -1) do + delete report_path(report) + end + + assert_redirected_to reports_path + assert_equal I18n.t("reports.destroy.success"), flash[:success] + end end