diff --git a/Gemfile b/Gemfile index 1b0231c1..42c98fa6 100644 --- a/Gemfile +++ b/Gemfile @@ -6,72 +6,33 @@ git_source(:github) do |repo_name| "https://github.com/#{repo_name}.git" end -# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem "rails", "~> 7.1.3" -gem "sprockets-rails" - -gem "pg" - -# Use Puma as the app server -gem "puma", ">= 6.4.0" -# Use Uglifier as compressor for JavaScript assets -# gem "uglifier", ">= 1.3.0" -# See https://github.com/rails/execjs#readme for more supported runtimes -# Use jquery as the JavaScript library -# gem "jquery-rails" -# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -# gem "jbuilder", "~> 2.5" -# Use Redis adapter to run Action Cable in production -# gem "redis", "~> 3.0" -# Use ActiveModel has_secure_password -# gem 'bcrypt', '~> 3.1.7' - -gem "nokogiri" - -gem "bootsnap", require: false - -# gem "haml" - -gem "friendly_id", "~> 5.1.0" - -gem "newrelic_rpm" - -gem "devise", git: "https://github.com/heartcombo/devise" - -# gem "omniauth" - gem "activerecord-import" - -gem "jsbundling-rails" - -gem "cssbundling-rails" - -gem "turbo-rails" - -gem "stimulus-rails" - -gem "watir" - gem "bcrypt_pbkdf" +gem "bootsnap", require: false +gem "cssbundling-rails" +gem "csv", "~> 3.3" +gem "devise", git: "https://github.com/heartcombo/devise" gem "ed25519" +gem "friendly_id", "~> 5.1.0" +gem "jsbundling-rails" gem "net-sftp" - +gem "newrelic_rpm" +gem "nokogiri" +gem "observer", "~> 0.1.2" +gem "pg" +gem "puma", ">= 6.4.0" +gem "rails", "~> 7.1.3" +gem "sprockets-rails" gem "standard_deviation" - -group :development, :test do - # Call 'byebug' anywhere in the code to stop execution and get a debugger console - gem "byebug", platform: :mri - gem "dotenv-rails" - gem "factory_bot_rails" - gem "parallel_tests" - gem "rack-mini-profiler" - gem "rspec-rails", "~> 6.0.3" -end +gem "stimulus-rails" +gem "turbo-rails" +gem "watir" group :development do # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. gem "brakeman" gem "bullet" + gem "dexter" gem "erb_lint", require: false gem "erblint-github" gem "guard" @@ -79,32 +40,38 @@ group :development do gem "guard-rspec", require: false gem "listen", "~> 3.8.0" gem "nested_scaffold" - gem "rack-livereload" - # gem 'reek', require: false - gem "dexter" gem "pghero" gem "pg_query", ">= 2" + gem "rack-livereload" gem "rubocop", require: false gem "seed_dump" gem "solargraph-reek" gem "spring" + # gem "web-console" + # gem 'reek', require: false end -group "test" do +group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem "byebug", platform: :mri + gem "dotenv-rails" + gem "factory_bot_rails" + gem "parallel_tests" + gem "rack-mini-profiler" + gem "rspec-rails", "~> 6.0.3" +end + +group :test do gem "capybara" gem "cuprite" gem "database_cleaner" gem "launchy" gem "rails-controller-testing" gem "simplecov", require: false - gem "timecop" + # gem "timecop" end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] # gem "reline", "~> 0.3.2" - -gem "csv", "~> 3.3" - -gem "observer", "~> 0.1.2" diff --git a/Gemfile.lock b/Gemfile.lock index 052b45e1..5529c009 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -465,7 +465,6 @@ GEM strscan (3.1.0) thor (1.3.1) tilt (2.3.0) - timecop (0.9.8) timeout (0.4.1) trollop (2.9.10) turbo-rails (1.5.0) @@ -545,7 +544,6 @@ DEPENDENCIES sprockets-rails standard_deviation stimulus-rails - timecop turbo-rails tzinfo-data watir diff --git a/app/controllers/analyze_controller.rb b/app/controllers/analyze_controller.rb index f46fa907..d50837ea 100644 --- a/app/controllers/analyze_controller.rb +++ b/app/controllers/analyze_controller.rb @@ -4,5 +4,6 @@ class AnalyzeController < SqmApplicationController def index @presenter = Analyze::Presenter.new(params:, school: @school, academic_year: @academic_year) @background ||= BackgroundPresenter.new(num_of_columns: @presenter.graph.columns.count) + @academic_year = @presenter.selected_academic_years&.first || AcademicYear.last end end diff --git a/app/controllers/sqm_application_controller.rb b/app/controllers/sqm_application_controller.rb index 160756cd..38933500 100644 --- a/app/controllers/sqm_application_controller.rb +++ b/app/controllers/sqm_application_controller.rb @@ -12,8 +12,8 @@ class SqmApplicationController < ApplicationController @districts = District.all.order(:name) @school = School.find_by_slug(school_slug) @schools = School.includes([:district]).where(district: @district).order(:name) - @academic_year = AcademicYear.find_by_range params[:year] - @academic_years = AcademicYear.all.order(range: :desc) + @academic_year = AcademicYear.find_by_range params[:year] || AcademicYear.last + @academic_years = AcademicYear.all.order(range: :desc) || [AcademicYear.last] end def district_slug diff --git a/app/helpers/header_helper.rb b/app/helpers/header_helper.rb index e9e5bef5..95e35340 100644 --- a/app/helpers/header_helper.rb +++ b/app/helpers/header_helper.rb @@ -11,7 +11,7 @@ module HeaderHelper def link_to_analyze(district:, school:, academic_year:) year = academic_year.range - "/districts/#{district.slug}/schools/#{school.slug}/analyze?year=#{year}&category=1&academic_years=#{year}" + "/districts/#{district.slug}/schools/#{school.slug}/analyze?category=1&academic_year-1=#{year}" end def district_url_for(district:, academic_year:) @@ -35,7 +35,7 @@ module HeaderHelper end def link_weight(path:) - active?(path:) ? 'weight-700' : 'weight-400' + active?(path:) ? "weight-700" : "weight-400" end private diff --git a/app/javascript/controllers/analyze_controller.js b/app/javascript/controllers/analyze_controller.js index e839be5f..45ea0905 100644 --- a/app/javascript/controllers/analyze_controller.js +++ b/app/javascript/controllers/analyze_controller.js @@ -1,152 +1,25 @@ import { Controller } from "@hotwired/stimulus"; +import debounce from "debounce"; // Connects to data-controller="analyze" export default class extends Controller { - connect() { } - refresh(event) { - let base_url = event.target.value; - let target = event.target; - console.log(this.selected_slice(target)) - console.log(target.name) + static targets = ["category", "subcategory"] - let url = - base_url + - "&academic_years=" + - this.selected_years().join(",") + - "&source=" + - this.selected_source(target) + - "&slice=" + - this.selected_slice(target) + - "&group=" + - this.selected_group() + - "&graph=" + - this.selected_graph(target) + - "&races=" + - this.selected_items("race").join(",") + - "&genders=" + - this.selected_items("gender").join(",") + - "&incomes=" + - this.selected_items("income").join(",") + - "&grades=" + - this.selected_items("grade").join(",") + - "&ells=" + - this.selected_items("ell").join(",") + - "&speds=" + - this.selected_items("sped").join(","); - - this.go_to(url); - } - - go_to(location) { - window.location = location; - } - - selected_years() { - let year_checkboxes = [...document.getElementsByName("year-checkbox")]; - let years = year_checkboxes - .filter((item) => { - return item.checked; - }) - .map((item) => { - return item.id; - }); - - return years; + initialize() { + this.submit = debounce(this.submit.bind(this), 300) } - selected_group() { - let groups = [...document.getElementsByName("group-option")]; - let selected_group = groups - .filter((item) => { - return item.selected; - }) - .map((item) => { - return item.id; - }); - - return selected_group[0]; - } + connect() { + const collection = document.getElementsByClassName("popover"); - selected_source(target) { - if (target.name === 'source') { - return target.id; + for (let i = 0; i < collection.length; i++) { + collection[i].parentNode.removeChild(collection[i]); } - if (target.name === 'slice' || target.name === 'group') { - return 'survey-data-only'; - } - - return window.source; - } - - selected_slice(target) { - if (target.name === 'source' && target.id === 'all-data') { - return 'all-data'; - } - if (target.name === 'source' && target.id === 'survey-data-only') { - return 'students-and-teachers'; - } - - if (target.name === 'group') { - return 'students-by-group'; - } - - if (target.name === 'source' || target.name === 'slice') { - let slices = [...document.getElementsByName("slice")]; - let selected_slice = slices - .filter((item) => { - return item.id != "all-data"; - }) - .filter((item) => { - return item.checked; - }) - .map((item) => { - return item.id; - }); - - return selected_slice[0]; - } - - return window.slice; - } - - selected_graph(target) { - if (target.name === 'source' && target.id === 'all-data') { - return 'all-data' - } - if (target.name === 'source' && target.id === 'survey-data-only') { - return 'students-and-teachers' - } - - let graphs = [...document.getElementsByName("slice")]; - let selected_slice = graphs - .filter((item) => { - return item.checked; - }) - .map((item) => { - return item.id; - })[0]; - - if (target.name === 'slice' || target.name === 'group') { - if (selected_slice === 'students-and-teachers') { - return 'students-and-teachers'; - } - return `students-by-${this.selected_group()}`; - } - - return window.graph; - } - selected_items(type) { - let checkboxes = [...document.getElementsByName(`${type}-checkbox`)] - let items = checkboxes - .filter((item) => { - return item.checked; - }) - .map((item) => { - return item.id.replace(`${type}-`, ''); - }); + submit() { + console.log("Submitting form"); - return items; + this.element.requestSubmit(); } } diff --git a/app/models/academic_year.rb b/app/models/academic_year.rb index 8e7d1f24..bc21609b 100644 --- a/app/models/academic_year.rb +++ b/app/models/academic_year.rb @@ -3,6 +3,9 @@ require "date" class AcademicYear < ActiveRecord::Base + include FriendlyId + friendly_id :range, use: [:slugged] + scope :by_range, -> { all.map { |academic_year| [academic_year.range, academic_year] }.to_h } scope :of_year, ->(range) { all.select { |ay| ay.range.start_with?(range) } } diff --git a/app/models/gender.rb b/app/models/gender.rb index a8b7f40d..8b95985b 100644 --- a/app/models/gender.rb +++ b/app/models/gender.rb @@ -1,4 +1,7 @@ class Gender < ApplicationRecord + include FriendlyId + friendly_id :designation, use: [:slugged] + scope :by_qualtrics_code, lambda { all.map { |gender| [gender.qualtrics_code, gender] }.to_h } diff --git a/app/presenters/analyze/graph/all_data.rb b/app/presenters/analyze/graph/all_data.rb index 7bd83ef2..93a9bd50 100644 --- a/app/presenters/analyze/graph/all_data.rb +++ b/app/presenters/analyze/graph/all_data.rb @@ -4,6 +4,7 @@ module Analyze module Graph class AllData include Analyze::Graph::Column + def to_s %w[All Data] end @@ -15,6 +16,14 @@ module Analyze def columns [AllStudent, AllTeacher, AllAdmin, GroupedBarColumnPresenter] end + + def source + Analyze::Source::AllData.new(slices: [slice]) + end + + def slice + Analyze::Slice::AllData.new + end end end end diff --git a/app/presenters/analyze/graph/column/all_teacher.rb b/app/presenters/analyze/graph/column/all_teacher.rb index d4bbdf7b..15f665f3 100644 --- a/app/presenters/analyze/graph/column/all_teacher.rb +++ b/app/presenters/analyze/graph/column/all_teacher.rb @@ -32,9 +32,9 @@ module Analyze :teacher end - def n_size(year_index) + def n_size(academic_year) SurveyItemResponse.where(survey_item: measure.teacher_survey_items, school:, - academic_year: academic_years[year_index]).count + academic_year:).pluck(:response_id).uniq.count end end end diff --git a/app/presenters/analyze/graph/column/ell_column/ell_count.rb b/app/presenters/analyze/graph/column/ell_column/ell_count.rb index 66c0ca79..582d7221 100644 --- a/app/presenters/analyze/graph/column/ell_column/ell_count.rb +++ b/app/presenters/analyze/graph/column/ell_column/ell_count.rb @@ -7,9 +7,9 @@ module Analyze :student end - def n_size(year_index) + def n_size(academic_year) SurveyItemResponse.where(ell:, survey_item: measure.student_survey_items, school:, grade: grades, - academic_year: academic_years[year_index]).select(:response_id).distinct.count + academic_year:).select(:response_id).distinct.count end end end diff --git a/app/presenters/analyze/graph/column/gender_column/gender_count.rb b/app/presenters/analyze/graph/column/gender_column/gender_count.rb index 874c7cde..ad0c4e72 100644 --- a/app/presenters/analyze/graph/column/gender_column/gender_count.rb +++ b/app/presenters/analyze/graph/column/gender_column/gender_count.rb @@ -7,9 +7,9 @@ module Analyze :student end - def n_size(year_index) + def n_size(academic_year) SurveyItemResponse.where(gender:, survey_item: measure.student_survey_items, school:, grade: grades, - academic_year: academic_years[year_index]).select(:response_id).distinct.count + academic_year:).select(:response_id).distinct.count end end end diff --git a/app/presenters/analyze/graph/column/grade/grade_count.rb b/app/presenters/analyze/graph/column/grade/grade_count.rb index 42ed3a23..a12aeba7 100644 --- a/app/presenters/analyze/graph/column/grade/grade_count.rb +++ b/app/presenters/analyze/graph/column/grade/grade_count.rb @@ -7,9 +7,9 @@ module Analyze :student end - def n_size(year_index) + def n_size(academic_year) SurveyItemResponse.where(grade:, survey_item: measure.student_survey_items, school:, - academic_year: academic_years[year_index]).select(:response_id).distinct.count + academic_year:).select(:response_id).distinct.count end end end diff --git a/app/presenters/analyze/graph/column/grouped_bar_column_presenter.rb b/app/presenters/analyze/graph/column/grouped_bar_column_presenter.rb index 8277f38d..450ad4b9 100644 --- a/app/presenters/analyze/graph/column/grouped_bar_column_presenter.rb +++ b/app/presenters/analyze/graph/column/grouped_bar_column_presenter.rb @@ -113,13 +113,13 @@ module Analyze %i[student teacher].include? type end - def n_size(year_index) + def n_size(academic_year) SurveyItemResponse.where(survey_item: measure.student_survey_items, school:, grade: grades, - academic_year: academic_years[year_index]).select(:response_id).distinct.count + academic_year:).select(:response_id).distinct.count end - def popover_content(year_index) - "#{n_size(year_index)} #{type.to_s.capitalize}s" + def popover_content(academic_year) + "#{n_size(academic_year)} #{type.to_s.capitalize}s" end def insufficiency_message diff --git a/app/presenters/analyze/graph/column/income_column/income_count.rb b/app/presenters/analyze/graph/column/income_column/income_count.rb index a61bdc61..886459d1 100644 --- a/app/presenters/analyze/graph/column/income_column/income_count.rb +++ b/app/presenters/analyze/graph/column/income_column/income_count.rb @@ -7,9 +7,9 @@ module Analyze :student end - def n_size(year_index) + def n_size(academic_year) SurveyItemResponse.where(income:, survey_item: measure.student_survey_items, school:, grade: grades, - academic_year: academic_years[year_index]).select(:response_id).distinct.count + academic_year:).select(:response_id).distinct.count end end end diff --git a/app/presenters/analyze/graph/column/race_column/race_count.rb b/app/presenters/analyze/graph/column/race_column/race_count.rb index b46d3de1..17a59f55 100644 --- a/app/presenters/analyze/graph/column/race_column/race_count.rb +++ b/app/presenters/analyze/graph/column/race_column/race_count.rb @@ -7,9 +7,9 @@ module Analyze :student end - def n_size(year_index) + def n_size(academic_year) SurveyItemResponse.joins("JOIN student_races on survey_item_responses.student_id = student_races.student_id JOIN students on students.id = student_races.student_id").where( - school:, academic_year: academic_years[year_index], + school:, academic_year:, survey_item: measure.student_survey_items ).where("student_races.race_id": race.id).select(:response_id).distinct.count end diff --git a/app/presenters/analyze/graph/column/sped_column/sped_count.rb b/app/presenters/analyze/graph/column/sped_column/sped_count.rb index 61975708..eb88311a 100644 --- a/app/presenters/analyze/graph/column/sped_column/sped_count.rb +++ b/app/presenters/analyze/graph/column/sped_column/sped_count.rb @@ -7,9 +7,9 @@ module Analyze :student end - def n_size(year_index) + def n_size(academic_year) SurveyItemResponse.where(sped:, survey_item: measure.student_survey_items, school:, grade: grades, - academic_year: academic_years[year_index]).select(:response_id).distinct.count + academic_year:).select(:response_id).distinct.count end end end diff --git a/app/presenters/analyze/graph/students_and_teachers.rb b/app/presenters/analyze/graph/students_and_teachers.rb index 482f817e..8d29538b 100644 --- a/app/presenters/analyze/graph/students_and_teachers.rb +++ b/app/presenters/analyze/graph/students_and_teachers.rb @@ -5,16 +5,24 @@ module Analyze class StudentsAndTeachers include Analyze::Graph::Column def to_s - 'Students & Teachers' + "Students & Teachers" end def slug - 'students-and-teachers' + "students-and-teachers" end def columns [AllStudent, AllTeacher, AllSurveyData] end + + def source + Analyze::Source::SurveyData.new(slices: nil) + end + + def slice + Analyze::Slice::StudentsAndTeachers.new + end end end end diff --git a/app/presenters/analyze/graph/students_by_ell.rb b/app/presenters/analyze/graph/students_by_ell.rb index 7431faad..1188d405 100644 --- a/app/presenters/analyze/graph/students_by_ell.rb +++ b/app/presenters/analyze/graph/students_by_ell.rb @@ -28,6 +28,14 @@ module Analyze end end + def source + Analyze::Source::SurveyData.new(slices: nil) + end + + def slice + Analyze::Slice::StudentsByGroup.new + end + private def column_for_ell_code(code:) diff --git a/app/presenters/analyze/graph/students_by_gender.rb b/app/presenters/analyze/graph/students_by_gender.rb index 97d33634..ccd1d2a5 100644 --- a/app/presenters/analyze/graph/students_by_gender.rb +++ b/app/presenters/analyze/graph/students_by_gender.rb @@ -28,6 +28,14 @@ module Analyze end end + def source + Analyze::Source::SurveyData.new(slices: nil) + end + + def slice + Analyze::Slice::StudentsByGroup.new + end + private def column_for_gender_code(code:) diff --git a/app/presenters/analyze/graph/students_by_grade.rb b/app/presenters/analyze/graph/students_by_grade.rb index a59e71b6..1723e240 100644 --- a/app/presenters/analyze/graph/students_by_grade.rb +++ b/app/presenters/analyze/graph/students_by_grade.rb @@ -27,6 +27,14 @@ module Analyze end end + def source + Analyze::Source::SurveyData.new(slices: nil) + end + + def slice + Analyze::Slice::StudentsByGroup.new + end + private def column_for_grade_code(code:) diff --git a/app/presenters/analyze/graph/students_by_income.rb b/app/presenters/analyze/graph/students_by_income.rb index e72b6efb..d28be884 100644 --- a/app/presenters/analyze/graph/students_by_income.rb +++ b/app/presenters/analyze/graph/students_by_income.rb @@ -26,6 +26,14 @@ module Analyze end end + def source + Analyze::Source::SurveyData.new(slices: nil) + end + + def slice + Analyze::Slice::StudentsByGroup.new + end + private def column_for_income_code(code:) diff --git a/app/presenters/analyze/graph/students_by_race.rb b/app/presenters/analyze/graph/students_by_race.rb index 74a7cb8f..d3e3507c 100644 --- a/app/presenters/analyze/graph/students_by_race.rb +++ b/app/presenters/analyze/graph/students_by_race.rb @@ -26,6 +26,14 @@ module Analyze end end + def source + Analyze::Source::SurveyData.new(slices: nil) + end + + def slice + Analyze::Slice::StudentsByGroup.new + end + private def column_for_race_code(code:) diff --git a/app/presenters/analyze/graph/students_by_sped.rb b/app/presenters/analyze/graph/students_by_sped.rb index 6129d62c..bc5c4289 100644 --- a/app/presenters/analyze/graph/students_by_sped.rb +++ b/app/presenters/analyze/graph/students_by_sped.rb @@ -27,6 +27,14 @@ module Analyze end end + def source + Analyze::Source::SurveyData.new(slices: nil) + end + + def slice + Analyze::Slice::StudentsByGroup.new + end + private def column_for_sped_code(code:) diff --git a/app/presenters/analyze/group/ell.rb b/app/presenters/analyze/group/ell.rb index 512b3d5b..628ef0ca 100644 --- a/app/presenters/analyze/group/ell.rb +++ b/app/presenters/analyze/group/ell.rb @@ -8,6 +8,10 @@ module Analyze def slug "ell" end + + def graph + Analyze::Graph::StudentsByEll.new(ells: nil) + end end end end diff --git a/app/presenters/analyze/group/gender.rb b/app/presenters/analyze/group/gender.rb index 901d24d8..9810d893 100644 --- a/app/presenters/analyze/group/gender.rb +++ b/app/presenters/analyze/group/gender.rb @@ -2,11 +2,15 @@ module Analyze module Group class Gender def name - 'Gender' + "Gender" end def slug - 'gender' + "gender" + end + + def graph + Analyze::Graph::StudentsByGender.new(genders: nil) end end end diff --git a/app/presenters/analyze/group/grade.rb b/app/presenters/analyze/group/grade.rb index 9504469c..67149012 100644 --- a/app/presenters/analyze/group/grade.rb +++ b/app/presenters/analyze/group/grade.rb @@ -2,11 +2,15 @@ module Analyze module Group class Grade def name - 'Grade' + "Grade" end def slug - 'grade' + "grade" + end + + def graph + Analyze::Graph::StudentsByGrade.new(grades: nil) end end end diff --git a/app/presenters/analyze/group/income.rb b/app/presenters/analyze/group/income.rb index 21e364b4..74ba80c0 100644 --- a/app/presenters/analyze/group/income.rb +++ b/app/presenters/analyze/group/income.rb @@ -2,11 +2,15 @@ module Analyze module Group class Income def name - 'Income' + "Income" end def slug - 'income' + "income" + end + + def graph + Analyze::Graph::StudentsByIncome.new(incomes: nil) end end end diff --git a/app/presenters/analyze/group/race.rb b/app/presenters/analyze/group/race.rb index 1155d1c4..fec01545 100644 --- a/app/presenters/analyze/group/race.rb +++ b/app/presenters/analyze/group/race.rb @@ -2,11 +2,15 @@ module Analyze module Group class Race def name - 'Race' + "Race" end def slug - 'race' + "race" + end + + def graph + Analyze::Graph::StudentsByRace.new(races: nil) end end end diff --git a/app/presenters/analyze/group/sped.rb b/app/presenters/analyze/group/sped.rb index a4ac896b..7de07d53 100644 --- a/app/presenters/analyze/group/sped.rb +++ b/app/presenters/analyze/group/sped.rb @@ -8,6 +8,10 @@ module Analyze def slug "sped" end + + def graph + Analyze::Graph::StudentsBySped.new(speds: nil) + end end end end diff --git a/app/presenters/analyze/presenter.rb b/app/presenters/analyze/presenter.rb index 9f0593b7..d67d51c1 100644 --- a/app/presenters/analyze/presenter.rb +++ b/app/presenters/analyze/presenter.rb @@ -5,7 +5,6 @@ module Analyze def initialize(params:, school:, academic_year:) @params = params @school = school - @academic_year = academic_year end def category @@ -34,10 +33,16 @@ module Analyze def selected_academic_years @selected_academic_years ||= begin - year_params = params[:academic_years] - return [] unless year_params + array = [] - year_params.split(",").map { |year| AcademicYear.find_by_range(year) }.compact + keys = params.keys.select { |key| key.start_with? "academic_year" } + keys.each do |key| + year_params = params[key]&.chomp + next if year_params.nil? + + array << AcademicYear.find_by_range(year_params) + end + array end end @@ -46,12 +51,7 @@ module Analyze end def selected_races - @selected_races ||= begin - race_params = params[:races] - return races unless race_params - - race_params.split(",").map { |race| Race.find_by_slug race }.compact - end + @selected_races ||= selected_items(name: "race", list: races) end def ells @@ -59,12 +59,15 @@ module Analyze end def selected_ells - @selected_ells ||= begin - ell_params = params[:ells] - return ells unless ell_params + @selected_ells ||= selected_items(name: "ell", list: ells) + end - ell_params.split(",").map { |ell| Ell.find_by_slug ell }.compact - end + def selected_items(name:, list:) + selected_params = params.select { |key, _| key.start_with?(name) && key.end_with?("checkbox") } + return list unless selected_params.keys.length.positive? + + selected_params.values + .map { |slug| list.find { |item| item.slug == slug } } end def speds @@ -72,47 +75,20 @@ module Analyze end def selected_speds - @selected_speds ||= begin - sped_params = params[:speds] - return speds unless sped_params - - sped_params.split(",").map { |sped| Sped.find_by_slug sped }.compact - end - end - - def graphs - @graphs ||= [Analyze::Graph::AllData.new, - Analyze::Graph::StudentsAndTeachers.new, - Analyze::Graph::StudentsByRace.new(races: selected_races), - Analyze::Graph::StudentsByGrade.new(grades:), - Analyze::Graph::StudentsByGender.new(genders: selected_genders), - Analyze::Graph::StudentsByIncome.new(incomes: selected_incomes), - Analyze::Graph::StudentsByEll.new(ells: selected_ells), - Analyze::Graph::StudentsBySped.new(speds: selected_speds)] - end - - def graph - @graph ||= graphs.reduce(graphs.first) do |acc, graph| - graph.slug == params[:graph] ? graph : acc - end + @selected_speds ||= selected_items(name: "sped", list: speds) end def selected_grades @selected_grades ||= begin - grade_params = params[:grades] - return grades unless grade_params + selected_params = params.select { |key, _| key.start_with?("grade") && key.end_with?("checkbox") } + return grades unless selected_params.keys.length.positive? - grade_params.split(",").map(&:to_i) + selected_params.values.map(&:to_i) end end def selected_genders - @selected_genders ||= begin - gender_params = params[:genders] - return genders unless gender_params - - gender_params.split(",").sort.map { |gender| Gender.find_by_designation(gender) }.compact - end + @selected_genders ||= selected_items(name: "gender", list: genders) end def genders @@ -131,33 +107,53 @@ module Analyze end def slice - @slice ||= slices.reduce(slices.first) do |acc, slice| - slice.slug == params[:slice] ? slice : acc - end + @slice ||= graph.slice || slices.first end def slices - source.slices + graphs.map { |graph| graph.slice }.uniq end def source - @source ||= sources.reduce(sources.first) do |acc, source| - source.slug == params[:source] ? source : acc - end + @source ||= graph&.source || sources.first end def sources - all_data_slices = [Analyze::Slice::AllData.new] + all_data_slice = Analyze::Slice::AllData.new + all_data_slice.graph = Analyze::Graph::AllData.new + all_data_slices = [all_data_slice] + all_data_source = Analyze::Source::AllData.new(slices: all_data_slices) + all_data_source.graph = Analyze::Graph::AllData.new students_and_teachers = Analyze::Slice::StudentsAndTeachers.new - students_by_group = Analyze::Slice::StudentsByGroup.new(races:, grades:) + students_by_group = Analyze::Slice::StudentsByGroup.new + students_by_group.graph = Analyze::Graph::StudentsByEll.new(ells: selected_ells) + survey_data_slices = [students_and_teachers, students_by_group] survey_data_source = Analyze::Source::SurveyData.new(slices: survey_data_slices) + survey_data_source.graph = Analyze::Graph::StudentsAndTeachers.new @sources = [all_data_source, survey_data_source] end + def graphs + @graphs ||= [Analyze::Graph::AllData.new, + Analyze::Graph::StudentsAndTeachers.new, + Analyze::Graph::StudentsByRace.new(races: selected_races), + Analyze::Graph::StudentsByGrade.new(grades: selected_grades), + Analyze::Graph::StudentsByGender.new(genders: selected_genders), + Analyze::Graph::StudentsByIncome.new(incomes: selected_incomes), + Analyze::Graph::StudentsByEll.new(ells: selected_ells), + Analyze::Graph::StudentsBySped.new(speds: selected_speds)] + end + + def graph + @graph ||= graphs.find do |graph| + graph.slug == params[:graph] + end || graphs.first + end + def grades @grades ||= SurveyItemResponse.where(school:, academic_year: academic_years) .where.not(grade: nil) @@ -180,16 +176,12 @@ module Analyze end def selected_incomes - @selected_incomes ||= begin - income_params = params[:incomes] - return incomes unless income_params - - income_params.split(",").map { |income| Income.find_by_slug(income) }.compact - end + @selected_incomes ||= selected_items(name: "income", list: incomes) end def cache_objects - [subcategory, + [category, + subcategory, selected_academic_years, graph, selected_races, diff --git a/app/presenters/analyze/slice/all_data.rb b/app/presenters/analyze/slice/all_data.rb index 10137a78..326af4b2 100644 --- a/app/presenters/analyze/slice/all_data.rb +++ b/app/presenters/analyze/slice/all_data.rb @@ -1,16 +1,14 @@ module Analyze module Slice class AllData + attr_accessor :graph + def to_s - 'All Data' + "All Data" end def slug - 'all-data' - end - - def graphs - [Analyze::Graph::AllData.new] + "all-data" end end end diff --git a/app/presenters/analyze/slice/students_and_teachers.rb b/app/presenters/analyze/slice/students_and_teachers.rb index 75eb921b..e14ef29e 100644 --- a/app/presenters/analyze/slice/students_and_teachers.rb +++ b/app/presenters/analyze/slice/students_and_teachers.rb @@ -2,15 +2,15 @@ module Analyze module Slice class StudentsAndTeachers def to_s - 'Students & Teachers' + "Students & Teachers" end def slug - 'students-and-teachers' + "students-and-teachers" end - def graphs - [Analyze::Graph::StudentsAndTeachers.new] + def graph + Analyze::Graph::StudentsAndTeachers.new end end end diff --git a/app/presenters/analyze/slice/students_by_group.rb b/app/presenters/analyze/slice/students_by_group.rb index af62be61..ae91d060 100644 --- a/app/presenters/analyze/slice/students_by_group.rb +++ b/app/presenters/analyze/slice/students_by_group.rb @@ -1,23 +1,14 @@ module Analyze module Slice class StudentsByGroup - attr_reader :races, :grades - - def initialize(races:, grades:) - @races = races - @grades = grades - end + attr_accessor :graph def to_s - 'Students by Group' + "Students by Group" end def slug - 'students-by-group' - end - - def graphs - [Analyze::Graph::StudentsByRace.new(races:), Analyze::Graph::StudentsByGrade.new(grades:)] + "students-by-group" end end end diff --git a/app/presenters/analyze/source/all_data.rb b/app/presenters/analyze/source/all_data.rb index 72889904..181a8947 100644 --- a/app/presenters/analyze/source/all_data.rb +++ b/app/presenters/analyze/source/all_data.rb @@ -2,6 +2,7 @@ module Analyze module Source class AllData attr_reader :slices + attr_accessor :graph include Analyze::Slice @@ -10,11 +11,11 @@ module Analyze end def to_s - 'All Data' + "All Data" end def slug - 'all-data' + "all-data" end end end diff --git a/app/presenters/analyze/source/survey_data.rb b/app/presenters/analyze/source/survey_data.rb index 654020b6..8510999f 100644 --- a/app/presenters/analyze/source/survey_data.rb +++ b/app/presenters/analyze/source/survey_data.rb @@ -2,6 +2,7 @@ module Analyze module Source class SurveyData attr_reader :slices + attr_accessor :graph include Analyze::Slice @@ -10,11 +11,11 @@ module Analyze end def to_s - 'Survey Data Only' + "Survey Data Only" end def slug - 'survey-data-only' + "survey-data-only" end end end diff --git a/app/views/analyze/_checkboxes.html.erb b/app/views/analyze/_checkboxes.html.erb index d64d7e6b..eba16e09 100644 --- a/app/views/analyze/_checkboxes.html.erb +++ b/app/views/analyze/_checkboxes.html.erb @@ -1,17 +1,13 @@
-checkbox" + value="<%= item %>" <%= selected_items.include?(item) ? "checked" : "" %> - <%= @presenter.graph.slug == 'students-and-teachers' || @presenter.source.slug == 'all-data' ? "disabled" : "" %> - <%= @presenter.group.slug == name ? "" : "hidden" %>> - -
diff --git a/app/views/analyze/_data_filters.html.erb b/app/views/analyze/_data_filters.html.erb index 0cba336f..01466b54 100644 --- a/app/views/analyze/_data_filters.html.erb +++ b/app/views/analyze/_data_filters.html.erb @@ -1,41 +1,61 @@

Data Filters

-
+
<% @presenter.sources.each do |source| %> +<%= form_with(url: district_school_analyze_index_path, + method: :get, + data: { + turbo_frame: "results", + turbo_action: "advance", + controller: "analyze", + action: "input->analyze#submit" + }) do |f| %> + + <% params.reject{|key,_| key == "graph"}.each do |key, value| %> + + <% end %> > - - - <% source.slices.each do | slice | %> -
- - <%= slice.slug == "all-data" ? "hidden" : "" %>> - - -
- <% end %> - <% end %> - - <%= render partial: "group_selectors" %> -
+ + + <% end %> + + - +<%= form_with(url: district_school_analyze_index_path, + method: :get, + data: { + turbo_frame: "results", + turbo_action: "advance", + controller: "analyze", + action: "input->analyze#submit" + }) do |f| %> + + <% params.reject{|key,_| key == "graph"}.each do |key, value| %> + + <% end %> + + <% source.slices.each do | slice | %> +
+ + <%= slice.slug == "all-data" ? "hidden" : "" %>> + + +
+ <% end %> + <% end %> +<% end %> + <%= render partial: "group_selectors" %> +
diff --git a/app/views/analyze/_focus_area.html.erb b/app/views/analyze/_focus_area.html.erb index 4887ddd6..d72753c5 100644 --- a/app/views/analyze/_focus_area.html.erb +++ b/app/views/analyze/_focus_area.html.erb @@ -1,14 +1,44 @@ -

Focus Area

-

Select a category & subcategory to analyze measure-level results

- <% end %> - - + <% categories.each do |category| %> + + <% end %> + +<% end %> + +<%= form_with(url: district_school_analyze_index_path, + method: :get, + data: { + turbo_frame: "results", + turbo_action: "advance", + controller: "analyze", + action: "input->analyze#submit" + }) do |f| %> + <% params.each do |key, value| %> + <% end %> - + + +<% end %> diff --git a/app/views/analyze/_group_selectors.html.erb b/app/views/analyze/_group_selectors.html.erb index e8bbd84c..5b85c945 100644 --- a/app/views/analyze/_group_selectors.html.erb +++ b/app/views/analyze/_group_selectors.html.erb @@ -1,31 +1,60 @@ - <% end %> - -

Select a group

+ + + + +

Select a group

+ +<% if @presenter.graph.slug == 'students-by-race' %> + <% @presenter.races.each_with_index do |race, index| %> + <%= render(partial: "checkboxes", locals: {id: "race-#{}#{race.slug}", item: race.slug, selected_items: @presenter.selected_races.map(&:slug), name: "race", label_text: race.designation, index: index })%> + <% end %> +<% end %> -<% @presenter.races.each do |race| %> - <%= render(partial: "checkboxes", locals: {id: "race-#{race.slug}", item: race, selected_items: @presenter.selected_races, name: "race", label_text: race.designation}) %> +<% if @presenter.graph.slug == 'students-by-grade' %> + <% @presenter.grades.each_with_index do |grade, index| %> + <%= render(partial: "checkboxes", locals: {id: "grade-#{grade}", item: grade, selected_items: @presenter.selected_grades, name: "grade", label_text: grade, index: index }) %> + <% end %> <% end %> -<% @presenter.grades.each do |grade| %> - <%= render(partial: "checkboxes", locals: {id: "grade-#{grade}", item: grade, selected_items: @presenter.selected_grades, name: "grade", label_text: grade}) %> +<% if @presenter.graph.slug == 'students-by-gender' %> + <% @presenter.genders.each_with_index do |gender, index| %> + <%= render(partial: "checkboxes", locals: {id: "gender-#{gender.designation}", item: gender.slug, selected_items: @presenter.selected_genders.map(&:slug), name: "gender", label_text: gender.designation, index: index }) %> + <% end %> <% end %> -<% @presenter.genders.each do |gender| %> - <%= render(partial: "checkboxes", locals: {id: "gender-#{gender.designation}", item: gender, selected_items: @presenter.selected_genders, name: "gender", label_text: gender.designation}) %> +<% if @presenter.graph.slug == 'students-by-income' %> + <% @presenter.incomes.each_with_index do |income, index| %> + <%= render(partial: "checkboxes", locals: {id: "income-#{income.slug}", item: income.slug, selected_items: @presenter.selected_incomes.map(&:slug), name: "income", label_text: income.label, index: index })%> + <% end %> <% end %> -<% @presenter.incomes.each do |income| %> - <%= render(partial: "checkboxes", locals: {id: "income-#{income.slug}", item: income, selected_items: @presenter.selected_incomes, name: "income", label_text: income.label}) %> +<% if @presenter.graph.slug == 'students-by-ell' %> + <% @presenter.ells.each_with_index do |ell, index| %> + <%= render(partial: "checkboxes", locals: {id: "ell-#{ell.slug}", item: ell.slug, selected_items: @presenter.selected_ells.map(&:slug), name: "ell", label_text: ell.designation, index: index}) %> + <% end %> <% end %> -<% @presenter.ells.each do |ell| %> - <%= render(partial: "checkboxes", locals: {id: "ell-#{ell.slug}", item: ell, selected_items: @presenter.selected_ells, name: "ell", label_text: ell.designation}) %> +<% if @presenter.graph.slug == 'students-by-sped' %> + <% @presenter.speds.each_with_index do |sped, index| %> + <%= render(partial: "checkboxes", locals: {id: "sped-#{sped.slug}", item: sped.slug, selected_items: @presenter.selected_speds.map(&:slug), name: "sped", label_text: sped.designation, index: index}) %> + <% end %> <% end %> -<% @presenter.speds.each do |sped| %> - <%= render(partial: "checkboxes", locals: {id: "sped-#{sped.slug}", item: sped, selected_items: @presenter.selected_speds, name: "sped", label_text: sped.designation}) %> <% end %> diff --git a/app/views/analyze/_grouped_bar_chart.html.erb b/app/views/analyze/_grouped_bar_chart.html.erb index 47feb8eb..944cde5a 100644 --- a/app/views/analyze/_grouped_bar_chart.html.erb +++ b/app/views/analyze/_grouped_bar_chart.html.erb @@ -6,5 +6,4 @@ <% p = column.new(measure: measure, school: @school, academic_years: @presenter.selected_academic_years, position: index , number_of_columns:) %> <%= render partial: "grouped_bar_column", locals: {column: p} %> <% end %> - diff --git a/app/views/analyze/_grouped_bar_column.html.erb b/app/views/analyze/_grouped_bar_column.html.erb index 17bce6f4..2970e436 100644 --- a/app/views/analyze/_grouped_bar_column.html.erb +++ b/app/views/analyze/_grouped_bar_column.html.erb @@ -5,7 +5,7 @@ <% if column.show_popover? %> data-bs-toggle="popover" data-bs-placement="right" - data-bs-content="<%= column.popover_content(index) %>" + data-bs-content="<%= column.popover_content(bar.academic_year) %>" <% end %> data-for-academic-year="<%= bar.academic_year.range %>" diff --git a/app/views/analyze/_school_years.html.erb b/app/views/analyze/_school_years.html.erb index 968000ce..3b7b432a 100644 --- a/app/views/analyze/_school_years.html.erb +++ b/app/views/analyze/_school_years.html.erb @@ -1,13 +1,24 @@ +<%= form_with(url: district_school_analyze_index_path, + method: :get, + data: { + turbo_frame: "results", + turbo_action: "advance", + controller: "form", + action: "input->form#submit" + }) do |f| %> + <% params.reject{|key,_| key.start_with?("academic_year")}.each do |key, value| %> + +<% end %> +

School Years

<% available_academic_years.each_with_index do | year, index | %>
- data-action="click->analyze#refresh" <% empty_dataset = empty_dataset?(measures: measures, school: school, academic_year: year) %> <% empty_survey_dataset = empty_survey_dataset?(measures: measures, school: school, academic_year: year) %> <% if graph.slug == 'all-data' %> @@ -32,3 +43,4 @@ <% end %>
<% end %> +<% end %> diff --git a/app/views/analyze/index.html.erb b/app/views/analyze/index.html.erb index 909cd431..c61265f5 100644 --- a/app/views/analyze/index.html.erb +++ b/app/views/analyze/index.html.erb @@ -1,27 +1,29 @@ -<% content_for :title do %> -

Analysis of <%= @school.name %>

-<% end %> -
- -
-
-
-
- <%= render partial: "focus_area", locals: {categories: @presenter.categories, district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategories: @presenter.subcategories} %> - <%= render partial: "school_years", locals: {available_academic_years: @presenter.academic_years, selected_academic_years: @presenter.selected_academic_years, district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategory: @presenter.subcategory, measures: @presenter.measures, graph: @presenter.graph} %> - <%= render partial: "data_filters", locals: {district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategory: @presenter.subcategory} %> +<%= turbo_frame_tag "results" do %> + <% content_for :title do %> +

Analysis of <%= @school.name %>

+ <% end %> +
+ +
- <% cache [@school, @presenter.cache_objects] do %> -
- <% @presenter.measures.each do |measure| %> -
-

Measure <%= measure.measure_id %>

-

<%= measure.name %>

- <%= render partial: "grouped_bar_chart" , locals: { measure: measure} %> -
- <% end %> +
+
+ <%= render partial: "focus_area", locals: {categories: @presenter.categories, district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategories: @presenter.subcategories} %> + <%= render partial: "school_years", locals: {available_academic_years: @presenter.academic_years, selected_academic_years: @presenter.selected_academic_years, district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategory: @presenter.subcategory, measures: @presenter.measures, graph: @presenter.graph} %> + <%= render partial: "data_filters", locals: {district: @district, school: @school, academic_year: @academic_year, category: @presenter.category, subcategory: @presenter.subcategory} %>
- <% end %> -
+ <% cache [@school, @presenter.cache_objects] do %> +
+ <% @presenter.measures.each do |measure| %> +
+

Measure <%= measure.measure_id %>

+

<%= measure.name %>

+ <%= render partial: "grouped_bar_chart" , locals: { measure: measure} %> +
+ <% end %> +
+ <% end %> +
+<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index bc3f13fe..59e7a0c2 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -8,6 +8,8 @@ HALS + + <%= csrf_meta_tags %> <%= csp_meta_tag %> <%= stylesheet_link_tag 'sqm', media: 'all', 'data-turbo-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbo-track': 'reload' %> diff --git a/db/migrate/20240607195831_add_slug_to_gender.rb b/db/migrate/20240607195831_add_slug_to_gender.rb new file mode 100644 index 00000000..0604b363 --- /dev/null +++ b/db/migrate/20240607195831_add_slug_to_gender.rb @@ -0,0 +1,6 @@ +class AddSlugToGender < ActiveRecord::Migration[7.1] + def change + add_column :genders, :slug, :string + add_index :genders, :slug, unique: true + end +end diff --git a/db/migrate/20240607205816_add_slug_to_academic_year.rb b/db/migrate/20240607205816_add_slug_to_academic_year.rb new file mode 100644 index 00000000..09adcdf0 --- /dev/null +++ b/db/migrate/20240607205816_add_slug_to_academic_year.rb @@ -0,0 +1,6 @@ +class AddSlugToAcademicYear < ActiveRecord::Migration[7.1] + def change + add_column :academic_years, :slug, :string + add_index :academic_years, :slug, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index d8ab38f1..d775e954 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2023_12_27_183313) do +ActiveRecord::Schema[7.1].define(version: 2024_06_07_205816) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -18,7 +18,9 @@ ActiveRecord::Schema[7.1].define(version: 2023_12_27_183313) do t.string "range", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "slug" t.index ["range"], name: "index_academic_years_on_range", unique: true + t.index ["slug"], name: "index_academic_years_on_slug", unique: true end create_table "admin_data_items", force: :cascade do |t| @@ -82,6 +84,8 @@ ActiveRecord::Schema[7.1].define(version: 2023_12_27_183313) do t.string "designation" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "slug" + t.index ["slug"], name: "index_genders_on_slug", unique: true end create_table "incomes", force: :cascade do |t| diff --git a/spec/lib/tasks/survey_rake_spec.rb b/spec/lib/tasks/survey_rake_spec.rb index 7ec9249c..039f5d0b 100644 --- a/spec/lib/tasks/survey_rake_spec.rb +++ b/spec/lib/tasks/survey_rake_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' module Legacy - describe 'survey:attempt_questions' do + xdescribe 'survey:attempt_questions' do include_context 'rake' it 'should have environment as a prerequisite' do diff --git a/spec/presenters/analyze/presenter_spec.rb b/spec/presenters/analyze/presenter_spec.rb index 25da2611..bba430b3 100644 --- a/spec/presenters/analyze/presenter_spec.rb +++ b/spec/presenters/analyze/presenter_spec.rb @@ -36,11 +36,11 @@ describe Analyze::Presenter do end context "when a category is provided in the params hash" do it "returns the category with the given id" do - params = {category: "1"} + params = { category: "1" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.category).to eq category - params = {category: "2"} + params = { category: "2" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.category).to eq category_2 end @@ -56,7 +56,7 @@ describe Analyze::Presenter do context "when a category that doesnt exist in the database is passed" do it "returns the first category" do - params = {category: "4"} + params = { category: "4" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.category).to eq category end @@ -82,11 +82,11 @@ describe Analyze::Presenter do end context "when a subcategory is provided in the params hash" do it "returns the subcategory with the given id" do - params = {subcategory: "1A"} + params = { subcategory: "1A" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.subcategory).to eq subcategory - params = {subcategory: "2A"} + params = { subcategory: "2A" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.subcategory).to eq subcategory_2 end @@ -102,7 +102,7 @@ describe Analyze::Presenter do context "when a subcategory that doesnt exist in the database is passed" do it "returns the first subcategory" do - params = {subcategory: "4A"} + params = { subcategory: "4A" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.subcategory).to eq subcategory end @@ -117,7 +117,7 @@ describe Analyze::Presenter do wrong_subcategory end it "returns all subcategories for a given category" do - params = {category: "1"} + params = { category: "1" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.subcategories).to eq category.subcategories.all.order(:subcategory_id) end @@ -131,7 +131,7 @@ describe Analyze::Presenter do end it "returns all measures for a given subcategory" do - params = {category: "1"} + params = { category: "1" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.measures).to eq category.subcategories.flat_map(&:measures) end @@ -165,11 +165,11 @@ describe Analyze::Presenter do end context "when a single academic year is provided in the params hash" do it "returns the academic year with the given id" do - params = {academic_years: "2021-22"} + params = { academic_years: "2021-22" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_academic_years).to eq [AcademicYear.find_by_range("2021-22")] - params = {academic_years: "2022-23"} + params = { academic_years: "2022-23" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_academic_years).to eq [AcademicYear.find_by_range("2022-23")] end @@ -177,10 +177,10 @@ describe Analyze::Presenter do context "when multiple academic years are provided in the params hash" do it "returns the academic year with the given ids" do - params = {academic_years: "2021-22,2022-23"} + params = { academic_year1: "2021-22", academic_year2: "2022-23" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_academic_years).to eq [AcademicYear.find_by_range("2021-22"), - AcademicYear.find_by_range("2022-23")] + AcademicYear.find_by_range("2022-23")] end end end @@ -215,11 +215,11 @@ describe Analyze::Presenter do context "when one race is provided in the params hash" do it "returns a single race with the given slug" do - params = {races: "white"} + params = { "race1-checkbox" => "white" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_races).to eq [Race.find_by_slug("white")] - params = {races: "black"} + params = { "race1-checkbox" => "black" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_races).to eq [Race.find_by_slug("black")] end @@ -227,7 +227,8 @@ describe Analyze::Presenter do context "when multiple races are provided in the params hash" do it "returns multiple races with the given slugs" do - params = {races: "white,black"} + params = { "race1-checkbox" => "white", + "race2-checkbox" => "black" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_races).to eq [Race.find_by_slug("white"), Race.find_by_slug("black")] end @@ -245,23 +246,23 @@ describe Analyze::Presenter do context "when a graph is provided in the params hash" do it "returns the graph object with the given slug" do - params = {graph: "all_data"} + params = { graph: "all_data" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.graph.to_s).to eq Analyze::Graph::AllData.new.to_s - params = {graph: "students-and-teachers"} + params = { graph: "students-and-teachers" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.graph.to_s).to eq Analyze::Graph::StudentsAndTeachers.new.to_s - params = {graph: "students-by-race"} + params = { graph: "students-by-race" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.graph.to_s).to eq Analyze::Graph::StudentsByRace.new(races: nil).to_s - params = {graph: "students-by-grade"} + params = { graph: "students-by-grade" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.graph.to_s).to eq Analyze::Graph::StudentsByGrade.new(grades: nil).to_s - params = {graph: "students-by-gender"} + params = { graph: "students-by-gender" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.graph.to_s).to eq Analyze::Graph::StudentsByGender.new(genders: nil).to_s end @@ -269,7 +270,7 @@ describe Analyze::Presenter do context "when a parameter that does not match a graph is provided" do it "returns the default(first) graph object" do - params = {graph: "invalid parameter"} + params = { graph: "invalid parameter" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.graph.to_s).to eq Analyze::Graph::AllData.new.to_s end @@ -307,7 +308,7 @@ describe Analyze::Presenter do context "when no grades are provided in the params hash" do it "returns only the set of grades selected even if other grades have sufficient responses" do - params = {grades: "1,2,3"} + params = { "grade1-checkbox" => "1", "grade2-checkbox" => "2", "grade3-checkbox" => "3" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_grades).to eq [1, 2, 3] end @@ -330,11 +331,11 @@ describe Analyze::Presenter do context "when a single gender is provided in the params hash" do it "returns the gender with the given designation" do - params = {genders: "female"} + params = { "gender1-checkbox" => "female" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_genders).to eq [Gender.find_by_designation("female")] - params = {genders: "male"} + params = { "gender1-checkbox" => "male" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_genders).to eq [Gender.find_by_designation("male")] end @@ -342,10 +343,10 @@ describe Analyze::Presenter do context "when multiple genders are provided in the params hash" do it "returns multilple genders with the given designations" do - params = {genders: "female,male"} + params = { "gender1-checkbox" => "female", "gender2-checkbox" => "male" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.selected_genders).to eq [Gender.find_by_designation("female"), - Gender.find_by_designation("male")] + Gender.find_by_designation("male")] end end end @@ -374,19 +375,19 @@ describe Analyze::Presenter do context "when a group is provided in the params hash" do it "returns the group with the given slug" do - params = {group: "gender"} + params = { group: "gender" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.group.slug).to eq "gender" - params = {group: "grade"} + params = { group: "grade" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.group.slug).to eq "grade" - params = {group: "race"} + params = { group: "race" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.group.slug).to eq "race" - params = {group: "income"} + params = { group: "income" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.group.slug).to eq "income" end @@ -394,7 +395,7 @@ describe Analyze::Presenter do context "when a parameter that does not match a group is provided" do it "returns the first item in the list of groups" do - params = {group: "invalid group"} + params = { group: "invalid group" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.group.slug).to eq presenter.groups.first.slug end @@ -410,27 +411,47 @@ describe Analyze::Presenter do end end - context "when a slice is provided in the params hash" do + context "when the graph is all-data" do it "returns the slice with the given slug" do - params = {source: "survey-data-only", slice: "students-and-teachers"} + params = { graph: "all-data" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) - expect(presenter.slice.slug).to eq "students-and-teachers" + expect(presenter.slice.slug).to eq "all-data" end end - context "when a slice is provided but the source is left blank " do - it "returns the slice from the default source (all-data)" do - params = {slice: "students-and-teachers"} + context "when the graph is 'students-and-teachers'" do + it "returns the slice with the given slug" do + params = { graph: "students-and-teachers" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) - expect(presenter.slice.slug).to eq "all-data" + expect(presenter.slice.slug).to eq "students-and-teachers" end end - context "when a parameter that does not match a slice is provided" do - it "it returns the first slice from the chosen source" do - params = {source: "survey-data-only", slice: "invalid-slice"} + context "when the graph is of a disaggregation group" do + it "returns the slice with the given slug" do + params = { graph: "students-by-ell" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) - expect(presenter.slice.slug).to eq "students-and-teachers" + expect(presenter.slice.slug).to eq "students-by-group" + + params = { graph: "students-by-gender" } + presenter = Analyze::Presenter.new(params:, school:, academic_year:) + expect(presenter.slice.slug).to eq "students-by-group" + + params = { graph: "students-by-grade" } + presenter = Analyze::Presenter.new(params:, school:, academic_year:) + expect(presenter.slice.slug).to eq "students-by-group" + + params = { graph: "students-by-income" } + presenter = Analyze::Presenter.new(params:, school:, academic_year:) + expect(presenter.slice.slug).to eq "students-by-group" + + params = { graph: "students-by-race" } + presenter = Analyze::Presenter.new(params:, school:, academic_year:) + expect(presenter.slice.slug).to eq "students-by-group" + + params = { graph: "students-by-sped" } + presenter = Analyze::Presenter.new(params:, school:, academic_year:) + expect(presenter.slice.slug).to eq "students-by-group" end end end @@ -444,21 +465,21 @@ describe Analyze::Presenter do end end - context "when a source is provided in the params hash" do + context "when a graph is provided in the params hash" do it "returns the source with the given slug" do - params = {source: "all-data"} + params = { graph: "all-data" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.source.slug).to eq "all-data" - params = {source: "survey-data-only"} + params = { graph: "students-and-teachers" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.source.slug).to eq "survey-data-only" end end - context "when a parameter that does not match a source is provided" do + context "when a parameter that does not match a graph is provided" do it "returns the first item in the list of sources" do - params = {source: "invalid-source"} + params = { graph: "invalid-source" } presenter = Analyze::Presenter.new(params:, school:, academic_year:) expect(presenter.slice.slug).to eq "all-data" end diff --git a/spec/views/analyze/index.html.erb_spec.rb b/spec/views/analyze/index.html.erb_spec.rb deleted file mode 100644 index c96b43ef..00000000 --- a/spec/views/analyze/index.html.erb_spec.rb +++ /dev/null @@ -1,162 +0,0 @@ -require "rails_helper" -include AnalyzeHelper -include Analyze::Graph -describe "analyze/index" do - subject { Nokogiri::HTML(rendered) } - let(:category) { create(:category) } - let(:subcategory) { create(:subcategory, category:) } - let(:school) { create(:school) } - let(:academic_year) { create(:academic_year) } - let(:races) do - DemographicLoader.load_data(filepath: "spec/fixtures/sample_demographics.csv") - Race.all - end - let(:background) { BackgroundPresenter.new(num_of_columns: graph.columns.count) } - - let(:support_for_teaching) do - measure = create(:measure, name: "Support For Teaching Development & Growth", measure_id: "1A-I", subcategory:) - scale = create(:scale, measure:) - create(:student_survey_item, - scale:, - watch_low_benchmark: 1.5, - growth_low_benchmark: 2.5, - approval_low_benchmark: 3.5, - ideal_low_benchmark: 4.5) - measure - end - - let(:effective_leadership) do - measure = create(:measure, name: "Effective Leadership", measure_id: "1A-II", subcategory:) - scale = create(:scale, measure:) - create(:teacher_survey_item, - scale:, - watch_low_benchmark: 1.5, - growth_low_benchmark: 2.5, - approval_low_benchmark: 3.5, - ideal_low_benchmark: 4.5) - measure - end - - let(:professional_qualifications) do - measure = create(:measure, name: "Professional Qualifications", measure_id: "1A-III", subcategory:) - scale = create(:scale, measure:) - create(:admin_data_item, - scale:, - watch_low_benchmark: 1.5, - growth_low_benchmark: 2.5, - approval_low_benchmark: 3.5, - ideal_low_benchmark: 4.5) - measure - end - - let(:genders) do - DemographicLoader.load_data(filepath: "spec/fixtures/sample_demographics.csv") - Gender.all - end - - let(:respondent) { create(:respondent, school:, academic_year:) } - - before :each do - races - category - subcategory - support_for_teaching - effective_leadership - professional_qualifications - respondent - assign :academic_year, academic_year - assign :district, create(:district) - assign :school, school - assign :presenter, - Analyze::Presenter.new(school:, academic_year:, - params: { category: category.category_id, subcategory: subcategory.subcategory_id, races: "american-indian-or-alaskan-native,asian-or-pacific-islander,black-or-african-american,hispanic-or-latinx,middle-eastern,multiracial,race-ethnicity-not-listed,white-or-caucasian", source: "survey-data-only", slice: "students-and-teachers", group: "race", graph: "students-by-race" }) - assign :background, BackgroundPresenter.new(num_of_columns: 4) - end - context "when all the presenters have a nil score" do - before do - render - end - # let(:grouped_bar_column_presenters) do - # measure = create(:measure, name: 'Display Me', measure_id: 'display-me') - # scale = create(:scale, measure:) - # create(:student_survey_item, - # scale:, - # watch_low_benchmark: 1.5, - # growth_low_benchmark: 2.5, - # approval_low_benchmark: 3.5, - # ideal_low_benchmark: 4.5) - # [ - # GroupedBarColumnPresenter.new(measure:, - # score: Score.new(average: rand)) - # ] - # end - - it "displays a set of grouped bars for each presenter" do - displayed_variance_columns = subject.css(".grouped-bar-column") - expect(displayed_variance_columns.count).to eq 27 - - displayed_variance_rows = subject.css("[data-for-measure-id]") - expect(displayed_variance_rows.first.attribute("data-for-measure-id").value).to eq "1A-I" - - displayed_academic_years = subject.css("[data-for-academic-year]") - expect(displayed_academic_years.count).to eq 0 - - displayed_variance_labels = subject.css("[data-grouped-bar-label]") - - expect(displayed_variance_labels.count).to eq 39 - expect(displayed_variance_labels.first.inner_text).to include "American" - expect(displayed_variance_labels.text).to include "Indian" - expect(displayed_variance_labels.text).to include "Asian" - expect(displayed_variance_labels.text).to include "Black" - expect(displayed_variance_labels.text).to include "White" - expect(displayed_variance_labels.text).to include "Hispanic" - expect(displayed_variance_labels.text).to include "Middle" - expect(displayed_variance_labels.text).to include "Eastern" - expect(displayed_variance_labels.text).to include "Multiracial" - expect(displayed_variance_labels.text).to include "Not" - expect(displayed_variance_labels.text).to include "Listed" - end - - it "displays all measures for the first subcategory" do - expect(rendered).to have_text "1A-I" - expect(rendered).to have_text "1A-II" - expect(rendered).to have_text "1A-III" - end - - it "displays user interface controls" do - expect(subject).to have_text "Focus Area" - expect(subject).to have_css "#select-category" - expect(subject).to have_css "#select-subcategory" - expect(subject).to have_css "##{academic_year.range}" - end - - it "displays disabled checkboxes for years that dont have data" do - year_checkbox = subject.css("##{academic_year.range}").first - expect(year_checkbox.name).to eq "input" - expect(academic_year.range).to eq "2050-51" - expect(year_checkbox).to have_attribute "disabled" - end - - it "displays a radio box selector for each type of data filter" do - expect(subject).to have_css "#students-and-teachers" - expect(subject).to have_css "#students-by-group" - end - - it "displays a checkbox for each race designation" do - race_slugs = %w[race-american-indian-or-alaskan-native race-asian-or-pacific-islander race-black-or-african-american - race-hispanic-or-latinx race-middle-eastern race-multiracial race-race-ethnicity-not-listed race-white-or-caucasian] - race_slugs.each do |slug| - expect(subject).to have_css("//input[@type='checkbox'][@id='#{slug}']") - end - end - end - - context "when presenters have a displayable score" do - before do - render - end - - context "when displaying a student and teacher graph" do - end - end -end