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 committed Mar 12, 2024
2 parents 2a8eb4b + 0513ff4 commit c34f403
Show file tree
Hide file tree
Showing 23 changed files with 2,412 additions and 122 deletions.
2 changes: 1 addition & 1 deletion assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"sanitize-html": "^2.7.0",
"sanitize-html": "^2.12.1",
"slate": "^0.94.1",
"slate-history": "^0.93.0",
"slate-hyperscript": "^0.77.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,9 @@ const AdaptiveRuleContextMenu = (props: any) => {
cursor: 'pointer',
left: '70px',
bottom: sequenceEditorExpanded ? `1px` : `auto`,
top: sequenceEditorExpanded ? `auto` : `${clientY - 30}px`,
top: sequenceEditorExpanded
? `auto`
: `${clientY - (item !== 'initState' && !item?.default ? 270 : 30)}px`,
}}
className={`dropdown-menu ${props.show ? 'show' : ''}`}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const SequenceEditor: React.FC<any> = (props: any) => {
const bankLabel = 'Question Bank';
const screenLabel = 'Screen';
const ref = useRef<HTMLDivElement>(null);

const refSequence = useRef<HTMLOListElement>(null);
useEffect(() => {
if (props.menuItemClicked) {
const { event, item, parentItem, isLayer, isBank, direction } = props.menuItemClicked;
Expand Down Expand Up @@ -222,7 +222,7 @@ const SequenceEditor: React.FC<any> = (props: any) => {
if (parent) {
move(itemIndex, itemIndex + 1, parent.children);
} else {
// if there is no parent, move within hierarchy
// if there is no parent , move within hierarchy
move(itemIndex, itemIndex + 1, hierarchyCopy);
}
}
Expand Down Expand Up @@ -399,13 +399,13 @@ const SequenceEditor: React.FC<any> = (props: any) => {
const sequenceItemToggleClick = () => {
setTimeout(() => {
const scrollHeight = ref.current?.scrollHeight || 0;
const clientHeight = ref.current?.clientHeight || 0;
const sequenceClientHeight = refSequence?.current?.clientHeight || 0;
dispatch(
setLeftPanelState({
sequenceEditorHeight: ref?.current?.clientHeight
? ref?.current?.clientHeight + 150
: ref?.current?.clientHeight,
sequenceEditorExpanded: scrollHeight > clientHeight ? true : false,
sequenceEditorExpanded: scrollHeight < sequenceClientHeight ? true : false,
}),
);
}, 1000);
Expand Down Expand Up @@ -606,7 +606,7 @@ const SequenceEditor: React.FC<any> = (props: any) => {
maxHeight: !bottomLeftPanel && open ? 'calc(100vh - 100px)' : '55vh',
}}
>
<ListGroup as="ol" className="aa-sequence">
<ListGroup ref={refSequence} as="ol" className="aa-sequence">
{getHierarchyList(hierarchy)}
</ListGroup>
</Accordion.Collapse>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,15 @@ export const TargetedFeedback: React.FC<Props> = (props) => {

// only show feedbacks for relevant choice set, presumably current part's on multipart
const partMappings = getFeedbackForChoices(props.choices || model.choices, hook.targetedMappings);
// some migrated qs erroneously included correct answer in targeted feedback map: ignore
const firstCorrect = partMappings.find((m) => m.response.score > 0);
const mappings = partMappings.filter((m) => m !== firstCorrect);

const customScoring = hasCustomScoring(model);

return (
<>
{partMappings.map((mapping) => (
{mappings.map((mapping) => (
<ResponseCard
key={mapping.response.id}
title="Targeted feedback"
Expand Down
66 changes: 51 additions & 15 deletions assets/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9065,6 +9065,15 @@ dom-serializer@^1.0.1:
domhandler "^4.2.0"
entities "^2.0.0"

dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"

dom-walk@^0.1.0:
version "0.1.2"
resolved "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz"
Expand All @@ -9087,6 +9096,11 @@ domelementtype@^2.0.1, domelementtype@^2.2.0:
resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz"
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==

domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==

domexception@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz"
Expand All @@ -9108,6 +9122,13 @@ domhandler@^4.2.0:
dependencies:
domelementtype "^2.2.0"

domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"

domutils@^2.5.2:
version "2.8.0"
resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz"
Expand All @@ -9126,6 +9147,15 @@ domutils@^2.6.0:
domelementtype "^2.2.0"
domhandler "^4.2.0"

domutils@^3.0.1:
version "3.1.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e"
integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"

dot-case@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz"
Expand Down Expand Up @@ -9252,6 +9282,11 @@ entities@^2.0.0:
resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==

entities@^4.2.0, entities@^4.4.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==

envinfo@^7.7.3:
version "7.8.1"
resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz"
Expand Down Expand Up @@ -11182,6 +11217,16 @@ htmlparser2@^6.0.0, htmlparser2@^6.1.0:
domutils "^2.5.2"
entities "^2.0.0"

htmlparser2@^8.0.0:
version "8.0.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21"
integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.0.1"
entities "^4.4.0"

[email protected]:
version "2.0.0"
resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz"
Expand Down Expand Up @@ -15237,7 +15282,7 @@ postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0
picocolors "^0.2.1"
source-map "^0.6.1"

postcss@^8.0.9, postcss@^8.2.15, postcss@^8.3.5:
postcss@^8.0.9, postcss@^8.2.15, postcss@^8.3.11, postcss@^8.3.5:
version "8.4.18"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz"
integrity sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==
Expand All @@ -15246,15 +15291,6 @@ postcss@^8.0.9, postcss@^8.2.15, postcss@^8.3.5:
picocolors "^1.0.0"
source-map-js "^1.0.2"

postcss@^8.3.11:
version "8.4.14"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz"
integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
dependencies:
nanoid "^3.3.4"
picocolors "^1.0.0"
source-map-js "^1.0.2"

prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"
Expand Down Expand Up @@ -16854,14 +16890,14 @@ sane@^4.0.3:
minimist "^1.1.1"
walker "~1.0.5"

sanitize-html@^2.7.0:
version "2.7.0"
resolved "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.7.0.tgz"
integrity sha512-jfQelabOn5voO7FAfnQF7v+jsA6z9zC/O4ec0z3E35XPEtHYJT/OdUziVWlKW4irCr2kXaQAyXTXDHWAibg1tA==
sanitize-html@^2.12.1:
version "2.12.1"
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.12.1.tgz#280a0f5c37305222921f6f9d605be1f6558914c7"
integrity sha512-Plh+JAn0UVDpBRP/xEjsk+xDCoOvMBwQUf/K+/cBAVuTbtX8bj2VB7S1sL1dssVpykqp0/KPSesHrqXtokVBpA==
dependencies:
deepmerge "^4.2.2"
escape-string-regexp "^4.0.0"
htmlparser2 "^6.0.0"
htmlparser2 "^8.0.0"
is-plain-object "^5.0.0"
parse-srcset "^1.0.2"
postcss "^8.3.11"
Expand Down
61 changes: 45 additions & 16 deletions lib/oli/analytics/by_activity.ex
Original file line number Diff line number Diff line change
@@ -1,24 +1,53 @@
defmodule Oli.Analytics.ByActivity do
import Ecto.Query, warn: false
alias Oli.Delivery.Sections.SectionResource
alias Oli.Repo
alias Oli.Analytics.Common
alias Oli.Publishing

def query_against_project_slug(project_slug) do
Repo.all(
from activity in subquery(
Publishing.query_unpublished_revisions_by_type(project_slug, "activity")
),
left_join: analytics in subquery(Common.analytics_by_activity(project_slug)),
on: activity.resource_id == analytics.activity_id,
select: %{
slice: activity,
eventually_correct: analytics.eventually_correct,
first_try_correct: analytics.first_try_correct,
number_of_attempts: analytics.number_of_attempts,
relative_difficulty: analytics.relative_difficulty
},
preload: [:resource_type]
)
def query_against_project_slug(project_slug, []),
do: get_base_query(project_slug, []) |> Repo.all()

def query_against_project_slug(project_slug, filtered_sections) do
project_slug
|> get_base_query(filtered_sections)
|> get_query_with_join_filter(filtered_sections)
|> Repo.all()
end

defp get_base_query(project_slug, filtered_sections) do
subquery =
if filtered_sections != [] do
Publishing.query_unpublished_revisions_by_type_and_section(
project_slug,
"activity",
filtered_sections
)
else
Publishing.query_unpublished_revisions_by_type(
project_slug,
"activity"
)
end

from activity in subquery(subquery),
left_join: analytics in subquery(Common.analytics_by_activity(project_slug)),
on: activity.resource_id == analytics.activity_id,
select: %{
slice: activity,
eventually_correct: analytics.eventually_correct,
first_try_correct: analytics.first_try_correct,
number_of_attempts: analytics.number_of_attempts,
relative_difficulty: analytics.relative_difficulty
},
preload: [:resource_type]
end

defp get_query_with_join_filter(query, filter_list) do
from activity in query,
join: resource in assoc(activity, :resource),
left_join: section_resource in SectionResource,
on: resource.id == section_resource.resource_id,
where: section_resource.section_id in ^filter_list
end
end
91 changes: 61 additions & 30 deletions lib/oli/analytics/by_objective.ex
Original file line number Diff line number Diff line change
@@ -1,42 +1,73 @@
defmodule Oli.Analytics.ByObjective do
import Ecto.Query, warn: false
alias Oli.Delivery.Snapshots.Snapshot
alias Oli.Delivery.Sections.SectionResource

alias Oli.Repo
alias Oli.Analytics.Common
alias Oli.Publishing
alias Oli.Authoring.Course.Project

def query_against_project_slug(project_slug) do
activity_objectives =
from(project in Project,
where: project.slug == ^project_slug,
join: snapshot in Snapshot,
on: snapshot.project_id == project.id,
group_by: [snapshot.objective_id],
select: %{
objective_id: snapshot.objective_id,
number_of_attempts: count(snapshot.id)
}
)
def query_against_project_slug(project_slug, []),
do: get_base_query(project_slug, get_activity_objectives(project_slug), []) |> Repo.all()

def query_against_project_slug(project_slug, filtered_sections) do
project_slug
|> get_base_query(get_activity_objectives(project_slug), filtered_sections)
|> get_query_with_join_filter(filtered_sections)
|> Repo.all()
end

defp get_base_query(project_slug, activity_objectives, filtered_sections) do
subquery =
if filtered_sections != [] do
Publishing.query_unpublished_revisions_by_type_and_section(
project_slug,
"objective",
filtered_sections
)
else
Publishing.query_unpublished_revisions_by_type(
project_slug,
"objective"
)
end

from(
objective in subquery(subquery),
left_join: pairing in subquery(activity_objectives),
on: objective.resource_id == pairing.objective_id,
left_join: analytics in subquery(Common.analytics_by_objective(project_slug)),
on: pairing.objective_id == analytics.objective_id,
select: %{
slice: objective,
eventually_correct: analytics.eventually_correct,
first_try_correct: analytics.first_try_correct,
number_of_attempts: pairing.number_of_attempts,
relative_difficulty: analytics.relative_difficulty
},
preload: [:resource_type]
)
end

defp get_query_with_join_filter(query, filter) do
from objective in query,
join: resource in assoc(objective, :resource),
left_join: section_resource in SectionResource,
on: resource.id == section_resource.resource_id,
where: section_resource.section_id in ^filter
end

Repo.all(
from(
objective in subquery(
Publishing.query_unpublished_revisions_by_type(project_slug, "objective")
),
left_join: pairing in subquery(activity_objectives),
on: objective.resource_id == pairing.objective_id,
left_join: analytics in subquery(Common.analytics_by_objective(project_slug)),
on: pairing.objective_id == analytics.objective_id,
select: %{
slice: objective,
eventually_correct: analytics.eventually_correct,
first_try_correct: analytics.first_try_correct,
number_of_attempts: pairing.number_of_attempts,
relative_difficulty: analytics.relative_difficulty
},
preload: [:resource_type]
)
defp get_activity_objectives(project_slug) do
from(project in Project,
where: project.slug == ^project_slug,
join: snapshot in Snapshot,
on: snapshot.project_id == project.id,
group_by: [snapshot.objective_id],
select: %{
objective_id: snapshot.objective_id,
number_of_attempts: count(snapshot.id)
}
)
end
end
Loading

0 comments on commit c34f403

Please sign in to comment.