Skip to content

Commit

Permalink
feat: highlight students with differentiation rubrics in strand assse…
Browse files Browse the repository at this point in the history
…ssment tab

- added `check_diff_rubrics_for_strand_id` opt in `Schools.list_students/1`
  • Loading branch information
endoooo committed Jan 23, 2024
1 parent b5a8ad5 commit 7479dea
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 32 deletions.
1 change: 1 addition & 0 deletions lib/lanttern/learning_context/strand.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ defmodule Lanttern.LearningContext.Strand do
field :is_starred, :boolean, virtual: true

has_many :activities, Lanttern.LearningContext.Activity
has_many :assessment_points, Lanttern.Assessments.AssessmentPoint

many_to_many :subjects, Lanttern.Taxonomy.Subject,
join_through: "strands_subjects",
Expand Down
3 changes: 1 addition & 2 deletions lib/lanttern/rubrics/rubric.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ defmodule Lanttern.Rubrics.Rubric do
has_many :assessment_points, Lanttern.Assessments.AssessmentPoint

many_to_many :students, Lanttern.Schools.Student,
join_through: "differentiation_rubrics_students",
on_replace: :delete
join_through: "differentiation_rubrics_students"

timestamps()
end
Expand Down
52 changes: 39 additions & 13 deletions lib/lanttern/schools.ex
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ defmodule Lanttern.Schools do
`:preloads` – preloads associated data
`:classes_ids` – filter students by provided list of ids
`:check_diff_rubrics_for_strand_id` - used to check if student has any differentiation rubric for given strand id
## Examples
Expand All @@ -389,24 +390,49 @@ defmodule Lanttern.Schools do
"""
def list_students(opts \\ []) do
Student
|> maybe_filter_students_by_class(opts)
from(
s in Student,
order_by: s.name
)
|> filter_students(opts)
|> load_has_diff_rubric_flag(Keyword.get(opts, :check_diff_rubrics_for_strand_id))
|> Repo.all()
|> maybe_preload(opts)
end

defp maybe_filter_students_by_class(student_query, opts) do
case Keyword.get(opts, :classes_ids) do
nil ->
student_query
defp filter_students(queryable, opts),
do: Enum.reduce(opts, queryable, &apply_students_filter/2)

classes_ids ->
from(
s in student_query,
join: c in assoc(s, :classes),
where: c.id in ^classes_ids
)
end
defp apply_students_filter({:classes_ids, ids}, queryable) do
from(
s in queryable,
join: c in assoc(s, :classes),
where: c.id in ^ids
)
end

defp apply_students_filter(_, queryable), do: queryable

defp load_has_diff_rubric_flag(queryable, nil), do: queryable

defp load_has_diff_rubric_flag(queryable, strand_id) do
has_diff_query =
from(
s in Student,
left_join: dr in assoc(s, :diff_rubrics),
left_join: r in assoc(dr, :parent_rubric),
left_join: ap in Lanttern.Assessments.AssessmentPoint,
on: ap.rubric_id == r.id and ap.strand_id == ^strand_id,
group_by: s.id,
select: %{student_id: s.id, has_diff_rubric: count(ap) > 0}
)

from(
s in queryable,
join: d in subquery(has_diff_query),
on: d.student_id == s.id,
select: %{s | has_diff_rubric: d.has_diff_rubric}
)
end

@doc """
Expand Down
4 changes: 4 additions & 0 deletions lib/lanttern/schools/student.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule Lanttern.Schools.Student do
schema "students" do
field :name, :string
field :classes_ids, {:array, :id}, virtual: true
field :has_diff_rubric, :boolean, virtual: true, default: false

belongs_to :school, Lanttern.Schools.School

Expand All @@ -16,6 +17,9 @@ defmodule Lanttern.Schools.Student do
on_replace: :delete,
preload_order: [asc: :name]

many_to_many :diff_rubrics, Lanttern.Rubrics.Rubric,
join_through: "differentiation_rubrics_students"

timestamps()
end

Expand Down
4 changes: 2 additions & 2 deletions lib/lanttern_web/live/pages/strands/id/strand_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ defmodule LantternWeb.StrandLive do
# prevent user from navigating directly to nested views

defp maybe_redirect(%{assigns: %{live_action: live_action}} = socket, params)
when live_action in [:manage_rubric, :diff_rubric],
when live_action in [:manage_rubric],
do: redirect(socket, to: ~p"/strands/#{params["id"]}?tab=assessment")

defp maybe_redirect(socket, _params), do: socket
Expand Down Expand Up @@ -69,7 +69,7 @@ defmodule LantternWeb.StrandLive do
do: assign(socket, :current_tab, Map.get(@tabs, tab, :about))

defp set_current_tab(socket, _params, live_action)
when live_action in [:manage_rubric, :diff_rubric],
when live_action in [:manage_rubric],
do: assign(socket, :current_tab, :assessment)

defp set_current_tab(socket, _params, _live_action),
Expand Down
26 changes: 13 additions & 13 deletions lib/lanttern_web/live/pages/strands/id/strand_live.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@
>
About
</:tab>
<:tab
patch={~p"/strands/#{@strand}?#{%{tab: "activities"}}"}
is_current={@current_tab == :activities && "true"}
>
Activities
</:tab>
<:tab
patch={~p"/strands/#{@strand}?#{%{tab: "assessment"}}"}
is_current={@current_tab == :assessment && "true"}
>
Assessment
</:tab>
<:tab
patch={~p"/strands/#{@strand}?#{%{tab: "activities"}}"}
is_current={@current_tab == :activities && "true"}
>
Activities
</:tab>
<:tab
patch={~p"/strands/#{@strand}?#{%{tab: "notes"}}"}
is_current={@current_tab == :notes && "true"}
Expand Down Expand Up @@ -71,13 +71,6 @@
strand={@strand}
live_action={@live_action}
/>
<.live_component
:if={@current_tab == :activities}
module={ActivitiesComponent}
id="strand-details-activities"
strand={@strand}
live_action={@live_action}
/>
<.live_component
:if={@current_tab == :assessment}
module={AssessmentComponent}
Expand All @@ -87,6 +80,13 @@
current_user={@current_user}
live_action={@live_action}
/>
<.live_component
:if={@current_tab == :activities}
module={ActivitiesComponent}
id="strand-details-activities"
strand={@strand}
live_action={@live_action}
/>
<.live_component
:if={@current_tab == :notes}
module={NotesComponent}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ defmodule LantternWeb.StrandLive.StrandRubricsComponent do
container_selector="#differentiation-rubrics-section"
on_click={JS.push("load_diff_rubrics", value: %{student_id: student.id})}
phx-target={@myself}
theme={if student.has_diff_rubric, do: "cyan", else: "subtle"}
/>
</div>
<div
Expand Down Expand Up @@ -294,7 +295,10 @@ defmodule LantternWeb.StrandLive.StrandRubricsComponent do
|> assign_new(:students, fn ->
case assigns.params do
%{"classes_ids" => classes_ids} when is_list(classes_ids) and classes_ids != [] ->
Schools.list_students(classes_ids: classes_ids)
Schools.list_students(
classes_ids: classes_ids,
check_diff_rubrics_for_strand_id: strand.id
)

_ ->
[]
Expand Down
1 change: 0 additions & 1 deletion lib/lanttern_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ defmodule LantternWeb.Router do
live "/strands/:id/goal/edit", StrandLive, :edit_goal
live "/strands/:id/new_activity", StrandLive, :new_activity
live "/strands/:id/rubric/manage", StrandLive, :manage_rubric
live "/strands/:id/rubric/differentiation", StrandLive, :diff_rubric
live "/strands/activity/:id", ActivityLive, :show
live "/strands/activity/:id/edit", ActivityLive, :edit

Expand Down
45 changes: 45 additions & 0 deletions test/lanttern/schools_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,51 @@ defmodule Lanttern.SchoolsTest do
end
end

test "list_students/1 with diff rubrics opts returns all students as expected" do
student_1 = student_fixture(%{name: "AAA"})
student_2 = student_fixture(%{name: "BBB"})

strand = Lanttern.LearningContextFixtures.strand_fixture()
scale = Lanttern.GradingFixtures.scale_fixture()
parent_rubric = Lanttern.RubricsFixtures.rubric_fixture(%{scale_id: scale.id})

Lanttern.Rubrics.create_diff_rubric_for_student(student_1.id, %{
criteria: "diff rubric for std 1",
scale_id: scale.id,
diff_for_rubric_id: parent_rubric.id
})

Lanttern.AssessmentsFixtures.assessment_point_fixture(%{
strand_id: strand.id,
rubric_id: parent_rubric.id
})

# other rubrics for testing
other_strand = Lanttern.LearningContextFixtures.strand_fixture()
other_parent_rubric = Lanttern.RubricsFixtures.rubric_fixture(%{scale_id: scale.id})

Lanttern.Rubrics.create_diff_rubric_for_student(student_2.id, %{
criteria: "diff rubric for std 2",
scale_id: scale.id,
diff_for_rubric_id: other_parent_rubric.id
})

Lanttern.AssessmentsFixtures.assessment_point_fixture(%{
strand_id: other_strand.id,
rubric_id: other_parent_rubric.id
})

# assert
[expected_1, expected_2] =
Schools.list_students(check_diff_rubrics_for_strand_id: strand.id)

assert expected_1.id == student_1.id
assert expected_1.has_diff_rubric

assert expected_2.id == student_2.id
assert !expected_2.has_diff_rubric
end

test "get_student/2 returns the student with given id" do
student = student_fixture()
assert Schools.get_student(student.id) == student
Expand Down

0 comments on commit 7479dea

Please sign in to comment.