From 49368343735f684fa112a28191e80d6287e9f2fe Mon Sep 17 00:00:00 2001 From: Volodymyr Shynkarov <3dmirok@gmail.com> Date: Fri, 10 Jan 2025 22:33:54 -0800 Subject: [PATCH] Date range filter (#37) * Show latest lab test per day chronologically, disabled doublig of dates in table * Add date filter to lab tests table * fixed 2 rubocop offenses * added date range rules * added place holder for empty data and added defauld dates * rewrite to use AR (was SQL), some logic moved to the Model * moved min and max date range vaues into configuration * fixed rubocop offenses related with using dates without timezone * fixed naming, AGAIN authorization in lab tests controller and few another fixes * fixed messages on empty records, empty records in specific date range * important but founded and fixed! fix: Associate lab tests with selected patient * fixed values render in table * removed extra variable * Fix formating and naming --------- Co-authored-by: aksafan --- app/controllers/lab_tests_controller.rb | 9 ++-- app/models/lab_test.rb | 16 +++++++ app/views/lab_tests/_date_filter.html.erb | 25 +++++++++++ .../lab_tests/_no_data_placeholder.html.erb | 42 +++++++++++++++++++ app/views/lab_tests/index.html.erb | 10 ++++- config/application.rb | 8 ++++ config/locales/en.yml | 8 ++++ 7 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 app/views/lab_tests/_date_filter.html.erb create mode 100644 app/views/lab_tests/_no_data_placeholder.html.erb diff --git a/app/controllers/lab_tests_controller.rb b/app/controllers/lab_tests_controller.rb index 03b0f98..73be542 100644 --- a/app/controllers/lab_tests_controller.rb +++ b/app/controllers/lab_tests_controller.rb @@ -12,8 +12,10 @@ def index @recordables = policy_scope(LabTest) .select(:recordable_id, :created_at) .where(user_id: @chosen_user_id) + .in_date_range(params[:start_date], params[:end_date]) .order(:created_at) .group(:recordable_id, :created_at) + @biomarkers = policy_scope(Biomarker) .includes(:reference_ranges, :lab_tests) .where(lab_tests: { user_id: @chosen_user_id }) @@ -42,7 +44,7 @@ def create ActiveRecord::Base.transaction do @health_record = HealthRecord.new( - user: set_user, + user: lab_test_user, notes: lab_test_params[:notes] ) @@ -115,7 +117,7 @@ def save_health_record_with_lab_test @health_record.save && @lab_test.save end - def set_user + def lab_test_user if current_user.full_access_roles_can? && lab_test_params[:user_id].present? User.find(lab_test_params[:user_id]) else @@ -124,7 +126,8 @@ def set_user end def build_lab_test - @lab_test = current_user.lab_tests.build(lab_test_params) + user = lab_test_user + @lab_test = user.lab_tests.build(lab_test_params) end # Only allow a list of trusted parameters through. diff --git a/app/models/lab_test.rb b/app/models/lab_test.rb index b7f7555..de166c7 100644 --- a/app/models/lab_test.rb +++ b/app/models/lab_test.rb @@ -13,6 +13,22 @@ class LabTest < ApplicationRecord message: :must_be_nonnegative_and_numeric } + scope :in_date_range, lambda { |start_date, end_date| + scope = all + scope = scope.where(created_at: Date.parse(start_date).beginning_of_day..) if start_date.present? + scope = scope.where(created_at: ..Date.parse(end_date).end_of_day) if end_date.present? + scope + } + + scope :with_date, lambda { |date| + where(created_at: date.all_day) + } + + # Single ordering scope with consistent secondary ordering + scope :order_by_date, lambda { + order(created_at: :asc, id: :asc) + } + class Status NORMAL = :normal HIGH = :high diff --git a/app/views/lab_tests/_date_filter.html.erb b/app/views/lab_tests/_date_filter.html.erb new file mode 100644 index 0000000..5367a09 --- /dev/null +++ b/app/views/lab_tests/_date_filter.html.erb @@ -0,0 +1,25 @@ +
+ <%= form_with(url: lab_tests_path, method: :get, class: "inline-flex items-center") do |f| %> +
+ <%= t('lab_tests.lab_test_date_filter.from') %> + <%= f.date_field :start_date, + value: params[:start_date] || Rails.application.config.x.lab_test_date_range[:default_start_date].call, + min: Rails.application.config.x.lab_test_date_range[:min_date], + max: Rails.application.config.x.lab_test_date_range[:max_date], + onchange: "this.nextElementSibling.nextElementSibling.min=this.value", + class: "rounded-md border border-gray-300 py-2 px-3 mr-6", + placeholder: "mm/dd/yyyy" %> + + <%= t('lab_tests.lab_test_date_filter.to') %> + <%= f.date_field :end_date, + value: params[:end_date] || Rails.application.config.x.lab_test_date_range[:default_end_date].call, + min: params[:start_date] || Rails.application.config.x.lab_test_date_range[:min_date], + max: Rails.application.config.x.lab_test_date_range[:max_date], + class: "rounded-md border border-gray-300 py-2 px-3 mr-6", + placeholder: "mm/dd/yyyy" %> + + <%= f.submit t('lab_tests.lab_test_date_filter.filter'), + class: "primary-button" %> +
+ <% end %> +
\ No newline at end of file diff --git a/app/views/lab_tests/_no_data_placeholder.html.erb b/app/views/lab_tests/_no_data_placeholder.html.erb new file mode 100644 index 0000000..be29c31 --- /dev/null +++ b/app/views/lab_tests/_no_data_placeholder.html.erb @@ -0,0 +1,42 @@ +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+

+ <%= t('lab_tests.lab_test_no_data_placeholder.no_data_title') %> +

+ + <% if params[:start_date].present? && params[:end_date].present? %> +

+ <%= t('lab_tests.lab_test_no_data_placeholder.no_data_message_with_dates', + start_date: Date.parse(params[:start_date]).strftime("%B %d, %Y"), + end_date: Date.parse(params[:end_date]).strftime("%B %d, %Y")) %> +

+ <% else %> +

+ <%= t('lab_tests.lab_test_no_data_placeholder.no_data_message_no_dates') %> +

+ <% end %> +
+
\ No newline at end of file diff --git a/app/views/lab_tests/index.html.erb b/app/views/lab_tests/index.html.erb index 6a8c2c1..f66c0c0 100644 --- a/app/views/lab_tests/index.html.erb +++ b/app/views/lab_tests/index.html.erb @@ -8,6 +8,12 @@ data: { turbo_frame: "_top" } %> - - <%= render "index_table", recordables: @recordables, biomarkers: @biomarkers %> +
+ <%= render 'date_filter' %> +
+ <% if @recordables.present? %> + <%= render "index_table", recordables: @recordables, biomarkers: @biomarkers %> + <% else %> + <%= render 'no_data_placeholder' %> + <% end %> \ No newline at end of file diff --git a/config/application.rb b/config/application.rb index fab9667..bd8dd3f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -44,5 +44,13 @@ class Application < Rails::Application # Fixes broken tailwind.css build for CI # @see https://github.com/rails/tailwindcss-rails/issues/153#issuecomment-1225895063 config.assets.css_compressor = nil + + # Lab test date range settings + config.x.lab_test_date_range = { + min_date: '1900-01-01', + max_date: '2100-01-01', + default_start_date: -> { Time.zone.today.beginning_of_year }, + default_end_date: -> { Time.zone.today } + } end end diff --git a/config/locales/en.yml b/config/locales/en.yml index 26dac5c..bb83b18 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -62,6 +62,14 @@ en: success: "Lab test was successfully updated." destroy: success: "Lab test was successfully removed." + lab_test_date_filter: + from: "From" + to: "To" + filter: "Filter" + lab_test_no_data_placeholder: + no_data_title: "No Lab Tests Found" + no_data_message_with_dates: "No lab tests were found between %{start_date} and %{end_date}" + no_data_message_no_dates: "No lab tests have been recorded yet" admin: users: update: