Skip to content

Commit

Permalink
Merge branch 'Simon-Initiative:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
dtiwarATS authored May 20, 2024
2 parents 3991502 + 82e131a commit 53bf1ad
Show file tree
Hide file tree
Showing 15 changed files with 416 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ npm-debug.log

# Since we are building assets from assets/ we ignore priv/static
/priv/static/
/test_bundles/

# Ignore generated flame graph stack files
/_flame_graph_stacks/
Expand Down
5 changes: 3 additions & 2 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ config :oli,
]

config :oli, :xapi_upload_pipeline,
producer_module: Broadway.DummyProducer,
producer_module: Oli.Analytics.XAPI.QueueProducer,
uploader_module: Oli.Analytics.XAPI.FileWriterUploader,
batcher_concurrency: 1,
batch_size: 10,
batch_timeout: 100,
processor_concurrency: 1
processor_concurrency: 1,
suppress_event_emitting: true

# Configure your database
config :oli, Oli.Repo,
Expand Down
14 changes: 9 additions & 5 deletions lib/oli/analytics/xapi.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ defmodule Oli.Analytics.XAPI do
@chars "abcdefghijklmnopqrstuvwxyz1234567890" |> String.split("", trim: true)

def emit(%StatementBundle{} = bundle) do
producer =
Oli.Analytics.XAPI.UploadPipeline
|> Broadway.producer_names()
|> Enum.random()
config = Application.fetch_env!(:oli, :xapi_upload_pipeline)

GenStage.cast(producer, {:insert, bundle})
if !Keyword.get(config, :suppress_event_emitting, false) do
producer =
Oli.Analytics.XAPI.UploadPipeline
|> Broadway.producer_names()
|> Enum.random()

GenStage.cast(producer, {:insert, bundle})
end
end

def emit(category, events) when is_list(events) do
Expand Down
3 changes: 2 additions & 1 deletion lib/oli/delivery/gating/condition_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ defmodule Oli.Delivery.Gating.ConditionTypes do
{"Schedule", Oli.Delivery.Gating.ConditionTypes.Schedule},
{"AlwaysOpen", Oli.Delivery.Gating.ConditionTypes.AlwaysOpen},
{"Started", Oli.Delivery.Gating.ConditionTypes.Started},
{"Finished", Oli.Delivery.Gating.ConditionTypes.Finished}
{"Finished", Oli.Delivery.Gating.ConditionTypes.Finished},
{"Progress", Oli.Delivery.Gating.ConditionTypes.Progress}
]
end
end
74 changes: 74 additions & 0 deletions lib/oli/delivery/gating/condition_types/progress.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
defmodule Oli.Delivery.Gating.ConditionTypes.Progress do
@moduledoc """
The progress strategy provides a condition that requires a practice page type source resource to have a
certain percentage of progress in its content.
"""

alias Oli.Delivery.Gating.GatingCondition
alias Oli.Delivery.Gating.GatingConditionData
alias Oli.Delivery.Gating.ConditionTypes.ConditionContext
alias Oli.Delivery.Sections
alias Oli.Publishing.DeliveryResolver

@behaviour Oli.Delivery.Gating.ConditionTypes.ConditionType

def type do
:progress
end

def evaluate(
%GatingCondition{
data: %GatingConditionData{
resource_id: resource_id,
minimum_percentage: minimum_percentage
}
},
%ConditionContext{} = context
) do
{resource_accesses, context} = ConditionContext.resource_accesses(context)

result =
case Map.get(resource_accesses, resource_id) do
nil ->
false

%{resource_attempts_count: 0} ->
false

%{progress: progress} ->
case minimum_percentage do
nil -> true
min -> progress >= min
end
end

{result, context}
end

def details(
%GatingCondition{
section_id: section_id,
resource_id: resource_id,
data: %GatingConditionData{
resource_id: source_id,
minimum_percentage: minimum_percentage
}
},
_ \\ []
) do
section = Sections.get_section!(section_id)

[revision, revision_source] =
DeliveryResolver.from_resource_id(section.slug, [resource_id, source_id])

case minimum_percentage do
nil ->
"#{revision.title} cannot be accessed until #{revision_source.title} is completed"

min ->
{percentage, _} = (min * 100) |> Float.to_string() |> Integer.parse()

"#{revision.title} cannot be accessed until #{percentage}% of #{revision_source.title} activities have been completed"
end
end
end
3 changes: 2 additions & 1 deletion lib/oli/delivery/gating/gating_condition.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ defmodule Oli.Delivery.Gating.GatingCondition do
:schedule,
:always_open,
:started,
:finished
:finished,
:progress
]

# The ways in which this gate affects access to graded resources
Expand Down
14 changes: 3 additions & 11 deletions lib/oli_web/components/delivery/user_account.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule OliWeb.Components.Delivery.UserAccount do
<div class="relative">
<button
id={@id}
class={"flex flex-row items-center justify-center rounded-full outline outline-2 outline-primary-800 dark:outline-neutral-700 hover:outline-4 hover:dark:outline-zinc-600 focus:outline-4 focus:outline-primary-800 dark:focus:outline-zinc-600 #{@class}"}
class={"flex flex-row items-center justify-center rounded-full outline outline-2 outline-neutral-300 dark:outline-neutral-700 hover:outline-4 hover:dark:outline-zinc-600 focus:outline-4 focus:outline-primary-300 dark:focus:outline-zinc-600 #{@class}"}
phx-click={toggle_menu("##{@id}-dropdown")}
>
<.user_icon ctx={@ctx} />
Expand Down Expand Up @@ -55,14 +55,6 @@ defmodule OliWeb.Components.Delivery.UserAccount do
in: {"ease-out duration-300", "opacity-0 top-[40px]", "opacity-100"},
out: {"ease-out duration-300", "opacity-100", "opacity-0 top-[40px]"}
)
|> JS.remove_class("dark:bg-black bg-delivery-header", to: "#header")
|> JS.add_class("dark:!bg-[#0F0D0F] !bg-gray-100", to: "#header")
end

def reset_header_color(js \\ %JS{}) do
js
|> JS.add_class("dark:bg-black bg-delivery-header", to: "#header")
|> JS.remove_class("dark:!bg-[#0F0D0F] !bg-gray-100", to: "#header")
end

attr(:id, :string, required: true)
Expand Down Expand Up @@ -139,7 +131,7 @@ defmodule OliWeb.Components.Delivery.UserAccount do
~H"""
<div
id={@id}
phx-click-away={JS.hide() |> reset_header_color()}
phx-click-away={JS.hide()}
class={"hidden absolute top-[51px] -right-[9px] z-50 p-[10px] whitespace-nowrap bg-gray-100 border-gray-300 w-[220px] dark:bg-[#0F0D0F] rounded-xl border dark:border-zinc-800 #{@class}"}
>
<ul>
Expand Down Expand Up @@ -183,7 +175,7 @@ defmodule OliWeb.Components.Delivery.UserAccount do

_method ->
~H"""
<%= link to: @href, method: @method, class: "w-[190px] text-gray-800 hover:text-white dark:text-white text-sm font-normal font-['Roboto'] h-8 px-1.5 py-2 mt-[10px] m-[5px] rounded-md border border-rose-400 justify-center items-center gap-2.5 inline-flex cursor-pointer hover:no-underline hover:bg-[#33181A] hover:border-red-500", target: @target do %>
<%= link to: @href, method: @method, class: "w-[190px] text-gray-800 hover:text-white dark:text-white text-sm font-normal font-['Roboto'] h-8 px-1.5 py-2 mt-[10px] m-[5px] rounded-md border border-rose-400 justify-center items-center gap-2.5 inline-flex cursor-pointer hover:no-underline hover:bg-red-300 hover:border-red-500 dark:hover:bg-[#33181A]", target: @target do %>
<%= render_slot(@inner_block) %>
<% end %>
"""
Expand Down
4 changes: 2 additions & 2 deletions lib/oli_web/live/delivery/student/index_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ defmodule OliWeb.Delivery.Student.IndexLive do
<div class="w-full absolute p-8 justify-start items-start gap-6 inline-flex">
<.course_progress has_visited_section={@has_visited_section} progress={@section_progress} />
<div class="w-3/4 h-full flex-col justify-start items-start gap-6 inline-flex">
<div class="w-full h-fit overflow-y-auto p-6 bg-[#1C1A20] bg-opacity-20 dark:bg-opacity-100 rounded-2xl justify-start items-start gap-32 inline-flex">
<div class="w-full h-fit overflow-y-auto p-6 bg-zinc-400 bg-opacity-20 dark:bg-[#1C1A20] dark:bg-opacity-100 rounded-2xl justify-start items-start gap-32 inline-flex">
<div class="flex-col justify-start items-start gap-7 inline-flex grow">
<div class="self-stretch justify-between items-baseline inline-flex gap-2.5">
<div class="text-2xl font-bold leading-loose tracking-tight">
Expand Down Expand Up @@ -300,7 +300,7 @@ defmodule OliWeb.Delivery.Student.IndexLive do
defp course_progress(assigns) do
~H"""
<div class="w-1/4 h-48 flex-col justify-start items-start gap-6 inline-flex">
<div class="w-full h-96 p-6 bg-[#1C1A20] bg-opacity-20 dark:bg-opacity-100 rounded-2xl justify-start items-start gap-32 inline-flex">
<div class="w-full h-96 p-6 bg-zinc-400 bg-opacity-20 dark:bg-[#1C1A20] dark:bg-opacity-100 rounded-2xl justify-start items-start gap-32 inline-flex">
<div class="flex-col justify-start items-start gap-5 inline-flex grow">
<div class="justify-start items-start gap-2.5 inline-flex">
<div class="text-2xl font-bold leading-loose tracking-tight">
Expand Down
44 changes: 44 additions & 0 deletions lib/oli_web/live/sections/gating_and_scheduling/form.ex
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,50 @@ defmodule OliWeb.Sections.GatingAndScheduling.Form do
"""
end

def render_condition_options(%{gating_condition: %{type: :progress}} = assigns) do
assigns = assign(assigns, :data, assigns.gating_condition.data)

~H"""
<div class="form-group">
<label for="source">Resource That Must Has Progress</label>
<div class="input-group mb-3">
<input
type="text"
id="source"
readonly
class="form-control"
placeholder="Select a source resource..."
aria-label="resource-title"
aria-describedby="basic-addon2"
phx-click="show-ungraded-picker"
{maybe_source_value(assigns)}
/>
<div class="input-group-append">
<button class="btn btn-outline-primary" type="button" phx-click="show-ungraded-picker">
Select
</button>
</div>
</div>
</div>
<div class="flex flex-row items-center w-full gap-x-2 mb-4 mt-2">
<div class="sm:col-span-2 w-full">
<input
type="number"
class="form-control"
id="min-score-value"
disabled={assigns.gating_condition.data[:resource_id] == nil}
min="0"
max="100"
value={value_from_min_score(@data)}
phx-hook="TextInputListener"
phx-value-change="change_min_score"
/>
</div>
<label for="min-score-value" class="sm:col-span-1 col-form-label">%</label>
</div>
"""
end

def render_condition_options(%{gating_condition: %{type: :always_open}} = assigns) do
~H"""
<div class="alert alert-secondary" role="alert">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,61 @@ defmodule OliWeb.Delivery.Sections.GatingAndScheduling.GatingConditionStore do
{:noreply, show_modal(socket, modal, modal_assigns: modal_assigns)}
end

def handle_event("show-ungraded-picker", _, socket) do
%{section: section} = socket.assigns

hierarchy = DeliveryResolver.full_hierarchy(section.slug)
root = hierarchy

filter_items_fn =
case socket.assigns.gating_condition.resource_id do
nil ->
fn items ->
Enum.filter(
items,
&((&1.uuid != root.uuid and
(&1.revision.resource_type_id ==
Oli.Resources.ResourceType.id_for_page() and
!&1.revision.graded)) or
&1.revision.resource_type_id ==
Oli.Resources.ResourceType.id_for_container())
)
end

resource_id ->
fn items ->
Enum.filter(
items,
&((&1.uuid != root.uuid and
&1.revision.resource_id != resource_id and
(&1.revision.resource_type_id ==
Oli.Resources.ResourceType.id_for_page() and
!&1.revision.graded)) or
&1.revision.resource_type_id ==
Oli.Resources.ResourceType.id_for_container())
)
end
end

modal_assigns = %{
id: "select_resource",
hierarchy: hierarchy,
active: root,
selection: nil,
filter_items_fn: filter_items_fn,
on_select: "select_source",
on_cancel: "cancel_select_resource"
}

modal = fn assigns ->
~H"""
<SelectResourceModal.render {@modal_assigns} />
"""
end

{:noreply, show_modal(socket, modal, modal_assigns: modal_assigns)}
end

def handle_event("show-all-picker", _, socket) do
%{section: section} = socket.assigns

Expand Down
31 changes: 31 additions & 0 deletions lib/oli_web/live/sections/gating_and_scheduling/table_model.ex
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,37 @@ defmodule OliWeb.Delivery.Sections.GatingAndScheduling.TableModel do
"""
end

def render_details_column(
%{ctx: _} = assigns,
%GatingCondition{
type: :progress,
data: %GatingConditionData{
minimum_percentage: nil
}
},
_
) do
~H"""
<div>
A resource must be completed
</div>
"""
end

def render_details_column(
%{ctx: _} = assigns,
%GatingCondition{
type: :progress
},
_
) do
~H"""
<div>
A resource must be completed with a minimum of progress
</div>
"""
end

def render_details_column(
%{ctx: _ctx} = assigns,
%GatingCondition{
Expand Down
11 changes: 8 additions & 3 deletions lib/oli_web/pow/author_context.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule OliWeb.Pow.AuthorContext do
repo: Oli.Repo,
user: Oli.Accounts.Author

alias Oli.Repo
alias Oli.{Repo, Utils}
alias Oli.Accounts
alias Oli.Accounts.Author
alias OliWeb.Router.Helpers, as: Routes
Expand Down Expand Up @@ -42,9 +42,14 @@ defmodule OliWeb.Pow.AuthorContext do
"Account already exists",
"account_already_exists.html",
%{
url: Routes.authoring_pow_session_path(OliWeb.Endpoint, :new),
url:
Utils.ensure_absolute_url(
Routes.authoring_pow_session_path(OliWeb.Endpoint, :new)
),
forgot_password:
Routes.authoring_pow_reset_password_reset_password_path(OliWeb.Endpoint, :new)
Utils.ensure_absolute_url(
Routes.authoring_pow_reset_password_reset_password_path(OliWeb.Endpoint, :new)
)
}
)
|> Oli.Mailer.deliver_now()
Expand Down
Loading

0 comments on commit 53bf1ad

Please sign in to comment.