Skip to content

Commit

Permalink
Fixes 2224 (#1247)
Browse files Browse the repository at this point in the history
* Fix points list sorting and percentages

* Better sort in course-status-summary-for-user

* Prompt research form to users who have started a course before the form was added

* Remove console.log

* System test fixes
  • Loading branch information
nygrenh authored Feb 22, 2024
1 parent e220252 commit 0f09118
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,40 +1,47 @@
/* eslint-disable i18next/no-literal-string */
import { css } from "@emotion/css"
import { RichText } from "@wordpress/block-editor"
import { BlockEditProps } from "@wordpress/blocks"
import React from "react"
import { useTranslation } from "react-i18next"

import CheckBox from "../../shared-module/components/InputFields/CheckBox"
import BlockWrapper from "../BlockWrapper"
import BlockPlaceholderWrapper from "../BlockPlaceholderWrapper"

import { CheckBoxAttributes } from "."

const ResearchConsentCheckBoxEditor: React.FC<
React.PropsWithChildren<BlockEditProps<CheckBoxAttributes>>
> = ({ clientId, attributes, isSelected, setAttributes }) => {
const { content } = attributes
const { t } = useTranslation()

return (
<BlockWrapper id={clientId}>
<BlockPlaceholderWrapper
id={clientId}
title={t("title-research-form-checkbox")}
explanation={t("research-form-checkbox-description")}
>
<div
className={css`
display: flex;
flex-direction: rox;
align-items: baseline;
padding: 1rem;
width: 100%;
`}
>
<CheckBox label={" "} checked={isSelected} />

<RichText
className="paragraph"
className={css`
width: 100%;
`}
tagName="span"
value={content}
onChange={(value: string) => setAttributes({ content: value })}
placeholder={"Add question here"}
/>
</div>
</BlockWrapper>
</BlockPlaceholderWrapper>
)
}

Expand Down
59 changes: 37 additions & 22 deletions services/course-material/src/components/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { NewProposedBlockEdit } from "../shared-module/bindings"
import ErrorBanner from "../shared-module/components/ErrorBanner"
import Spinner from "../shared-module/components/Spinner"
import LoginStateContext from "../shared-module/contexts/LoginStateContext"
import useQueryParameter from "../shared-module/hooks/useQueryParameter"
import { baseTheme } from "../shared-module/styles"
import { assertNotNullOrUndefined } from "../shared-module/utils/nullability"
Expand Down Expand Up @@ -72,16 +73,18 @@ const Page: React.FC<React.PropsWithChildren<Props>> = ({ onRefresh, organizatio
const { t } = useTranslation()
const router = useRouter()

const [showAndEditForm, setshowAndEditForm] = useState<boolean>(false)
const [showResearchConsentForm, setShowResearchConsentForm] = useState<boolean>(false)
const [shouldAnswerResearchForm, setShouldAnswerResearchForm] = useState<boolean>(false)
const [hasAnsweredForm, setHasAnsweredForm] = useState<boolean>(false)
const researchFormQueryParam = useQueryParameter("show_research_form")
const [shouldFetchResearchFormData, setShouldFetchResearchFormData] = useState<boolean>(false)
const loginContext = useContext(LoginStateContext)
const waitingForCourseSettingsToBeFilled =
pageContext.settings?.current_course_instance_id === null ||
pageContext.settings?.current_course_instance_id === undefined

useEffect(() => {
if (researchFormQueryParam) {
setshowAndEditForm(true)
setShouldFetchResearchFormData(true)
setShowResearchConsentForm(true)
const newPathObject = {
...router,
}
Expand All @@ -92,22 +95,35 @@ const Page: React.FC<React.PropsWithChildren<Props>> = ({ onRefresh, organizatio
}
}, [router, researchFormQueryParam])

const getUserAnswers = useQuery({
queryKey: [`courses-${courseId}-research-consent-form-user-answer`],
queryFn: () => fetchResearchFormAnswersWithUserId(assertNotNullOrUndefined(courseId)),
enabled: !!shouldFetchResearchFormData,
})
const getResearchConsentForm = useQuery({
const researchConsentFormQuery = useQuery({
queryKey: [`courses-${courseId}-research-consent-form`],
queryFn: () => fetchResearchFormWithCourseId(assertNotNullOrUndefined(courseId)),
enabled: !!shouldFetchResearchFormData,
enabled: loginContext.signedIn === true && Boolean(courseId),
})

const researchConsentFormAnswerQuery = useQuery({
queryKey: [`courses-${courseId}-research-consent-form-user-answer`],
queryFn: () => fetchResearchFormAnswersWithUserId(assertNotNullOrUndefined(courseId)),
enabled: loginContext.signedIn === true && Boolean(courseId),
})

useEffect(() => {
if (getUserAnswers.data?.length === 0 && !shouldAnswerResearchForm && !hasAnsweredForm) {
if (
researchConsentFormQuery.data !== null &&
researchConsentFormAnswerQuery.data?.length === 0 &&
!shouldAnswerResearchForm &&
!hasAnsweredForm &&
!waitingForCourseSettingsToBeFilled
) {
setShouldAnswerResearchForm(true)
}
}, [getUserAnswers.data?.length, hasAnsweredForm, shouldAnswerResearchForm])
}, [
researchConsentFormAnswerQuery.data?.length,
hasAnsweredForm,
shouldAnswerResearchForm,
researchConsentFormQuery.data,
waitingForCourseSettingsToBeFilled,
])

const getPageAudioFiles = useQuery({
queryKey: [`page-${pageId}-audio-files`, courseId, isMaterialPage],
Expand Down Expand Up @@ -156,23 +172,22 @@ const Page: React.FC<React.PropsWithChildren<Props>> = ({ onRefresh, organizatio
<CourseSettingsModal
onClose={() => {
onRefresh()
setShouldFetchResearchFormData(true)
}}
/>
)}
{getResearchConsentForm.isSuccess &&
getResearchConsentForm.data !== null &&
(showAndEditForm || shouldAnswerResearchForm) && (
{researchConsentFormQuery.isSuccess &&
researchConsentFormQuery.data !== null &&
(showResearchConsentForm || shouldAnswerResearchForm) && (
<SelectResearchConsentForm
editForm={showAndEditForm}
editForm={showResearchConsentForm}
shouldAnswerResearchForm={shouldAnswerResearchForm}
usersInitialAnswers={getUserAnswers.data}
researchForm={getResearchConsentForm.data}
usersInitialAnswers={researchConsentFormAnswerQuery.data}
researchForm={researchConsentFormQuery.data}
onClose={() => {
setshowAndEditForm(false)
setShowResearchConsentForm(false)
setShouldAnswerResearchForm(false)
setHasAnsweredForm(true)
if (showAndEditForm) {
if (showResearchConsentForm) {
router.back()
}
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,24 @@ const SelectResearchConsentForm: React.FC<React.PropsWithChildren<ResearchConsen

// Adds all checkbox ids and false as default answer to questionIdsAndAnswers
useEffect(() => {
if (usersInitialAnswers) {
const questions = usersInitialAnswers?.reduce(
(acc, obj) => ({
...acc,
[obj.research_form_question_id]: obj.research_consent,
}),
{},
)
setQuestionIdsAndAnswers(questions)
} else {
const questions = getResearchFormQuestions.data?.reduce(
(acc, obj) => ({
...acc,
[obj.id]: false,
}),
{},
)
setQuestionIdsAndAnswers(questions)
}
setQuestionIdsAndAnswers((prev) => {
let res = prev
if (!res) {
res = {}
}
if (usersInitialAnswers) {
for (const answer of usersInitialAnswers) {
res[answer.research_form_question_id] = answer.research_consent
}
}
// Find out missing questions and add them to the list
for (const question of getResearchFormQuestions.data ?? []) {
if (Object.prototype.hasOwnProperty.call(res, question.id) === false) {
res[question.id] = false
}
}
return res
})
}, [getResearchFormQuestions.data, setQuestionIdsAndAnswers, usersInitialAnswers])

const mutation = useToastMutation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,18 @@ const CourseInstanceExerciseStatusList: React.FC<
})
.map(([chapterId, exerciseStatusListUnsorted]) => {
const chapter = courseStructure.data.chapters.find((ch) => ch.id === chapterId)
const exerciseStatusList = exerciseStatusListUnsorted.sort(
(a, b) => a.exercise.order_number - b.exercise.order_number,
)

const exerciseStatusList = exerciseStatusListUnsorted
.sort((a, b) => a.exercise.order_number - b.exercise.order_number)
.sort((a, b) => {
const aPage = courseStructure.data.pages.find((p) => p.id === a.exercise.page_id)
const bPage = courseStructure.data.pages.find((p) => p.id === b.exercise.page_id)
if (aPage && bPage) {
return aPage.order_number - bPage.order_number
}
return 0
})

return (
<div
key={chapterId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ const CourseInstancePointsList: React.FC<
} else if (sorting == NUMBER) {
return first.user.user_id.localeCompare(second.user.user_id)
} else if (sorting == SCORE) {
return first.totalPoints - second.totalPoints
return second.totalPoints - first.totalPoints
} else if (sorting == EMAIL) {
return first.user.email.localeCompare(second.user.email)
} else {
return first.chapterPoints[sorting] - second.chapterPoints[sorting]
return second.chapterPoints[sorting] - first.chapterPoints[sorting]
}
}

Expand Down Expand Up @@ -148,7 +148,10 @@ const CourseInstancePointsList: React.FC<
return (
<th key={c.id}>
{t("title-chapter-only-number", { "chapter-number": c.chapter_number })}{" "}
<a href={courseSorting} onClick={() => setSorting(courseSorting)}>
<a
href={courseSorting}
onClick={() => setSorting(courseSorting.substring(1))}
>
{DOWN_ARROW}
</a>
</th>
Expand Down Expand Up @@ -194,7 +197,7 @@ const CourseInstancePointsList: React.FC<
<td>{user.email}</td>
<td>
{roundDown(totalPoints, 2)}/{instanceTotalPoints} (
{Math.round(totalPoints / instanceTotalPoints)}%)
{roundDown((totalPoints / instanceTotalPoints) * 100, 0)}%)
</td>

{getPointsList.data.chapter_points.map((c) => {
Expand Down
2 changes: 2 additions & 0 deletions shared-module/src/locales/en/cms.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
"peer-reviews-to-receive-and-give-error-message": "Peer reviews to give must be greater than peer reviews to receive",
"please-select-exercise-type": "Please select an exercise type:",
"remove": "Remove",
"research-form-checkbox-description": "This block is used to add a question to the research form.",
"reset": "Reset",
"save": "Save",
"saved": "Saved",
Expand All @@ -104,6 +105,7 @@
"task": "Task",
"title-assignment": "Assignment",
"title-outdated-blocks-migrated": "Outdated blocks migrated",
"title-research-form-checkbox": "Research form checkbox",
"top-level-block-placeholder": "Top level pages placeholder",
"top-level-block-placeholder-explanation": "This block list all the top level pages in a course and it is placed on the course material front page.",
"tries-per-slide": "Max tries per slide",
Expand Down
2 changes: 2 additions & 0 deletions shared-module/src/locales/fi/cms.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"peer-reviews-to-receive-and-give-error-message": "Annettujen vertaisarvioiden määrä täytyy olla suurempi kuin vastaanotettujen vertaisarvioiden määrä",
"please-select-exercise-type": "Ole hyvä ja valitse harjoitustyyppi:",
"remove": "Poista",
"research-form-checkbox-description": "Tämä lohko lisää valintaruudun tutkimuslomakkeeseen.",
"reset": "Palauta",
"save": "Tallenna",
"saved": "Tallennettu",
Expand All @@ -91,6 +92,7 @@
"task": "Tehtävä",
"title-assignment": "Tehtävänanto",
"title-outdated-blocks-migrated": "Vanhentuneet lohkot päivitetty",
"title-research-form-checkbox": "Tutkimuslomakkeen valintaruutu",
"top-level-block-placeholder": "Yleisten sivujen paikkamerkki",
"top-level-block-placeholder-explanation": "Tämä lohko listaa kaikki kurssin yleiset sivut ja on sijoitettu kurssin etusivulle.",
"tries-per-slide": "Maksimimäärä yrityksiä per dia",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 3 additions & 7 deletions system-tests/src/tests/research-form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,9 @@ test("Can create a new research form for a course", async ({ page }) => {
.fill("This course does research")
await page.getByRole("option", { name: "CheckBox" }).click()
await page.getByRole("document", { name: "Block: CheckBox" }).locator("div").nth(1).click()
await page
.getByRole("textbox", { name: "Add question here" })
.fill("I want to take part in reseach")
await page.getByRole("textbox", { name: "Add question here" }).press("ArrowLeft")
await page
.getByRole("textbox", { name: "Add question here" })
.fill("I want to take part in research")
await page.getByRole("textbox").fill("I want to take part in reseach")
await page.getByRole("textbox").press("ArrowLeft")
await page.getByRole("textbox").fill("I want to take part in research")
await page.getByRole("button", { name: "Save" }).click()
await page.getByText("Operation successful!").waitFor()
})
Expand Down

0 comments on commit 0f09118

Please sign in to comment.