diff --git a/app/components/common_components/organization_statistics.rb b/app/components/common_components/organization_statistics.rb
index 7fcf85346..95ef624b2 100644
--- a/app/components/common_components/organization_statistics.rb
+++ b/app/components/common_components/organization_statistics.rb
@@ -2,23 +2,32 @@ class CommonComponents::OrganizationStatistics < ViewComponent::Base
include ApplicationHelper
include CollectionHelper
- def initialize(group_lesson_summaries, selected_date = Time.zone.today)
- @lesson_summaries = group_lesson_summaries
+ # rubocop:disable Metrics/ParameterLists
+ def initialize(lesson_summaries, number_of_lessons:, total_data_points:, selected_date:, available_lesson_dates: [], used_default_date: false)
+ @lesson_summaries = lesson_summaries
+ @number_of_lessons = number_of_lessons
+ @total_data_points = total_data_points
@selected_date = selected_date
- @number_of_lessons = @lesson_summaries.count
- @total_data_points = @lesson_summaries.sum(&:grade_count)
+ @available_lesson_dates = available_lesson_dates
+ @used_default_date = used_default_date
end
+ # rubocop:enable Metrics/ParameterLists
erb_template <<~ERB
>
+
<% if @enabled_dates %> data-datepicker-enabled-dates-value='<%= @enabled_dates.to_json %>'<% end %>>
<% if @form %>
<%= @form.text_field @target, data: { 'datepicker-target' => 'picker' },
class: @custom_class || 'rounded-md border-purple-500 text-sm focus:border-green-600 focus:outline-hidden focus:ring-green-600', autocomplete: 'disabled' %>
@@ -15,11 +15,14 @@ class Datepicker < ViewComponent::Base
ERB
- def initialize(date:, target:, form: nil, custom_name: nil, custom_class: nil)
+ # rubocop:disable Metrics/ParameterLists
+ def initialize(date:, target:, form: nil, custom_name: nil, custom_class: nil, enabled_dates: nil)
@date = date
@target = target
@form = form
@custom_name = custom_name
@custom_class = custom_class
+ @enabled_dates = enabled_dates
end
+ # rubocop:enable Metrics/ParameterLists
end
diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb
index f695b6d9b..f2b858e89 100644
--- a/app/controllers/organizations_controller.rb
+++ b/app/controllers/organizations_controller.rb
@@ -118,8 +118,7 @@ def initialize_organization(id)
@new_member = User.new
@roles = Role::LOCAL_ROLES.keys
- @selected_date = params[:selected_date] || Time.zone.today
- @lesson_summaries = GroupLessonSummary.where(chapter_id: @organization.chapters, lesson_date: @selected_date)
+ populate_lesson_activity
end
def chapter_order_scope
@@ -171,6 +170,16 @@ def undelete
private
+ def populate_lesson_activity
+ lesson_summaries_for_organization = GroupLessonSummary.where(chapter_id: @organization.chapters)
+ @available_lesson_dates = lesson_summaries_for_organization.distinct.pluck(:lesson_date).sort
+ @used_default_date = params[:selected_date].blank?
+ @selected_date = params[:selected_date].presence || @available_lesson_dates.last || Time.zone.today
+ @lesson_summaries = lesson_summaries_for_organization.where(lesson_date: @selected_date).to_a
+ @number_of_lessons = @lesson_summaries.count
+ @total_data_points = @lesson_summaries.sum(&:grade_count)
+ end
+
def file_is_csv?(content_type)
%w[text/csv text/x-csv application/vnd.ms-excel application/csv application/x-csv].include? content_type
end
diff --git a/app/javascript/controllers/datepicker_controller.js b/app/javascript/controllers/datepicker_controller.js
index 6c4f25459..63b2251cd 100644
--- a/app/javascript/controllers/datepicker_controller.js
+++ b/app/javascript/controllers/datepicker_controller.js
@@ -3,7 +3,7 @@ import * as pikaday from 'pikaday'
// Connects to data-controller="datepicker"
export default class extends Controller {
- static values = { date: String }
+ static values = { date: String, enabledDates: Array }
static targets = [ "picker", "anchor" ]
updateFilter() {
@@ -19,16 +19,18 @@ export default class extends Controller {
}
connect() {
+ const formatDate = (date) => {
+ const parts = [date.getFullYear(), ('0'+(date.getMonth()+1)).slice(-2), ('0'+date.getDate()).slice(-2)];
+ return parts.join("-");
+ }
+ const enabledDates = this.hasEnabledDatesValue ? new Set(this.enabledDatesValue) : null
+
const picker = new Pikaday({
field: this.pickerTarget,
minDate: new Date(Date.parse('1970-01-01')),
maxDate: new Date(),
format: 'YYYY-MM-DD',
- toString(date, format) {
- // showing the date here in the format defined above
- const parts = [date.getFullYear(), ('0'+(date.getMonth()+1)).slice(-2), ('0'+date.getDate()).slice(-2)];
- return parts.join("-");
- },
+ toString: formatDate,
parse(dateString, format) {
// dateString is the result of the `toString` method
const parts = dateString.split('-');
@@ -36,7 +38,8 @@ export default class extends Controller {
const month = parseInt(parts[1]) - 1;
const day = parseInt(parts[2]);
return new Date(year, month, day);
- }
+ },
+ disableDayFn: enabledDates ? (date) => !enabledDates.has(formatDate(date)) : undefined
});
}
}
diff --git a/app/views/organizations/show.html.erb b/app/views/organizations/show.html.erb
index 9d490c4bb..a1676987e 100644
--- a/app/views/organizations/show.html.erb
+++ b/app/views/organizations/show.html.erb
@@ -31,10 +31,10 @@ end %>
<% end %>
<% end %>
<% end %>
- <%= render CommonComponents::Card.new(title: "Statistics".capitalize) do |card| %>
+ <%= render CommonComponents::Card.new(title: t(:lesson_activity)) do |card| %>
<% card.with_card_content do %>
- <%= render CommonComponents::OrganizationStatistics.new(@lesson_summaries, @selected_date) %>
+ <%= render CommonComponents::OrganizationStatistics.new(@lesson_summaries, number_of_lessons: @number_of_lessons, total_data_points: @total_data_points, selected_date: @selected_date, available_lesson_dates: @available_lesson_dates, used_default_date: @used_default_date) %>
<% end %>
<% end %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 83b1a7f19..1e112cdbf 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -395,6 +395,9 @@ en:
groups_with_lessons: Groups with Lessons
performance_change: Performance change
+ lesson_activity: Lesson Activity
+ showing_data_for_last_lessons: Showing data for last lessons
+ no_lessons_data_exists: No lessons data exists
nr_of_lessons: Nr. of Lessons
nr_of_assessments: Nr. of Assessments
nr_of_graded_students: Nr. of Graded students
diff --git a/spec/features/organization_features_spec.rb b/spec/features/organization_features_spec.rb
index fcae57eb8..f85f27265 100644
--- a/spec/features/organization_features_spec.rb
+++ b/spec/features/organization_features_spec.rb
@@ -48,17 +48,9 @@
end
end
- it 'does not display the organization\'s statistics when there is no data' do
- expect(page).to have_content 'No data for the selected date'
- expect(page).to have_content 'Statistics'
- end
-
- it 'does display the organization\'s statistics when there is data' do
- expect(page).to have_content 'Statistics'
-
- fill_in 'select_date', with: @lesson.date
- click_link 'Filter'
-
+ it 'defaults to the most recent lesson date and shows lesson activity immediately' do
+ expect(page).to have_content 'Lesson Activity'
+ expect(page).to have_content 'Showing data for last lessons'
expect(page).to have_content 'Nr. of Lessons'
expect(page).to have_content 'Nr. of Assessments'
expect(page).to have_content 'Groups with Lessons'
@@ -69,6 +61,25 @@
expect(statistic_components[1]).to have_content 3
expect(statistic_components[2]).to have_content @groups.first.group_chapter_name
end
+
+ it 'shows a clear message when the selected date has no lesson data' do
+ empty_date = @lesson.date - 100
+
+ visit organization_path(@organization, selected_date: empty_date)
+
+ expect(page).to have_content 'No lessons data exists'
+ expect(page).not_to have_content 'Showing data for last lessons'
+ end
+
+ it 'still shows lesson activity when explicitly filtering to a date with data' do
+ fill_in 'select_date', with: @lesson.date
+ click_link 'Filter'
+
+ expect(page).to have_content 'Nr. of Lessons'
+ expect(page).to have_content 'Nr. of Assessments'
+ expect(page).to have_content 'Groups with Lessons'
+ expect(page).not_to have_content 'Showing data for last lessons'
+ end
end
describe 'Adding members to organization' do