diff --git a/.prettierrc.json b/.prettierrc.json
new file mode 100644
index 00000000..0967ef42
--- /dev/null
+++ b/.prettierrc.json
@@ -0,0 +1 @@
+{}
diff --git a/.rubocop.yml b/.rubocop.yml
index 73e129f9..341ce7e0 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -10,5 +10,3 @@ Metrics/ClassLength:
Style/Documentation:
Enabled: false
-
-
diff --git a/app/controllers/analyze_controller.rb b/app/controllers/analyze_controller.rb
index ba321deb..1248a388 100644
--- a/app/controllers/analyze_controller.rb
+++ b/app/controllers/analyze_controller.rb
@@ -2,7 +2,7 @@
class AnalyzeController < SqmApplicationController
before_action :assign_categories, :assign_subcategories, :assign_measures, :assign_academic_years,
- :response_rate_timestamp, only: [:index]
+ :response_rate_timestamp, :races, :selected_races, :graph, :graphs, only: [:index]
def index; end
private
@@ -45,4 +45,31 @@ class AnalyzeController < SqmApplicationController
end
@response_rate_timestamp
end
+
+ def races
+ @races ||= Race.all.order(designation: :ASC)
+ end
+
+ def selected_races
+ @selected_races ||= begin
+ race_params = params[:races]
+ return @selected_races = races unless race_params
+
+ race_list = race_params.split(',') if race_params
+ if race_list
+ race_list = race_list.map do |race|
+ Race.find_by_slug race
+ end
+ end
+ race_list
+ end
+ end
+
+ def graph
+ @graph ||= params[:graph] || 'students-and-teachers'
+ end
+
+ def graphs
+ @graphs ||= [AnalysisGraph::StudentsAndTeachers.new, AnalysisGraph::StudentsByGroup.new]
+ end
end
diff --git a/app/helpers/analyze_helper.rb b/app/helpers/analyze_helper.rb
index be6df60f..de725518 100644
--- a/app/helpers/analyze_helper.rb
+++ b/app/helpers/analyze_helper.rb
@@ -84,4 +84,9 @@ module AnalyzeHelper
@empty_dataset[[school, academic_year]]
end
+
+ def base_url
+ analyze_subcategory_link(district: @district, school: @school, academic_year: @academic_year, category: @category,
+ subcategory: @subcategory)
+ end
end
diff --git a/app/javascript/controllers/.eslintrc.bak b/app/javascript/controllers/.eslintrc.bak
new file mode 100644
index 00000000..b36ffeaa
--- /dev/null
+++ b/app/javascript/controllers/.eslintrc.bak
@@ -0,0 +1,6 @@
+{
+ "parserOptions": {
+ "sourceType": "module",
+ "ecmaVersion": 2020
+ }
+}
diff --git a/app/javascript/controllers/.eslintrc.json b/app/javascript/controllers/.eslintrc.json
new file mode 100644
index 00000000..b36ffeaa
--- /dev/null
+++ b/app/javascript/controllers/.eslintrc.json
@@ -0,0 +1,6 @@
+{
+ "parserOptions": {
+ "sourceType": "module",
+ "ecmaVersion": 2020
+ }
+}
diff --git a/app/javascript/controllers/analyze_controller.js b/app/javascript/controllers/analyze_controller.js
index e4c08675..4efa653b 100644
--- a/app/javascript/controllers/analyze_controller.js
+++ b/app/javascript/controllers/analyze_controller.js
@@ -2,18 +2,63 @@ import { Controller } from "@hotwired/stimulus";
// Connects to data-controller="analyze"
export default class extends Controller {
- connect() {}
+ connect() { }
refresh(event) {
- let location = event.target.value;
+ let base_url = event.target.value;
+
+ let url =
+ base_url +
+ "&academic_years=" +
+ this.selected_years().join(",") +
+ "&graph=" +
+ this.selected_graph() +
+ "&races=" +
+ this.selected_races().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;
+ });
- let selected_years = year_checkboxes
+ return years;
+ }
+
+ selected_graph() {
+ let graphs = [...document.getElementsByName("graph")];
+ let selected_graph = graphs
+ .filter((item) => {
+ return item.checked;
+ })
+ .map((item) => {
+ return item.id;
+ });
+
+ return selected_graph[0];
+ }
+
+ selected_races() {
+ let race_checkboxes = [...document.getElementsByName("race-checkbox")]
+ let races = race_checkboxes
.filter((item) => {
return item.checked;
})
.map((item) => {
return item.id;
});
- window.location = location + "&academic_years=" + selected_years.join(",");
+
+ return races;
}
}
diff --git a/app/lib/seeder.rb b/app/lib/seeder.rb
index b2143397..c9461f34 100644
--- a/app/lib/seeder.rb
+++ b/app/lib/seeder.rb
@@ -139,6 +139,10 @@ class Seeder
end
end
+ def seed_demographics(csv_file)
+ DemographicLoader.load_data(filepath: csv_file)
+ end
+
private
def marked?(mark)
diff --git a/app/models/academic_year.rb b/app/models/academic_year.rb
index f4f4464a..121ed671 100644
--- a/app/models/academic_year.rb
+++ b/app/models/academic_year.rb
@@ -2,18 +2,23 @@
class AcademicYear < ActiveRecord::Base
def self.find_by_date(date)
- if date.month > 6
- ay_range_start = date.year
- ay_range_end = date.year + 1
- else
- ay_range_start = date.year - 1
- ay_range_end = date.year
- end
- AcademicYear.find_by_range("#{ay_range_start}-#{ay_range_end.to_s[2, 3]}")
+ year = parse_year_range(date:)
+ AcademicYear.find_by_range("#{year.start}-#{year.end.to_s[2, 3]}")
end
def formatted_range
years = range.split('-')
"#{years.first} – 20#{years.second}"
end
+
+ def self.parse_year_range(date:)
+ year = date.year
+ if date.month > 6
+ AcademicYearRange.new(year, year + 1)
+ else
+ AcademicYearRange.new(year - 1, year)
+ end
+ end
end
+
+AcademicYearRange = Struct.new(:start, :end)
diff --git a/app/models/admin_data_value.rb b/app/models/admin_data_value.rb
index 9329b875..145bba5e 100644
--- a/app/models/admin_data_value.rb
+++ b/app/models/admin_data_value.rb
@@ -4,4 +4,5 @@ class AdminDataValue < ApplicationRecord
belongs_to :school
belongs_to :admin_data_item
belongs_to :academic_year
+ validates :likert_score, numericality: { greater_than: 0, less_than_or_equal_to: 5 }
end
diff --git a/app/models/analysis_graph/students_and_teachers.rb b/app/models/analysis_graph/students_and_teachers.rb
new file mode 100644
index 00000000..4453eccd
--- /dev/null
+++ b/app/models/analysis_graph/students_and_teachers.rb
@@ -0,0 +1,11 @@
+module AnalysisGraph
+ class StudentsAndTeachers
+ def to_s
+ 'Students & Teachers'
+ end
+
+ def value
+ 'students-and-teachers'
+ end
+ end
+end
diff --git a/app/models/analysis_graph/students_by_group.rb b/app/models/analysis_graph/students_by_group.rb
new file mode 100644
index 00000000..468230b0
--- /dev/null
+++ b/app/models/analysis_graph/students_by_group.rb
@@ -0,0 +1,11 @@
+module AnalysisGraph
+ class StudentsByGroup
+ def to_s
+ 'Students by Group'
+ end
+
+ def value
+ 'students-by-group'
+ end
+ end
+end
diff --git a/app/models/race.rb b/app/models/race.rb
new file mode 100644
index 00000000..f5deadc9
--- /dev/null
+++ b/app/models/race.rb
@@ -0,0 +1,4 @@
+class Race < ApplicationRecord
+ include FriendlyId
+ friendly_id :designation, use: [:slugged]
+end
diff --git a/app/services/demographic_loader.rb b/app/services/demographic_loader.rb
new file mode 100644
index 00000000..b31db34e
--- /dev/null
+++ b/app/services/demographic_loader.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'csv'
+
+class DemographicLoader
+ def self.load_data(filepath:)
+ CSV.parse(File.read(filepath), headers: true) do |row|
+ qualtrics_code = row['Race Qualtrics Code'].to_i
+ designation = row['Race/Ethnicity']
+ next unless qualtrics_code && designation
+
+ if qualtrics_code.between?(6, 7)
+ UnknownRace.new(qualtrics_code:, designation:)
+ else
+ KnownRace.new(qualtrics_code:, designation:)
+ end
+ end
+ end
+end
+
+class KnownRace
+ def initialize(qualtrics_code:, designation:)
+ Race.find_or_create_by!(qualtrics_code:, designation:)
+ end
+end
+
+class UnknownRace
+ def initialize(qualtrics_code:, designation:)
+ Race.find_or_create_by!(qualtrics_code: 99, designation: 'Unknown')
+ end
+end
diff --git a/app/views/analyze/_data_filters.html.erb b/app/views/analyze/_data_filters.html.erb
new file mode 100644
index 00000000..2c71dc43
--- /dev/null
+++ b/app/views/analyze/_data_filters.html.erb
@@ -0,0 +1,28 @@
+
+
diff --git a/app/views/analyze/_focus_area.html.erb b/app/views/analyze/_focus_area.html.erb
new file mode 100644
index 00000000..9f4ae569
--- /dev/null
+++ b/app/views/analyze/_focus_area.html.erb
@@ -0,0 +1,14 @@
+
+Select a category & subcategory to analyze measure-level results
+
+
diff --git a/app/views/analyze/_graph_background.html.erb b/app/views/analyze/_graph_background.html.erb
new file mode 100644
index 00000000..2f93116e
--- /dev/null
+++ b/app/views/analyze/_graph_background.html.erb
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/analyze/_grouped_bar_chart.html.erb b/app/views/analyze/_grouped_bar_chart.html.erb
index acfe5e10..0741d155 100644
--- a/app/views/analyze/_grouped_bar_chart.html.erb
+++ b/app/views/analyze/_grouped_bar_chart.html.erb
@@ -1,37 +1,7 @@
-