@@ -297,7 +189,9 @@ defmodule OliWeb.Delivery.OpenAndFreeIndex do
@impl Phoenix.LiveView
def handle_event("search_section", %{"text_search" => text_search}, socket) do
{:noreply,
- push_patch(socket, to: ~p"/sections?#{%{socket.assigns.params | text_search: text_search}}")}
+ push_patch(socket,
+ to: ~p"/sections/workspace/student?#{%{socket.assigns.params | text_search: text_search}}"
+ )}
end
defp add_user_role([], _user), do: []
@@ -334,10 +228,7 @@ defmodule OliWeb.Delivery.OpenAndFreeIndex do
end)
end
- defp filter_by_role(sections, :instructor_workspace),
- do: Enum.filter(sections, fn s -> s.user_role == "instructor" end)
-
- defp filter_by_role(sections, :student_workspace),
+ defp filter_by_role(sections, :student),
do: Enum.filter(sections, fn s -> s.user_role == "student" end)
defp maybe_filter_by_text(sections, nil), do: sections
@@ -360,24 +251,6 @@ defmodule OliWeb.Delivery.OpenAndFreeIndex do
end)
end
- _docp =
- """
- Returns true if in any of the sections the user has "instructor" role.
- We do not want to show the role badge for students.
- """
-
- defp show_role_badges([]), do: false
-
- defp show_role_badges(sections) do
- Enum.reduce_while(sections, false, fn section, acc ->
- if section.user_role == "instructor" do
- {:halt, true}
- else
- {:cont, acc}
- end
- end)
- end
-
defp get_course_url(%{user_role: "student", slug: slug}, sidebar_expanded),
do: ~p"/sections/#{slug}?#{%{sidebar_expanded: sidebar_expanded}}"
@@ -390,14 +263,7 @@ defmodule OliWeb.Delivery.OpenAndFreeIndex do
%{
text_search: Params.get_param(params, "text_search", @default_params.text_search),
sidebar_expanded:
- Params.get_boolean_param(params, "sidebar_expanded", @default_params.sidebar_expanded),
- active_workspace:
- Params.get_atom_param(
- params,
- "active_workspace",
- [:course_author_workspace, :instructor_workspace, :student_workspace],
- @default_params.active_workspace
- )
+ Params.get_boolean_param(params, "sidebar_expanded", @default_params.sidebar_expanded)
}
end
diff --git a/lib/oli_web/live_session_plugs/require_enrollment.ex b/lib/oli_web/live_session_plugs/require_enrollment.ex
index 81db115f6ac..28b72850119 100644
--- a/lib/oli_web/live_session_plugs/require_enrollment.ex
+++ b/lib/oli_web/live_session_plugs/require_enrollment.ex
@@ -26,7 +26,7 @@ defmodule OliWeb.LiveSessionPlugs.RequireEnrollment do
{:halt,
socket
|> put_flash(:error, "You are not enrolled in this course")
- |> redirect(to: ~p"/sections")}
+ |> redirect(to: ~p"/sections/workspace/student")}
end
end
end
diff --git a/lib/oli_web/live_session_plugs/set_section.ex b/lib/oli_web/live_session_plugs/set_section.ex
index 08b21d10608..cd137b67568 100644
--- a/lib/oli_web/live_session_plugs/set_section.ex
+++ b/lib/oli_web/live_session_plugs/set_section.ex
@@ -12,7 +12,7 @@ defmodule OliWeb.LiveSessionPlugs.SetSection do
{:halt,
socket
|> put_flash(:error, "Section not found")
- |> push_navigate(to: ~p"/sections")}
+ |> push_navigate(to: ~p"/sections/workspace/student")}
section ->
section =
diff --git a/lib/oli_web/pow/user_routes.ex b/lib/oli_web/pow/user_routes.ex
index c53d14945c3..7abab87f0e4 100644
--- a/lib/oli_web/pow/user_routes.ex
+++ b/lib/oli_web/pow/user_routes.ex
@@ -9,7 +9,7 @@ defmodule OliWeb.Pow.UserRoutes do
alias Oli.Delivery.Sections.Section
@impl true
- def after_sign_in_path(conn) do
+ def after_sign_in_path(conn, target_workspace \\ :instructor_workspace) do
conn
|> request_path_or(
case conn.params do
@@ -17,11 +17,17 @@ defmodule OliWeb.Pow.UserRoutes do
Routes.delivery_path(conn, :show_enroll, section_slug)
_ ->
- Routes.live_path(conn, OliWeb.Delivery.OpenAndFreeIndex)
+ worskpace_path(conn, target_workspace)
end
)
end
+ defp worskpace_path(conn, :instructor_workspace),
+ do: Routes.live_path(conn, OliWeb.Workspace.Instructor)
+
+ defp worskpace_path(conn, :student_workspace),
+ do: Routes.live_path(conn, OliWeb.Workspace.Student)
+
@impl true
def after_registration_path(conn) do
conn
@@ -48,7 +54,7 @@ defmodule OliWeb.Pow.UserRoutes do
|> request_path_or(
case conn.assigns[:current_user] do
%User{independent_learner: true} ->
- Routes.live_path(conn, OliWeb.Delivery.OpenAndFreeIndex)
+ Routes.live_path(conn, OliWeb.Workspace.Student)
_ ->
Routes.delivery_path(conn, :index)
diff --git a/lib/oli_web/router.ex b/lib/oli_web/router.ex
index 4c49798c55b..1f371f6d81e 100644
--- a/lib/oli_web/router.ex
+++ b/lib/oli_web/router.ex
@@ -785,15 +785,45 @@ defmodule OliWeb.Router do
# Section Routes
###
- ### Sections - View Public Open and Free Courses
- scope "/sections", OliWeb do
+ ### Sections - Workspaces
+ scope "/sections/workspace/", OliWeb do
pipe_through([
:browser,
:delivery_protected,
+ :set_sidebar,
:pow_email_layout
])
- live("/", Delivery.OpenAndFreeIndex)
+ live_session :delivery_workspace,
+ root_layout: {OliWeb.LayoutView, :delivery},
+ layout: {OliWeb.Layouts, :workspace},
+ on_mount: [
+ OliWeb.LiveSessionPlugs.SetUser,
+ OliWeb.LiveSessionPlugs.SetSidebar,
+ OliWeb.LiveSessionPlugs.SetPreviewMode
+ ] do
+ live("/instructor", Workspace.Instructor)
+ live("/student", Workspace.Student)
+ end
+ end
+
+ scope "/sections/workspace/", OliWeb do
+ pipe_through([
+ :browser,
+ :set_sidebar,
+ :authoring_protected
+ ])
+
+ live_session :authoring_workspace,
+ root_layout: {OliWeb.LayoutView, :delivery},
+ layout: {OliWeb.Layouts, :workspace},
+ on_mount: [
+ OliWeb.LiveSessionPlugs.SetUser,
+ OliWeb.LiveSessionPlugs.SetSidebar,
+ OliWeb.LiveSessionPlugs.SetPreviewMode
+ ] do
+ live("/course_author", Workspace.CourseAuthor)
+ end
end
scope "/sections", OliWeb do
diff --git a/lib/oli_web/templates/cognito/create_prompt.html.eex b/lib/oli_web/templates/cognito/create_prompt.html.eex
index 58ea351d305..0afd2b23530 100644
--- a/lib/oli_web/templates/cognito/create_prompt.html.eex
+++ b/lib/oli_web/templates/cognito/create_prompt.html.eex
@@ -6,7 +6,7 @@
Would you like to
<%= link "create a new section with this lesson", to: @create_section_url %>
- or <%= link "go to my existing sections", to: Routes.live_path(@conn, OliWeb.Delivery.OpenAndFreeIndex) %>?
+ or <%= link "go to my existing sections", to: Routes.live_path(@conn, OliWeb.Workspace.Instructor) %>?
diff --git a/test/oli_web/controllers/cognito_controller_test.exs b/test/oli_web/controllers/cognito_controller_test.exs
index 73a2bc8d858..8ef9929ccd7 100644
--- a/test/oli_web/controllers/cognito_controller_test.exs
+++ b/test/oli_web/controllers/cognito_controller_test.exs
@@ -50,7 +50,7 @@ defmodule OliWeb.CognitoControllerTest do
assert conn
|> get(Routes.cognito_path(conn, :index, params))
|> html_response(302) =~
- "You are being
redirected."
+ "You are being
redirected."
end
test "creates new user and author, sends author setup email and redirects user to my courses",
@@ -71,7 +71,7 @@ defmodule OliWeb.CognitoControllerTest do
assert conn
|> get(Routes.cognito_path(conn, :index, params))
|> html_response(302) =~
- "You are being
redirected."
+ "You are being
redirected."
{:ok, claims} = Joken.peek_claims(id_token)
user = Accounts.get_user_by(email: email)
@@ -119,7 +119,7 @@ defmodule OliWeb.CognitoControllerTest do
assert conn
|> get(Routes.cognito_path(conn, :index, params))
|> html_response(302) =~
- "You are being
redirected."
+ "You are being
redirected."
{:ok, claims} = Joken.peek_claims(id_token)
user = Accounts.get_user_by(email: email)
@@ -712,7 +712,7 @@ defmodule OliWeb.CognitoControllerTest do
assert html =~
"Would you like to\n
create a new section with this lesson"
- assert html =~ "
go to my existing sections"
+ assert html =~ "
go to my existing sections"
end
end
diff --git a/test/oli_web/controllers/static_page_controller_test.exs b/test/oli_web/controllers/static_page_controller_test.exs
index 2acc24337fd..2b9a05190f2 100644
--- a/test/oli_web/controllers/static_page_controller_test.exs
+++ b/test/oli_web/controllers/static_page_controller_test.exs
@@ -97,7 +97,7 @@ defmodule OliWeb.StaticPageControllerTest do
test "updates the user timezone preference and redirects correctly", context do
{:ok, conn: conn, user: user} = user_conn(context)
new_timezone = "America/Montevideo"
- redirect_to = ~p"/sections"
+ redirect_to = ~p"/sections/workspace/student"
conn =
post(conn, Routes.static_page_path(conn, :update_timezone), %{
diff --git a/test/oli_web/live/delivery/open_and_free_index_test.exs b/test/oli_web/live/delivery/open_and_free_index_test.exs
deleted file mode 100644
index 472f2b96c29..00000000000
--- a/test/oli_web/live/delivery/open_and_free_index_test.exs
+++ /dev/null
@@ -1,539 +0,0 @@
-defmodule OliWeb.Delivery.OpenAndFreeIndexTest do
- use ExUnit.Case, async: true
- use OliWeb.ConnCase
-
- import Phoenix.LiveViewTest
- import Oli.Factory
-
- alias Lti_1p3.Tool.ContextRoles
- alias Oli.Delivery.Sections
- alias Oli.Accounts
- alias OliWeb.Pow.UserContext
-
- describe "user cannot access when is not logged in" do
- test "redirects to new session", %{
- conn: conn
- } do
- redirect_path = "/session/new?request_path=%2Fsections"
-
- {:error, {:redirect, %{to: ^redirect_path}}} = live(conn, ~p"/sections")
- end
- end
-
- describe "user" do
- setup [:user_conn]
-
- #### Student Workspace ####
- test "can access student workspace when logged in", %{conn: conn} do
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert has_element?(view, "h3", "Courses available")
- assert has_element?(view, "p", "You are not enrolled in any courses.")
- end
-
- test "can access student workspace when not enrolled to any section", %{conn: conn} do
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert has_element?(view, "p", "You are not enrolled in any courses.")
- end
-
- test "cannot access student workspace when locked", %{conn: conn, user: user} do
- UserContext.lock(user)
-
- {:error,
- {:redirect,
- %{
- to: "/session/new",
- flash: %{"error" => "Sorry, your account is locked. Please contact support."}
- }}} = live(conn, ~p"/sections")
- end
-
- test "can access student workspace when is unlocked after being locked", %{
- conn: conn,
- user: user
- } do
- # Lock the user
- {:ok, date, _timezone} = DateTime.from_iso8601("2019-05-22 20:30:00Z")
- {:ok, user} = Accounts.update_user(user, %{locked_at: date})
-
- # Unlock the user
- UserContext.unlock(user)
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert has_element?(view, "h3", "Courses available")
- assert has_element?(view, "p", "You are not enrolled in any courses.")
- end
-
- test "can see product title, image and description in sections index with a link to access to it in the student workspace",
- %{
- conn: conn,
- user: user
- } do
- section =
- insert(:section, %{
- open_and_free: true,
- cover_image: "https://example.com/some-image-url.png",
- description: "This is a description",
- title: "The best course ever!"
- })
-
- Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_learner)])
-
- {:ok, view, _html} =
- live(conn, ~p"/sections?active_workspace=student_workspace&sidebar_expanded=true")
-
- assert render(view) =~
- ~s|style=\"background-image: url('https://example.com/some-image-url.png');\"|
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, ~s{a[href="/sections/#{section.slug}?sidebar_expanded=true"]})
- end
-
- test "if no cover image is set, renders default image in enrollment page in the student workspace",
- %{
- conn: conn,
- user: user
- } do
- section = insert(:section, %{open_and_free: true})
-
- Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_learner)])
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert render(view) =~
- ~s|style=\"background-image: url('/images/course_default.png');\"|
- end
-
- test "can search by course name in student workspace", %{conn: conn, user: user} do
- section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
- section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
-
- Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_learner)])
- Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_learner)])
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "best"})
-
- assert has_element?(view, "h5", "The best course ever!")
- refute has_element?(view, "h5", "Maths")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: ""})
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "a not existing course"})
-
- refute has_element?(view, "h5", "The best course ever!")
- refute has_element?(view, "h5", "Maths")
- end
-
- test "can search by instructor name in student workspace", %{conn: conn, user: user} do
- section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
- section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
- section_3 = insert(:section, %{open_and_free: true, title: "Elixir"})
-
- instructor_1 = insert(:user, %{name: "Lionel Messi"})
- instructor_2 = insert(:user, %{name: "Angel Di Maria"})
-
- Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_learner)])
- Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_learner)])
- Sections.enroll(user.id, section_3.id, [ContextRoles.get_role(:context_learner)])
-
- Sections.enroll(instructor_1.id, section_1.id, [ContextRoles.get_role(:context_instructor)])
- Sections.enroll(instructor_1.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
-
- Sections.enroll(instructor_2.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
- Sections.enroll(instructor_2.id, section_3.id, [ContextRoles.get_role(:context_instructor)])
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
- assert has_element?(view, "h5", "Elixir")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "messi"})
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
- refute has_element?(view, "h5", "Elixir")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "maria"})
-
- refute has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
- assert has_element?(view, "h5", "Elixir")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "a not existing instructor"})
-
- refute has_element?(view, "h5", "The best course ever!")
- refute has_element?(view, "h5", "Maths")
- refute has_element?(view, "h5", "Elixir")
- end
-
- test "only sees sections enrolled as student on student workspace", %{conn: conn, user: user} do
- section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
- section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
-
- Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_learner)])
- Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert has_element?(view, "h5", "The best course ever!")
- refute has_element?(view, "h5", "Maths")
- end
-
- #### Instructor Workspace ####
-
- test "can access instructor workspace when logged in", %{conn: conn} do
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=instructor_workspace")
-
- assert has_element?(view, "h1", "Instructor Dashboard")
- assert has_element?(view, "p", "You are not enrolled in any courses as an instructor.")
- end
-
- test "can see product title, image and description in sections index with a link to manage it on instructor workspace",
- %{
- conn: conn,
- user: user
- } do
- section =
- insert(:section, %{
- open_and_free: true,
- cover_image: "https://example.com/some-image-url.png",
- description: "This is a description",
- title: "The best course ever!"
- })
-
- Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_instructor)])
-
- {:ok, view, _html} =
- live(conn, ~p"/sections?active_workspace=instructor_workspace&sidebar_expanded=true")
-
- assert render(view) =~
- ~s|style=\"background-image: url('https://example.com/some-image-url.png');\"|
-
- assert has_element?(view, "h5", "The best course ever!")
-
- assert has_element?(
- view,
- ~s{a[href="/sections/#{section.slug}/instructor_dashboard/manage?sidebar_expanded=true"]}
- )
- end
-
- test "if no cover image is set, renders default image in enrollment page on instructor workspace",
- %{
- conn: conn,
- user: user
- } do
- section = insert(:section, %{open_and_free: true})
-
- Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_learner)])
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert render(view) =~
- ~s|style=\"background-image: url('/images/course_default.png');\"|
- end
-
- test "can search by course name in instructor workspace", %{conn: conn, user: user} do
- section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
- section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
-
- Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_instructor)])
- Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=instructor_workspace")
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "best"})
-
- assert has_element?(view, "h5", "The best course ever!")
- refute has_element?(view, "h5", "Maths")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: ""})
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "a not existing course"})
-
- refute has_element?(view, "h5", "The best course ever!")
- refute has_element?(view, "h5", "Maths")
- end
-
- test "can search by instructor name in instructor workspace", %{conn: conn, user: user} do
- section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
- section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
- section_3 = insert(:section, %{open_and_free: true, title: "Elixir"})
-
- instructor_1 = insert(:user, %{name: "Lionel Messi"})
- instructor_2 = insert(:user, %{name: "Angel Di Maria"})
-
- Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_instructor)])
- Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
- Sections.enroll(user.id, section_3.id, [ContextRoles.get_role(:context_instructor)])
-
- Sections.enroll(instructor_1.id, section_1.id, [ContextRoles.get_role(:context_instructor)])
- Sections.enroll(instructor_1.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
-
- Sections.enroll(instructor_2.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
- Sections.enroll(instructor_2.id, section_3.id, [ContextRoles.get_role(:context_instructor)])
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=instructor_workspace")
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
- assert has_element?(view, "h5", "Elixir")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "messi"})
-
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
- refute has_element?(view, "h5", "Elixir")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "maria"})
-
- refute has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
- assert has_element?(view, "h5", "Elixir")
-
- view
- |> form("form[phx-change=search_section]")
- |> render_change(%{text_search: "a not existing instructor"})
-
- refute has_element?(view, "h5", "The best course ever!")
- refute has_element?(view, "h5", "Maths")
- refute has_element?(view, "h5", "Elixir")
- end
-
- test "only sees sections enrolled as instructor on instructor workspace", %{
- conn: conn,
- user: user
- } do
- section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
- section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
-
- Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_learner)])
- Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
-
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=instructor_workspace")
-
- refute has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, "h5", "Maths")
- end
-
- test "can not create sections on instructor worskpace when logged in as student", %{
- conn: conn
- } do
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=instructor_workspace")
-
- assert has_element?(
- view,
- "div[role='create section instructions']",
- "To create course sections,"
- )
-
- assert has_element?(
- view,
- "div[role='create section instructions'] button[onclick='window.showHelpModal();']",
- "contact support."
- )
-
- assert has_element?(view, "a[href='#']", "Create New Section")
- end
-
- test "can navigate between the different workspaces through the left navbar", %{
- conn: conn
- } do
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=student_workspace")
-
- assert has_element?(
- view,
- "a[href='/authoring/projects?active_workspace=course_author_workspace&sidebar_expanded=true']",
- "Course Author"
- )
-
- assert has_element?(
- view,
- "a[href='/sections?active_workspace=instructor_workspace&sidebar_expanded=true']",
- "Instructor"
- )
-
- assert has_element?(
- view,
- "a[href='/sections?active_workspace=student_workspace&sidebar_expanded=true']",
- "Student"
- )
-
- # we are currently on the student workspace
- refute has_element?(view, "h1", "Instructor Dashboard")
- assert has_element?(view, "h3", "Courses available")
-
- # we go to the instructor workspace
- view
- |> element(~s{nav[id=desktop-workspace-nav-menu] a}, "Instructor")
- |> render_click()
-
- assert_redirected(
- view,
- ~p"/sections?active_workspace=instructor_workspace&sidebar_expanded=true"
- )
-
- {:ok, view, _html} =
- live(conn, ~p"/sections?active_workspace=instructor_workspace&sidebar_expanded=true")
-
- assert has_element?(view, "h1", "Instructor Dashboard")
- refute has_element?(view, "h3", "Courses available")
-
- # we go back to the student workspace
- view
- |> element(~s{nav[id=desktop-workspace-nav-menu] a}, "Student")
- |> render_click()
-
- assert_redirected(
- view,
- ~p"/sections?active_workspace=student_workspace&sidebar_expanded=true"
- )
-
- {:ok, view, _html} =
- live(conn, ~p"/sections?active_workspace=student_workspace&sidebar_expanded=true")
-
- refute has_element?(view, "h1", "Instructor Dashboard")
- assert has_element?(view, "h3", "Courses available")
-
- # we go to the course author workspace
- view
- |> element(~s{nav[id=desktop-workspace-nav-menu] a}, "Course Author")
- |> render_click()
-
- assert_redirected(
- view,
- ~p"/authoring/projects?active_workspace=course_author_workspace&sidebar_expanded=true"
- )
- end
-
- test "can see expanded/collapsed sidebar nav", %{
- conn: conn
- } do
- {:ok, view, _html} = live(conn, ~p"/sections")
-
- assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=true]})
-
- labels = ["Course Author", "Instructor", "Student"]
-
- Enum.each(labels, fn label ->
- assert view
- |> element(~s{nav[id=desktop-workspace-nav-menu]})
- |> render() =~ label
- end)
-
- {:ok, view, _html} = live(conn, ~p"/sections?sidebar_expanded=false")
-
- assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=false]})
-
- Enum.each(labels, fn label ->
- refute view
- |> element(~s{nav[id=desktop-workspace-nav-menu]})
- |> render() =~ label
- end)
- end
-
- test "navbar expanded or collapsed state is kept after navigating to other menu link", %{
- conn: conn
- } do
- {:ok, view, _html} = live(conn, ~p"/sections?sidebar_expanded=true")
-
- assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=true]})
-
- view
- |> element(~s{nav[id=desktop-workspace-nav-menu] a}, "Student")
- |> render_click()
-
- assert_redirect(view, "/sections?active_workspace=student_workspace&sidebar_expanded=true")
-
- {:ok, view, _html} = live(conn, ~p"/sections?sidebar_expanded=false")
-
- assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=false]})
-
- view
- |> element(~s{nav[id=desktop-workspace-nav-menu] a[id="student_workspace_nav_link"]})
- |> render_click()
-
- assert_redirect(view, "/sections?active_workspace=student_workspace&sidebar_expanded=false")
- end
-
- test "if user is only a student, display student workspace with hidden sidebar",
- %{
- conn: conn,
- user: user
- } do
- section = insert(:section, %{open_and_free: true, title: "The best course ever!"})
- Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_learner)])
-
- {:ok, view, _html} = live(conn, ~p"/sections")
-
- assert has_element?(view, "h3", "Courses available")
- assert has_element?(view, "h5", "The best course ever!")
- assert has_element?(view, ~s{a[href="/sections/#{section.slug}?sidebar_expanded=false"]})
-
- assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=false]})
- end
- end
-
- describe "user as instructor" do
- setup [:instructor_conn]
-
- #### Instructor Workspace ####
-
- test "can create sections on instructor worskpace when logged in", %{
- conn: conn
- } do
- {:ok, view, _html} = live(conn, ~p"/sections?active_workspace=instructor_workspace")
-
- refute has_element?(
- view,
- "div[role='create section instructions']",
- "To create course sections,"
- )
-
- refute has_element?(
- view,
- "div[role='create section instructions'] button[onclick='window.showHelpModal();']",
- "contact support."
- )
-
- assert has_element?(view, "a[href='/sections/independent/create']", "Create New Section")
- end
- end
-end
diff --git a/test/oli_web/live/delivery/student/learn_live_test.exs b/test/oli_web/live/delivery/student/learn_live_test.exs
index fbee27454ef..a61c4a9b49c 100644
--- a/test/oli_web/live/delivery/student/learn_live_test.exs
+++ b/test/oli_web/live/delivery/student/learn_live_test.exs
@@ -2737,7 +2737,7 @@ defmodule OliWeb.Delivery.Student.ContentLiveTest do
assert_redirect(view, "/sections/#{section.slug}/assignments?sidebar_expanded=false")
end
- test "exit course button redirects to sections view with the student workspace selected", %{
+ test "exit course button redirects to the student workspace", %{
conn: conn,
section: section
} do
@@ -2748,7 +2748,7 @@ defmodule OliWeb.Delivery.Student.ContentLiveTest do
|> element(~s{nav[id=desktop-nav-menu] a[id="exit_course_button"]}, "Exit Course")
|> render_click()
- assert_redirect(view, "/sections?active_workspace=student_workspace&sidebar_expanded=true")
+ assert_redirect(view, "/sections/workspace/student?sidebar_expanded=true")
end
test "logo icon redirects to home page", %{
diff --git a/test/oli_web/live/workspace/instructor_test.exs b/test/oli_web/live/workspace/instructor_test.exs
new file mode 100644
index 00000000000..879c39bc8bb
--- /dev/null
+++ b/test/oli_web/live/workspace/instructor_test.exs
@@ -0,0 +1,339 @@
+defmodule OliWeb.Workspace.InstructorTest do
+ use ExUnit.Case, async: true
+ use OliWeb.ConnCase
+
+ import Phoenix.LiveViewTest
+ import Oli.Factory
+
+ alias Lti_1p3.Tool.ContextRoles
+ alias Oli.Delivery.Sections
+
+ describe "user cannot access when is not logged in" do
+ test "redirects to new session", %{
+ conn: conn
+ } do
+ redirect_path = "/session/new?request_path=%2Fsections%2Fworkspace%2Finstructor"
+
+ {:error, {:redirect, %{to: ^redirect_path}}} =
+ live(conn, ~p"/sections/workspace/instructor")
+ end
+ end
+
+ describe "user" do
+ setup [:user_conn]
+
+ test "can access instructor workspace when logged in", %{conn: conn} do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor")
+
+ assert has_element?(view, "h1", "Instructor Dashboard")
+ assert has_element?(view, "p", "You are not enrolled in any courses as an instructor.")
+ end
+
+ test "can see product title, image and description in sections index with a link to manage it on instructor workspace",
+ %{
+ conn: conn,
+ user: user
+ } do
+ section =
+ insert(:section, %{
+ open_and_free: true,
+ cover_image: "https://example.com/some-image-url.png",
+ description: "This is a description",
+ title: "The best course ever!"
+ })
+
+ Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_instructor)])
+
+ {:ok, view, _html} =
+ live(conn, ~p"/sections/workspace/instructor?sidebar_expanded=true")
+
+ assert render(view) =~
+ ~s|style=\"background-image: url('https://example.com/some-image-url.png');\"|
+
+ assert has_element?(view, "h5", "The best course ever!")
+
+ assert has_element?(
+ view,
+ ~s{a[href="/sections/#{section.slug}/instructor_dashboard/manage?sidebar_expanded=true"]}
+ )
+ end
+
+ test "if no cover image is set, renders default image in enrollment page on instructor workspace",
+ %{
+ conn: conn,
+ user: user
+ } do
+ section = insert(:section, %{open_and_free: true})
+
+ Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_instructor)])
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor")
+
+ assert render(view) =~
+ ~s|style=\"background-image: url('/images/course_default.png');\"|
+ end
+
+ test "can search by course name in instructor workspace", %{conn: conn, user: user} do
+ section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
+ section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
+
+ Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_instructor)])
+ Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor")
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "best"})
+
+ assert has_element?(view, "h5", "The best course ever!")
+ refute has_element?(view, "h5", "Maths")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: ""})
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "a not existing course"})
+
+ refute has_element?(view, "h5", "The best course ever!")
+ refute has_element?(view, "h5", "Maths")
+ end
+
+ test "can search by instructor name in instructor workspace", %{conn: conn, user: user} do
+ section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
+ section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
+ section_3 = insert(:section, %{open_and_free: true, title: "Elixir"})
+
+ instructor_1 = insert(:user, %{name: "Lionel Messi"})
+ instructor_2 = insert(:user, %{name: "Angel Di Maria"})
+
+ Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_instructor)])
+ Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
+ Sections.enroll(user.id, section_3.id, [ContextRoles.get_role(:context_instructor)])
+
+ Sections.enroll(instructor_1.id, section_1.id, [ContextRoles.get_role(:context_instructor)])
+ Sections.enroll(instructor_1.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
+
+ Sections.enroll(instructor_2.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
+ Sections.enroll(instructor_2.id, section_3.id, [ContextRoles.get_role(:context_instructor)])
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor")
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+ assert has_element?(view, "h5", "Elixir")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "messi"})
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+ refute has_element?(view, "h5", "Elixir")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "maria"})
+
+ refute has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+ assert has_element?(view, "h5", "Elixir")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "a not existing instructor"})
+
+ refute has_element?(view, "h5", "The best course ever!")
+ refute has_element?(view, "h5", "Maths")
+ refute has_element?(view, "h5", "Elixir")
+ end
+
+ test "only sees sections enrolled as instructor on instructor workspace", %{
+ conn: conn,
+ user: user
+ } do
+ section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
+ section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
+
+ Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_learner)])
+ Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor")
+
+ refute has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+ end
+
+ test "can not create sections on instructor worskpace when logged in as student", %{
+ conn: conn
+ } do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor")
+
+ assert has_element?(
+ view,
+ "div[role='create section instructions']",
+ "To create course sections,"
+ )
+
+ assert has_element?(
+ view,
+ "div[role='create section instructions'] button[onclick='window.showHelpModal();']",
+ "contact support."
+ )
+
+ assert has_element?(view, "a[href='#']", "Create New Section")
+ end
+
+ test "can navigate between the different workspaces through the left navbar", %{
+ conn: conn
+ } do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/student")
+
+ assert has_element?(
+ view,
+ "a[href='/sections/workspace/course_author?sidebar_expanded=true']",
+ "Course Author"
+ )
+
+ assert has_element?(
+ view,
+ "a[href='/sections/workspace/instructor?sidebar_expanded=true']",
+ "Instructor"
+ )
+
+ assert has_element?(
+ view,
+ "a[href='/sections/workspace/student?sidebar_expanded=true']",
+ "Student"
+ )
+
+ # we are currently on the student workspace
+ refute has_element?(view, "h1", "Instructor Dashboard")
+ assert has_element?(view, "h3", "Courses available")
+
+ # we go to the instructor workspace
+ view
+ |> element(~s{nav[id=desktop-workspace-nav-menu] a}, "Instructor")
+ |> render_click()
+
+ assert_redirected(
+ view,
+ ~p"/sections/workspace/instructor?sidebar_expanded=true"
+ )
+
+ {:ok, view, _html} =
+ live(conn, ~p"/sections/workspace/instructor?sidebar_expanded=true")
+
+ assert has_element?(view, "h1", "Instructor Dashboard")
+ refute has_element?(view, "h3", "Courses available")
+
+ # we go back to the student workspace
+ view
+ |> element(~s{nav[id=desktop-workspace-nav-menu] a}, "Student")
+ |> render_click()
+
+ assert_redirected(
+ view,
+ ~p"/sections/workspace/student?sidebar_expanded=true"
+ )
+
+ {:ok, view, _html} =
+ live(conn, ~p"/sections/workspace/student?sidebar_expanded=true")
+
+ refute has_element?(view, "h1", "Instructor Dashboard")
+ assert has_element?(view, "h3", "Courses available")
+
+ # we go to the course author workspace
+ view
+ |> element(~s{nav[id=desktop-workspace-nav-menu] a}, "Course Author")
+ |> render_click()
+
+ assert_redirected(
+ view,
+ ~p"/sections/workspace/course_author?sidebar_expanded=true"
+ )
+ end
+
+ test "can see expanded/collapsed sidebar nav", %{
+ conn: conn
+ } do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor")
+
+ assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=true]})
+
+ labels = ["Course Author", "Instructor", "Student"]
+
+ Enum.each(labels, fn label ->
+ assert view
+ |> element(~s{nav[id=desktop-workspace-nav-menu]})
+ |> render() =~ label
+ end)
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor?sidebar_expanded=false")
+
+ assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=false]})
+
+ Enum.each(labels, fn label ->
+ refute view
+ |> element(~s{nav[id=desktop-workspace-nav-menu]})
+ |> render() =~ label
+ end)
+ end
+
+ test "navbar expanded or collapsed state is kept after navigating to other menu link", %{
+ conn: conn
+ } do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor?sidebar_expanded=true")
+
+ assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=true]})
+
+ view
+ |> element(~s{nav[id=desktop-workspace-nav-menu] a}, "Student")
+ |> render_click()
+
+ assert_redirect(view, "/sections/workspace/student?sidebar_expanded=true")
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor?sidebar_expanded=false")
+
+ assert has_element?(view, ~s{nav[id=desktop-workspace-nav-menu][aria-expanded=false]})
+
+ view
+ |> element(~s{nav[id=desktop-workspace-nav-menu] a[id="student_workspace_nav_link"]})
+ |> render_click()
+
+ assert_redirect(view, "/sections/workspace/student?sidebar_expanded=false")
+ end
+ end
+
+ describe "user as instructor" do
+ setup [:instructor_conn]
+
+ test "can create sections on instructor worskpace when logged in", %{
+ conn: conn
+ } do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/instructor")
+
+ refute has_element?(
+ view,
+ "div[role='create section instructions']",
+ "To create course sections,"
+ )
+
+ refute has_element?(
+ view,
+ "div[role='create section instructions'] button[onclick='window.showHelpModal();']",
+ "contact support."
+ )
+
+ assert has_element?(view, "a[href='/sections/independent/create']", "Create New Section")
+ end
+ end
+end
diff --git a/test/oli_web/live/workspace/student_test.exs b/test/oli_web/live/workspace/student_test.exs
new file mode 100644
index 00000000000..d6d35c2c3a9
--- /dev/null
+++ b/test/oli_web/live/workspace/student_test.exs
@@ -0,0 +1,204 @@
+defmodule OliWeb.Workspace.StudentTest do
+ use ExUnit.Case, async: true
+ use OliWeb.ConnCase
+
+ import Phoenix.LiveViewTest
+ import Oli.Factory
+
+ alias Lti_1p3.Tool.ContextRoles
+ alias Oli.Delivery.Sections
+ alias Oli.Accounts
+ alias OliWeb.Pow.UserContext
+
+ describe "user cannot access when is not logged in" do
+ test "redirects to new session", %{
+ conn: conn
+ } do
+ redirect_path = "/session/new?request_path=%2Fsections%2Fworkspace%2Fstudent"
+
+ {:error, {:redirect, %{to: ^redirect_path}}} =
+ live(conn, ~p"/sections/workspace/student")
+ end
+ end
+
+ describe "user" do
+ setup [:user_conn]
+
+ test "can access student workspace when logged in", %{conn: conn} do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/student")
+
+ assert has_element?(view, "h3", "Courses available")
+ assert has_element?(view, "p", "You are not enrolled in any courses.")
+ end
+
+ test "can access student workspace when not enrolled to any section", %{conn: conn} do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/student")
+
+ assert has_element?(view, "p", "You are not enrolled in any courses.")
+ end
+
+ test "cannot access student workspace when locked", %{conn: conn, user: user} do
+ UserContext.lock(user)
+
+ {:error,
+ {:redirect,
+ %{
+ to: "/session/new",
+ flash: %{"error" => "Sorry, your account is locked. Please contact support."}
+ }}} = live(conn, ~p"/sections/workspace/student")
+ end
+
+ test "can access student workspace when is unlocked after being locked", %{
+ conn: conn,
+ user: user
+ } do
+ # Lock the user
+ {:ok, date, _timezone} = DateTime.from_iso8601("2019-05-22 20:30:00Z")
+ {:ok, user} = Accounts.update_user(user, %{locked_at: date})
+
+ # Unlock the user
+ UserContext.unlock(user)
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/student")
+
+ assert has_element?(view, "h3", "Courses available")
+ assert has_element?(view, "p", "You are not enrolled in any courses.")
+ end
+
+ test "can see product title, image and description in sections index with a link to access to it in the student workspace",
+ %{
+ conn: conn,
+ user: user
+ } do
+ section =
+ insert(:section, %{
+ open_and_free: true,
+ cover_image: "https://example.com/some-image-url.png",
+ description: "This is a description",
+ title: "The best course ever!"
+ })
+
+ Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_learner)])
+
+ {:ok, view, _html} =
+ live(conn, ~p"/sections/workspace/student?sidebar_expanded=true")
+
+ assert render(view) =~
+ ~s|style=\"background-image: url('https://example.com/some-image-url.png');\"|
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, ~s{a[href="/sections/#{section.slug}?sidebar_expanded=true"]})
+ end
+
+ test "if no cover image is set, renders default image in enrollment page in the student workspace",
+ %{
+ conn: conn,
+ user: user
+ } do
+ section = insert(:section, %{open_and_free: true})
+
+ Sections.enroll(user.id, section.id, [ContextRoles.get_role(:context_learner)])
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/student")
+
+ assert render(view) =~
+ ~s|style=\"background-image: url('/images/course_default.png');\"|
+ end
+
+ test "can search by course name in student workspace", %{conn: conn, user: user} do
+ section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
+ section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
+
+ Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_learner)])
+ Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_learner)])
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/student")
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "best"})
+
+ assert has_element?(view, "h5", "The best course ever!")
+ refute has_element?(view, "h5", "Maths")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: ""})
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "a not existing course"})
+
+ refute has_element?(view, "h5", "The best course ever!")
+ refute has_element?(view, "h5", "Maths")
+ end
+
+ test "can search by instructor name in student workspace", %{conn: conn, user: user} do
+ section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
+ section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
+ section_3 = insert(:section, %{open_and_free: true, title: "Elixir"})
+
+ instructor_1 = insert(:user, %{name: "Lionel Messi"})
+ instructor_2 = insert(:user, %{name: "Angel Di Maria"})
+
+ Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_learner)])
+ Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_learner)])
+ Sections.enroll(user.id, section_3.id, [ContextRoles.get_role(:context_learner)])
+
+ Sections.enroll(instructor_1.id, section_1.id, [ContextRoles.get_role(:context_instructor)])
+ Sections.enroll(instructor_1.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
+
+ Sections.enroll(instructor_2.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
+ Sections.enroll(instructor_2.id, section_3.id, [ContextRoles.get_role(:context_instructor)])
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/student")
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+ assert has_element?(view, "h5", "Elixir")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "messi"})
+
+ assert has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+ refute has_element?(view, "h5", "Elixir")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "maria"})
+
+ refute has_element?(view, "h5", "The best course ever!")
+ assert has_element?(view, "h5", "Maths")
+ assert has_element?(view, "h5", "Elixir")
+
+ view
+ |> form("form[phx-change=search_section]")
+ |> render_change(%{text_search: "a not existing instructor"})
+
+ refute has_element?(view, "h5", "The best course ever!")
+ refute has_element?(view, "h5", "Maths")
+ refute has_element?(view, "h5", "Elixir")
+ end
+
+ test "only sees sections enrolled as student on student workspace", %{conn: conn, user: user} do
+ section_1 = insert(:section, %{open_and_free: true, title: "The best course ever!"})
+ section_2 = insert(:section, %{open_and_free: true, title: "Maths"})
+
+ Sections.enroll(user.id, section_1.id, [ContextRoles.get_role(:context_learner)])
+ Sections.enroll(user.id, section_2.id, [ContextRoles.get_role(:context_instructor)])
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/student")
+
+ assert has_element?(view, "h5", "The best course ever!")
+ refute has_element?(view, "h5", "Maths")
+ end
+ end
+end
diff --git a/test/oli_web/pow/pow_test.exs b/test/oli_web/pow/pow_test.exs
index 527c76bc82e..094429add45 100644
--- a/test/oli_web/pow/pow_test.exs
+++ b/test/oli_web/pow/pow_test.exs
@@ -110,7 +110,7 @@ defmodule OliWeb.Common.PowTest do
)
assert html_response(conn, 302) =~
- ~p"/sections"
+ ~p"/sections/workspace/instructor"
# user who is already signed in should be automatically redirected away from sign in page
conn =
@@ -118,7 +118,7 @@ defmodule OliWeb.Common.PowTest do
|> get(Routes.pow_session_path(conn, :new))
assert html_response(conn, 302) =~
- ~p"/sections"
+ ~p"/sections/workspace/instructor"
end
test "hides authoring sign in box when coming from an invitation link", %{
@@ -142,7 +142,7 @@ defmodule OliWeb.Common.PowTest do
)
assert html_response(conn, 302) =~
- ~p"/sections"
+ ~p"/sections/workspace/instructor"
# user who is already signed in should be automatically redirected away from sign in page
conn =
@@ -150,7 +150,7 @@ defmodule OliWeb.Common.PowTest do
|> get(Routes.pow_session_path(conn, :new))
assert html_response(conn, 302) =~
- ~p"/sections"
+ ~p"/sections/workspace/instructor"
end
test "handles new session failure for non LMS user", %{conn: conn, user: user} do
diff --git a/test/oli_web/pow/users_context_test.exs b/test/oli_web/pow/users_context_test.exs
index ddcca487d0f..7b83d9d1de1 100644
--- a/test/oli_web/pow/users_context_test.exs
+++ b/test/oli_web/pow/users_context_test.exs
@@ -18,7 +18,7 @@ defmodule OliWeb.Pow.UserContextTest do
)
assert html_response(conn, 302) =~
- ~p"/sections"
+ ~p"/sections/workspace/instructor"
end
end
From 78ed30678ae4cace41b6ec3de643d6f997b8de20 Mon Sep 17 00:00:00 2001
From: Santiago Simoncelli
Date: Sat, 27 Jul 2024 11:00:19 -0300
Subject: [PATCH 03/10] [FEATURE] [MER-3302] Course author new projects view
(#4987)
* [MER-3302] Adds background and icon
* [MER-3302] Set course_author route
* [MER-3302] Course author workspace content
* [MER-3302] Adds tests
* [MER-3302] Skip tests temporarily
* Auto format
---------
Co-authored-by: simonchoxx
---
lib/oli_web/backgrounds.ex | 78 ++++
.../pow/session_html/new.html.heex | 2 +-
lib/oli_web/icons.ex | 4 +-
lib/oli_web/live/common/paged_table.ex | 2 +-
lib/oli_web/live/common/text_search.ex | 3 +-
lib/oli_web/live/workspace/course_author.ex | 355 ++++++++++++++++--
lib/oli_web/router.ex | 32 +-
.../live/workspace/course_author_test.exs | 236 ++++++++++++
.../live/workspace/instructor_test.exs | 2 +
test/oli_web/live/workspace/student_test.exs | 2 +
10 files changed, 655 insertions(+), 61 deletions(-)
create mode 100644 test/oli_web/live/workspace/course_author_test.exs
diff --git a/lib/oli_web/backgrounds.ex b/lib/oli_web/backgrounds.ex
index 217c5416b46..55f0744b255 100644
--- a/lib/oli_web/backgrounds.ex
+++ b/lib/oli_web/backgrounds.ex
@@ -366,4 +366,82 @@ defmodule OliWeb.Backgrounds do
"""
end
+
+ def course_author_header(assigns) do
+ ~H"""
+
+ """
+ end
end
diff --git a/lib/oli_web/controllers/pow/session_html/new.html.heex b/lib/oli_web/controllers/pow/session_html/new.html.heex
index a40a795783e..67a82e7f071 100644
--- a/lib/oli_web/controllers/pow/session_html/new.html.heex
+++ b/lib/oli_web/controllers/pow/session_html/new.html.heex
@@ -17,7 +17,7 @@
- <.pencil_writing />
+ <.pencil_writing color="white" />
Course Author
diff --git a/lib/oli_web/icons.ex b/lib/oli_web/icons.ex
index d0711e5d5df..11921b46342 100644
--- a/lib/oli_web/icons.ex
+++ b/lib/oli_web/icons.ex
@@ -1263,15 +1263,17 @@ defmodule OliWeb.Icons do
"""
end
+ attr :color, :string, default: "white"
+
def pencil_writing(assigns) do
~H"""
"""
diff --git a/lib/oli_web/live/common/paged_table.ex b/lib/oli_web/live/common/paged_table.ex
index a77d2a4311f..a1ca08a2b78 100644
--- a/lib/oli_web/live/common/paged_table.ex
+++ b/lib/oli_web/live/common/paged_table.ex
@@ -29,7 +29,7 @@ defmodule OliWeb.Common.PagedTable do
<% end %>
<%= if @total_count > 0 do %>
-
+
Showing all results (<%= @total_count %> total)
<%= if @show_top_paging do %>
diff --git a/lib/oli_web/live/common/text_search.ex b/lib/oli_web/live/common/text_search.ex
index e1fbbde6694..ddc35c4a171 100644
--- a/lib/oli_web/live/common/text_search.ex
+++ b/lib/oli_web/live/common/text_search.ex
@@ -12,10 +12,11 @@ defmodule OliWeb.Common.TextSearch do
def render(assigns) do
~H"""
+
+ {:ok, author} =
+ Accounts.set_author_preference(author, :admin_show_all_projects, new_value)
+
+ {new_value, author}
+
+ old_value ->
+ {old_value, author}
+ end
+
+ {show_deleted, author} =
+ case get_boolean_param(params, "show_deleted", show_deleted) do
+ new_value when new_value != show_deleted ->
+ {:ok, author} =
+ Accounts.set_author_preference(author, :admin_show_deleted_projects, new_value)
+
+ {new_value, author}
+
+ old_value ->
+ {old_value, author}
+ end
+
+ params = decode_params(params)
+
+ projects =
+ Course.browse_projects(
+ author,
+ %Paging{offset: params[:offset], limit: params[:limit]},
+ %Sorting{direction: table_model.sort_order, field: table_model.sort_by_spec.name},
+ include_deleted: show_deleted,
+ admin_show_all: show_all,
+ text_search: params[:text_search]
+ )
+
+ table_model = Map.put(table_model, :rows, projects)
+
+ total_count = determine_total(projects)
+
+ {:noreply,
+ assign(socket,
+ author: author,
+ projects: projects,
+ table_model: table_model,
+ total_count: total_count,
+ show_deleted: show_deleted,
+ show_all: show_all,
+ params: params
+ )}
end
- @impl Phoenix.LiveView
+ defp determine_total(projects) do
+ case(projects) do
+ [] -> 0
+ [hd | _] -> hd.total_count
+ end
+ end
+
+ attr(:author, :any)
+ attr(:is_admin, :boolean, default: false)
+ attr(:total_count, :integer, default: 0)
+ attr(:show_all, :boolean, default: true)
+ attr(:show_deleted, :boolean, default: false)
+ attr(:params, :map, default: %{})
+ @impl Phoenix.LiveView
def render(assigns) do
~H"""
-
-
-
-
-
-
-
-
-
- Course Author
-
+ <%= if is_nil(@author) do %>
+
Sign In in progress
+ <% else %>
+ <%= render_modal(assigns) %>
+
+
+
+
+
+
+
+
+
+ Course Author
+
+
+
+ Create, deliver, and continuously improve course materials.
+
-
- This is a placeholder for ticket MER-3320
-
-
-
-
-
- Some title
-
-
- some text
+
+
+
+ Projects
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ <% end %>
"""
end
+ def patch_with(socket, changes) do
+ %{table_model: table_model, params: params, show_all: show_all, show_deleted: show_deleted} =
+ socket.assigns
+
+ params =
+ Map.merge(
+ %{
+ sort_by: table_model.sort_by_spec.name,
+ sort_order: table_model.sort_order,
+ offset: params.offset,
+ limit: params.limit,
+ text_search: params.text_search,
+ show_deleted: show_deleted,
+ show_all: show_all
+ },
+ changes
+ )
+
+ {:noreply,
+ push_patch(socket, to: ~p"/sections/workspace/course_author?#{params}", replace: true)}
+ end
+
+ def handle_event("toggle_show_all", _, socket) do
+ patch_with(socket, %{show_all: !socket.assigns.show_all})
+ end
+
+ def handle_event("toggle_show_deleted", _, socket) do
+ patch_with(socket, %{show_deleted: !socket.assigns.show_deleted})
+ end
+
+ def handle_event("show_create_project_modal", _, socket) do
+ modal_assigns = %{
+ id: "create_project",
+ changeset: Project.new_project_changeset(%Project{title: ""})
+ }
+
+ modal = fn assigns ->
+ ~H"""
+
+ """
+ end
+
+ {:noreply, show_modal(socket, modal, modal_assigns: modal_assigns)}
+ end
+
+ @impl Phoenix.LiveView
+ def handle_event("validate_project", %{"project" => %{"title" => _title}}, socket) do
+ {:noreply, socket}
+ end
+
+ def handle_event(event, params, socket) do
+ {event, params, socket, &__MODULE__.patch_with/2}
+ |> delegate_to([
+ &TextSearch.handle_delegated/4,
+ &PagedTable.handle_delegated/4
+ ])
+ end
+
defp decode_params(params) do
%{
sidebar_expanded:
- Params.get_boolean_param(params, "sidebar_expanded", @default_params.sidebar_expanded)
+ Params.get_boolean_param(params, "sidebar_expanded", @default_params.sidebar_expanded),
+ offset: Params.get_int_param(params, "offset", @default_params.offset),
+ limit: Params.get_int_param(params, "limit", @default_params.limit),
+ text_search: Params.get_param(params, "text_search", @default_params.text_search),
+ direction: Params.get_param(params, "direction", @default_params.direction),
+ field: Params.get_param(params, "field", @default_params.field)
}
end
end
diff --git a/lib/oli_web/router.ex b/lib/oli_web/router.ex
index 1f371f6d81e..48bcbf1a642 100644
--- a/lib/oli_web/router.ex
+++ b/lib/oli_web/router.ex
@@ -156,6 +156,13 @@ defmodule OliWeb.Router do
plug(:delivery_layout)
end
+ pipeline :authoring_and_delivery do
+ plug(:delivery)
+ plug(OliWeb.EnsureUserNotLockedPlug)
+ plug(:authoring)
+ plug(OliWeb.EnsureUserNotLockedPlug)
+ end
+
pipeline :authoring_protected do
plug(:authoring)
@@ -789,9 +796,8 @@ defmodule OliWeb.Router do
scope "/sections/workspace/", OliWeb do
pipe_through([
:browser,
- :delivery_protected,
- :set_sidebar,
- :pow_email_layout
+ :authoring_and_delivery,
+ :set_sidebar
])
live_session :delivery_workspace,
@@ -802,30 +808,12 @@ defmodule OliWeb.Router do
OliWeb.LiveSessionPlugs.SetSidebar,
OliWeb.LiveSessionPlugs.SetPreviewMode
] do
+ live("/course_author", Workspace.CourseAuthor)
live("/instructor", Workspace.Instructor)
live("/student", Workspace.Student)
end
end
- scope "/sections/workspace/", OliWeb do
- pipe_through([
- :browser,
- :set_sidebar,
- :authoring_protected
- ])
-
- live_session :authoring_workspace,
- root_layout: {OliWeb.LayoutView, :delivery},
- layout: {OliWeb.Layouts, :workspace},
- on_mount: [
- OliWeb.LiveSessionPlugs.SetUser,
- OliWeb.LiveSessionPlugs.SetSidebar,
- OliWeb.LiveSessionPlugs.SetPreviewMode
- ] do
- live("/course_author", Workspace.CourseAuthor)
- end
- end
-
scope "/sections", OliWeb do
pipe_through([:browser])
diff --git a/test/oli_web/live/workspace/course_author_test.exs b/test/oli_web/live/workspace/course_author_test.exs
new file mode 100644
index 00000000000..71bfb587d3b
--- /dev/null
+++ b/test/oli_web/live/workspace/course_author_test.exs
@@ -0,0 +1,236 @@
+defmodule OliWeb.Workspace.CourseAuthorTest do
+ use ExUnit.Case, async: true
+ use OliWeb.ConnCase
+
+ import Oli.Factory
+ import Phoenix.LiveViewTest
+
+ alias OliWeb.Common.Utils
+
+ describe "user cannot access when is not logged in" do
+ test "shows sign in view if is not logged in as author/admin", %{
+ conn: conn
+ } do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ assert has_element?(view, "h1", "Sign In in progress")
+ end
+ end
+
+ describe "course author workspace as author" do
+ setup [:author_conn, :set_timezone]
+
+ test "shows course author header if is logged in", %{
+ conn: conn
+ } do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ assert has_element?(view, "h1", "Course Author")
+
+ assert has_element?(
+ view,
+ "h2",
+ "Create, deliver, and continuously improve course materials."
+ )
+ end
+
+ test "loads correctly when there are no projects", %{conn: conn} do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ assert has_element?(view, "#projects-table")
+ assert has_element?(view, "p", "None exist")
+ assert has_element?(view, "#button-new-project")
+ end
+
+ test "lists only projects the author owns", %{conn: conn, author: author} do
+ author_project = create_project_with_owner(author)
+ another_project = insert(:author) |> create_project_with_owner()
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ author_project_row =
+ view
+ |> element("##{author_project.id}")
+ |> render()
+
+ assert author_project_row =~ author_project.title
+ assert author_project_row =~ author.name
+ assert author_project_row =~ author.email
+ assert author_project_row =~ "Active"
+
+ refute has_element?(view, "##{another_project.id}")
+ end
+
+ test "applies show-deleted filter", %{conn: conn, author: author} do
+ active_project = create_project_with_owner(author)
+ deleted_project = create_project_with_owner(author, %{status: :deleted})
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ # shows only active projects by default
+ assert has_element?(view, "##{active_project.id}")
+ refute has_element?(view, "##{deleted_project.id}")
+
+ view
+ |> element("#deletedCheck")
+ |> render_click()
+
+ # shows both active and deleted projects
+ assert has_element?(view, "##{active_project.id}")
+ assert has_element?(view, "##{deleted_project.id}")
+ end
+
+ test "applies paging", %{conn: conn, author: author} do
+ [first_p | tail] =
+ 1..26
+ |> Enum.map(fn _ -> create_project_with_owner(author) end)
+ |> Enum.sort_by(& &1.title)
+
+ last_p = List.last(tail)
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ assert has_element?(view, "##{first_p.id}")
+ refute has_element?(view, "##{last_p.id}")
+
+ view
+ |> element("#header_paging button[phx-click=\"paged_table_page_change\"]", "2")
+ |> render_click()
+
+ refute has_element?(view, "##{first_p.id}")
+ assert has_element?(view, "##{last_p.id}")
+ end
+
+ test "applies sorting", %{conn: conn, author: author} do
+ create_project_with_owner(author, %{title: "Testing A"})
+ create_project_with_owner(author, %{title: "Testing B"})
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ assert view
+ |> element("tr:first-child > td:first-child")
+ |> render() =~
+ "Testing A"
+
+ view
+ |> element("th[phx-click=\"paged_table_sort\"]:first-of-type")
+ |> render_click(%{sort_by: "title"})
+
+ assert view
+ |> element("tr:first-child > td:first-child")
+ |> render() =~
+ "Testing B"
+ end
+ end
+
+ describe "course author workspace as admin" do
+ setup [:admin_conn, :set_timezone]
+
+ test "loads correctly when there are no projects", %{conn: conn} do
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ assert has_element?(view, "#projects-table")
+ assert has_element?(view, "p", "None exist")
+ assert has_element?(view, "#button-new-project")
+ end
+
+ test "lists projects", %{conn: conn, admin: admin, ctx: ctx} do
+ project = create_project_with_owner(admin)
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ project_row =
+ view
+ |> element("##{project.id}")
+ |> render()
+
+ assert project_row =~ project.title
+ assert project_row =~ Utils.render_date(project, :inserted_at, ctx)
+ assert project_row =~ admin.name
+ assert project_row =~ admin.email
+ assert project_row =~ "Active"
+ end
+
+ test "applies show-all filter", %{conn: conn, admin: admin} do
+ admin_project = create_project_with_owner(admin)
+ project = insert(:author) |> create_project_with_owner()
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ # shows all projects by default
+ assert has_element?(view, "##{admin_project.id}")
+ assert has_element?(view, "##{project.id}")
+
+ view
+ |> element("#allCheck")
+ |> render_click()
+
+ # shows only admin projects
+ assert has_element?(view, "##{admin_project.id}")
+ refute has_element?(view, "##{project.id}")
+ end
+
+ test "applies show-deleted filter", %{conn: conn, admin: admin} do
+ active_project = create_project_with_owner(admin)
+ deleted_project = insert(:project, status: :deleted)
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ # shows only active projects by default
+ assert has_element?(view, "##{active_project.id}")
+ refute has_element?(view, "##{deleted_project.id}")
+
+ view
+ |> element("#deletedCheck")
+ |> render_click()
+
+ # shows both active and deleted projects
+ assert has_element?(view, "##{active_project.id}")
+ assert has_element?(view, "##{deleted_project.id}")
+ end
+
+ test "applies paging", %{conn: conn} do
+ [first_p | tail] = insert_list(26, :project) |> Enum.sort_by(& &1.title)
+ last_p = List.last(tail)
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ assert has_element?(view, "##{first_p.id}")
+ refute has_element?(view, "##{last_p.id}")
+
+ view
+ |> element("#header_paging button[phx-click=\"paged_table_page_change\"]", "2")
+ |> render_click()
+
+ refute has_element?(view, "##{first_p.id}")
+ assert has_element?(view, "##{last_p.id}")
+ end
+
+ test "applies sorting", %{conn: conn} do
+ insert(:project, %{title: "Testing A"})
+ insert(:project, %{title: "Testing B"})
+
+ {:ok, view, _html} = live(conn, ~p"/sections/workspace/course_author")
+
+ assert view
+ |> element("tr:first-child > td:first-child")
+ |> render() =~
+ "Testing A"
+
+ view
+ |> element("th[phx-click=\"paged_table_sort\"]:first-of-type")
+ |> render_click(%{sort_by: "title"})
+
+ assert view
+ |> element("tr:first-child > td:first-child")
+ |> render() =~
+ "Testing B"
+ end
+ end
+
+ defp create_project_with_owner(owner, attrs \\ %{}) do
+ project = insert(:project, attrs)
+ insert(:author_project, project_id: project.id, author_id: owner.id)
+ project
+ end
+end
diff --git a/test/oli_web/live/workspace/instructor_test.exs b/test/oli_web/live/workspace/instructor_test.exs
index 879c39bc8bb..99c99e2d50d 100644
--- a/test/oli_web/live/workspace/instructor_test.exs
+++ b/test/oli_web/live/workspace/instructor_test.exs
@@ -9,6 +9,8 @@ defmodule OliWeb.Workspace.InstructorTest do
alias Oli.Delivery.Sections
describe "user cannot access when is not logged in" do
+ @tag :skip
+ # This test will be updated in MER-3304 and should assert that the sign in is shown
test "redirects to new session", %{
conn: conn
} do
diff --git a/test/oli_web/live/workspace/student_test.exs b/test/oli_web/live/workspace/student_test.exs
index d6d35c2c3a9..eb45fc17acc 100644
--- a/test/oli_web/live/workspace/student_test.exs
+++ b/test/oli_web/live/workspace/student_test.exs
@@ -11,6 +11,8 @@ defmodule OliWeb.Workspace.StudentTest do
alias OliWeb.Pow.UserContext
describe "user cannot access when is not logged in" do
+ @tag :skip
+ # This test will be updated in MER-3304 and should assert that the sign in is shown
test "redirects to new session", %{
conn: conn
} do
From b674ca596935ddecb46d08095c3f30b0179de49f Mon Sep 17 00:00:00 2001
From: Eli Knebel
Date: Mon, 29 Jul 2024 11:19:24 -0400
Subject: [PATCH 04/10] [BUG FIX] [MER-3156] Fix an issue with LaTeX wonkiness
and modals (#4981)
* only render a single ModalDisplay instance at any given time
* skip flaky test
---
assets/src/apps/authoring/Authoring.tsx | 3 ---
assets/src/apps/bank/ActivityBank.tsx | 3 ---
assets/src/apps/bibliography/Bibliography.tsx | 3 ---
assets/src/apps/page-editor/PageEditor.tsx | 3 ---
assets/src/components/activities/AuthoringElementProvider.tsx | 2 --
.../src/components/editing/elements/formula/FormulaEditor.tsx | 2 ++
lib/oli_web/templates/layout/chromeless.html.heex | 2 ++
lib/oli_web/templates/layout/workspace.html.eex | 2 ++
lib/oli_web/templates/shared/_help.html.heex | 4 ++--
test/oli/analytics/xapi/pipeline_test.exs | 1 +
10 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/assets/src/apps/authoring/Authoring.tsx b/assets/src/apps/authoring/Authoring.tsx
index 46a0933c193..1ec64748d92 100644
--- a/assets/src/apps/authoring/Authoring.tsx
+++ b/assets/src/apps/authoring/Authoring.tsx
@@ -1,7 +1,6 @@
import React, { useEffect, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getModeFromLocalStorage } from 'components/misc/DarkModeSelector';
-import { ModalDisplay } from 'components/modal/ModalDisplay';
import { isFirefox } from 'utils/browser';
import { AppsignalContext, ErrorBoundary } from '../../components/common/ErrorBoundary';
import { initAppSignal } from '../../utils/appsignal';
@@ -242,8 +241,6 @@ const Authoring: React.FC = (props: AuthoringProps) => {
- {/* ModalContainer handles re-parenting anywhere we use react-bootstrap Modals, ModalDisplay handles the torus style redux modals. TODO: unite these*/}
-
{isLoading && (
diff --git a/assets/src/apps/bank/ActivityBank.tsx b/assets/src/apps/bank/ActivityBank.tsx
index 8736b598a0a..fba06a4d2d2 100644
--- a/assets/src/apps/bank/ActivityBank.tsx
+++ b/assets/src/apps/bank/ActivityBank.tsx
@@ -15,7 +15,6 @@ import { PersistenceStatus } from 'components/content/PersistenceStatus';
import { Banner } from 'components/messages/Banner';
import { Page, Paging } from 'components/misc/Paging';
import { Modal } from 'components/modal/Modal';
-import { ModalDisplay } from 'components/modal/ModalDisplay';
import { arrangeObjectives } from 'components/resource/objectives/sort';
import { UndoToasts } from 'components/resource/undo/UndoToasts';
import { modalActions } from 'actions/modal';
@@ -588,8 +587,6 @@ export class ActivityBank extends React.Component
-
-
diff --git a/assets/src/apps/bibliography/Bibliography.tsx b/assets/src/apps/bibliography/Bibliography.tsx
index 7fb24c92656..28bab4fe805 100644
--- a/assets/src/apps/bibliography/Bibliography.tsx
+++ b/assets/src/apps/bibliography/Bibliography.tsx
@@ -6,7 +6,6 @@ import { ErrorBoundary } from 'components/common/ErrorBoundary';
import { Banner } from 'components/messages/Banner';
import { Page, Paging } from 'components/misc/Paging';
import { Modal } from 'components/modal/Modal';
-import { ModalDisplay } from 'components/modal/ModalDisplay';
import { modalActions } from 'actions/modal';
import { BibEntry } from 'data/content/bibentry';
import { Message, Severity, createMessage } from 'data/messages/messages';
@@ -326,8 +325,6 @@ const Bibliography: React.FC
= (props: BibliographyProps) =>
return (
-
-
-
-
diff --git a/assets/src/components/activities/AuthoringElementProvider.tsx b/assets/src/components/activities/AuthoringElementProvider.tsx
index 8b68db879ce..fff2b9f0339 100644
--- a/assets/src/components/activities/AuthoringElementProvider.tsx
+++ b/assets/src/components/activities/AuthoringElementProvider.tsx
@@ -2,7 +2,6 @@ import React, { useContext, useRef } from 'react';
import produce from 'immer';
import { Maybe } from 'tsmonad';
import { ErrorBoundary } from 'components/common/ErrorBoundary';
-import { ModalDisplay } from 'components/modal/ModalDisplay';
import { AuthoringElementProps } from './AuthoringElement';
import { ActivityModelSchema, MediaItemRequest, PostUndoable } from './types';
@@ -54,7 +53,6 @@ export const AuthoringElementProvider: React.FC
-
{children}
);
diff --git a/assets/src/components/editing/elements/formula/FormulaEditor.tsx b/assets/src/components/editing/elements/formula/FormulaEditor.tsx
index 9f82239b2f7..dca539e0679 100644
--- a/assets/src/components/editing/elements/formula/FormulaEditor.tsx
+++ b/assets/src/components/editing/elements/formula/FormulaEditor.tsx
@@ -23,6 +23,8 @@ export const FormulaEditor = (props: Props) => {
}
const onFormulaClick = () => {
+ console.log('onFormulaClick');
+
window.oliDispatch(
modalActions.display(
<%= Map.get(assigns, :inner_layout) || @inner_content %>
+
+ <%= react_component("Components.ModalDisplay") %>