Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into research-questions-…
Browse files Browse the repository at this point in the history
…download
  • Loading branch information
anadis504 committed Mar 21, 2024
2 parents ec023c6 + df49a6d commit db0243b
Show file tree
Hide file tree
Showing 62 changed files with 1,693 additions and 208 deletions.
28 changes: 0 additions & 28 deletions services/cms/src/blocks/ResearchConsentCheckbox/index.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,46 @@ import { BlockEditProps } from "@wordpress/blocks"
import React from "react"
import { useTranslation } from "react-i18next"

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

import { CheckBoxAttributes } from "."
import { ResearchConsentQuestionAttributes } from "."

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

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

<b>{t("label-question")}: </b>
<RichText
className={css`
width: 100%;
margin-left: 0.25rem;
`}
tagName="span"
label={t("title-research-form-question")}
value={content}
onChange={(value: string) => setAttributes({ content: value })}
/>
</div>
{(attributes.content ?? "").split(/\s+/).length < 3 && (
<ErrorBanner error={t("error-question-too-short")} variant="readOnly" />
)}
</BlockPlaceholderWrapper>
)
}
Expand Down
29 changes: 29 additions & 0 deletions services/cms/src/blocks/ResearchConsentQuestion/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* eslint-disable i18next/no-literal-string */
import { BlockConfiguration } from "@wordpress/blocks"
import { formatLtr } from "@wordpress/icons"

import ResearchConsentCheckBoxEditor from "./ResearchConsentQuestionEditor"
import ResearchConsentCheckBoxSave from "./ResearchConsentQuestionSave"

export interface ResearchConsentQuestionAttributes {
content: string
}

const ResearchConsentQuestionConfiguration: BlockConfiguration<ResearchConsentQuestionAttributes> =
{
title: "Research Form Question",
description: "Used to add a new question to the research consent form",
category: "text",
attributes: {
content: {
type: "string",
source: "html",
selector: "span",
},
},
icon: formatLtr,
edit: ResearchConsentCheckBoxEditor,
save: ResearchConsentCheckBoxSave,
}

export default ResearchConsentQuestionConfiguration
4 changes: 2 additions & 2 deletions services/cms/src/blocks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import LearningObjectives from "./LearningObjectives"
import Map from "./Map"
import PagesInChapter from "./PagesInChapter"
import PartnersBlock from "./Partners"
import ResearchConsentCheckBox from "./ResearchConsentCheckbox"
import ResearchFormQuestion from "./ResearchConsentQuestion"
import TableBox from "./TableBox"
import TopLevelPage from "./TopLevelPage"
import UnsupportedBlock from "./UnsupportedBlock"
Expand Down Expand Up @@ -91,7 +91,7 @@ export const blockTypeMapForTopLevelPages = [
] as Array<[string, BlockConfiguration<Record<string, any>>]>

export const blockTypeMapForResearchConsentForm = [
["moocfi/research-consent-checkbox", ResearchConsentCheckBox],
["moocfi/research-consent-question", ResearchFormQuestion],
] as Array<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[string, BlockConfiguration<Record<string, any>>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const ResearchFormEditor: React.FC<React.PropsWithChildren<ResearchFormEditorPro
modifyBlocks((data.content ?? []) as BlockInstance[], [
...allowedResearchFormCoreBlocks,
// eslint-disable-next-line i18next/no-literal-string
"moocfi/research-consent-checkbox",
"moocfi/research-consent-question",
]) as BlockInstance[],
)
const courseId = useContext(CourseContext)?.courseId
Expand All @@ -52,7 +52,7 @@ const ResearchFormEditor: React.FC<React.PropsWithChildren<ResearchFormEditorPro
modifyBlocks((data.content ?? []) as BlockInstance[], [
...allowedResearchFormCoreBlocks,
// eslint-disable-next-line i18next/no-literal-string
"moocfi/research-consent-checkbox",
"moocfi/research-consent-question",
]) as BlockInstance[],
)

Expand Down
52 changes: 27 additions & 25 deletions services/cms/src/pages/courses/[id]/research-form-edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import dynamic from "next/dynamic"
import React, { useState } from "react"
import { useTranslation } from "react-i18next"

import { CheckBoxAttributes } from "../../../blocks/ResearchConsentCheckbox"
import { ResearchConsentQuestionAttributes } from "../../../blocks/ResearchConsentQuestion"
import CourseContext from "../../../contexts/CourseContext"
import {
fetchResearchFormWithCourseId,
upsertResearchForm,
upsertResearchFormQuestion,
upsertResearchFormQuestions,
} from "../../../services/backend/courses"
import {
NewResearchForm,
Expand Down Expand Up @@ -80,8 +80,24 @@ const ResearchForms: React.FC<React.PropsWithChildren<ResearchFormProps>> = ({ q
await getResearchForm.refetch()
}
const mutate = useToastMutation(
(form: NewResearchForm) => {
return upsertResearchForm(assertNotNullOrUndefined(courseId), form)
async (form: NewResearchForm) => {
if (!isBlockInstanceArray(form.content)) {
throw new Error("content is not block instance")
}
const researchForm = await upsertResearchForm(assertNotNullOrUndefined(courseId), form)
const questions: NewResearchFormQuestion[] = []
form.content.forEach((block) => {
if (isMoocfiCheckbox(block)) {
const newResearchQuestion: NewResearchFormQuestion = {
question_id: block.clientId,
course_id: researchForm.course_id,
research_consent_form_id: researchForm.id,
question: block.attributes.content,
}
questions.push(newResearchQuestion)
}
upsertResearchFormQuestions(researchForm.id, questions)
})
},
{
notify: true,
Expand All @@ -91,25 +107,9 @@ const ResearchForms: React.FC<React.PropsWithChildren<ResearchFormProps>> = ({ q
},
)
const handleSave = async (form: NewResearchForm): Promise<ResearchForm> => {
const researchForm = await mutate.mutateAsync(form)

if (!isBlockInstanceArray(form.content)) {
throw new Error("content is not block instance")
}
form.content.forEach((block) => {
if (isMoocfiCheckbox(block)) {
const newResearchQuestion: NewResearchFormQuestion = {
question_id: block.clientId,
course_id: researchForm.course_id,
research_consent_form_id: researchForm.id,
question: block.attributes.content,
}
upsertResearchFormQuestion(researchForm.id, newResearchQuestion)
}
})

await getResearchForm.refetch()
return researchForm
await mutate.mutateAsync(form)
const newData = await getResearchForm.refetch()
return newData.data as ResearchForm
}

return (
Expand Down Expand Up @@ -150,8 +150,10 @@ function isBlockInstanceArray(obj: unknown): obj is BlockInstance[] {
return true
}

function isMoocfiCheckbox(obj: BlockInstance): obj is BlockInstance<CheckBoxAttributes> {
return obj.name === "moocfi/research-consent-checkbox"
function isMoocfiCheckbox(
obj: BlockInstance,
): obj is BlockInstance<ResearchConsentQuestionAttributes> {
return obj.name === "moocfi/research-consent-question"
}

const exported = withErrorBoundary(withSignedIn(dontRenderUntilQueryParametersReady(ResearchForms)))
Expand Down
6 changes: 3 additions & 3 deletions services/cms/src/services/backend/courses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ export const upsertResearchForm = async (
return validateResponse(response, isResearchForm)
}

export const upsertResearchFormQuestion = async (
export const upsertResearchFormQuestions = async (
courseId: string,
data: NewResearchFormQuestion,
data: NewResearchFormQuestion[],
): Promise<ResearchFormQuestion> => {
const response = await cmsClient.put(
`/courses/${courseId}/research-consent-form-question`,
`/courses/${courseId}/research-consent-form-questions`,
data,
{
responseType: "json",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import LearningObjectiveBlock from "./moocfi/LearningObjectiveBlock"
import Map from "./moocfi/Map"
import PagesInChapterBlock from "./moocfi/PagesInChapterBlock"
import PartnersBlock from "./moocfi/PartnersBlock"
import ResearchFormCheckBoxBlock from "./moocfi/ResearchFormCheckBoxBlock"
import ResearchConsentQuestionBlock from "./moocfi/ResearchConsentQuestionBlock"
import TableBox from "./moocfi/TableBox"
import TopLevelPageBlock from "./moocfi/TopLevelPagesBlock/index"

Expand Down Expand Up @@ -154,7 +154,7 @@ export const blockToRendererMap: { [blockName: string]: any } = {
"moocfi/map": Map,
"moocfi/author": AuthorBlock,
"moocfi/author-inner-block": AuthorInnerBlock,
"moocfi/research-consent-checkbox": ResearchFormCheckBoxBlock,
"moocfi/research-consent-question": ResearchConsentQuestionBlock,
"moocfi/exercise-custom-view-block": ExerciseCustomViewBlock,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const ResearchFormCheckBoxBlock: React.FC<
<>
<CheckBox
label={parseText(props.data.attributes.content, terms).parsedText}
labelIsRawHtml
checked={questionIdsAndAnswers[props.data.clientId]}
onChange={() => handleChange(!questionIdsAndAnswers[props.data.clientId])}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ const Exam: React.FC<React.PropsWithChildren<ExamProps>> = ({ query }) => {
<div id="exam-instructions">
<ExamStartBanner
onStart={async () => {
await enrollInExam(examId)
await enrollInExam(examId, false)
exam.refetch()
}}
examEnrollmentData={exam.data.enrollment_data}
Expand Down
Loading

0 comments on commit db0243b

Please sign in to comment.