From 5aaedf52df7d7daffc32408a2e5876eba9939d4b Mon Sep 17 00:00:00 2001 From: Olim Saidov Date: Fri, 22 Nov 2024 19:15:52 +0500 Subject: [PATCH] Add create questionnaire response --- .../public-library/questionnaires/page.tsx | 7 +- .../app/(authorized)/questionnaires/page.tsx | 86 ++++++++++++++++++- .../src/components/questionnaires-actions.tsx | 37 +++++++- .../src/lib/server/smart.ts | 7 ++ 4 files changed, 132 insertions(+), 5 deletions(-) diff --git a/aidbox-forms-smart-launch-2/src/app/(authorized)/public-library/questionnaires/page.tsx b/aidbox-forms-smart-launch-2/src/app/(authorized)/public-library/questionnaires/page.tsx index a30be19..bbedd2c 100644 --- a/aidbox-forms-smart-launch-2/src/app/(authorized)/public-library/questionnaires/page.tsx +++ b/aidbox-forms-smart-launch-2/src/app/(authorized)/public-library/questionnaires/page.tsx @@ -19,6 +19,7 @@ import { decidePageSize } from "@/lib/server/utils"; import ky from "ky"; import { QuestionnairesActions } from "@/components/questionnaires-actions"; import { getCurrentAidbox } from "@/lib/server/smart"; +import { revalidatePath } from "next/cache"; interface PageProps { searchParams: Promise<{ @@ -58,11 +59,15 @@ export default async function PublicLibraryPage({ searchParams }: PageProps) { "use server"; const aidbox = await getCurrentAidbox(); - return aidbox + const created = aidbox .post("fhir/Questionnaire", { json: { ...questionnaire, id: undefined }, }) .json(); + + revalidatePath("/questionnaires"); + + return created; } return ( diff --git a/aidbox-forms-smart-launch-2/src/app/(authorized)/questionnaires/page.tsx b/aidbox-forms-smart-launch-2/src/app/(authorized)/questionnaires/page.tsx index 98fd959..f246c0e 100644 --- a/aidbox-forms-smart-launch-2/src/app/(authorized)/questionnaires/page.tsx +++ b/aidbox-forms-smart-launch-2/src/app/(authorized)/questionnaires/page.tsx @@ -1,4 +1,9 @@ -import { getCurrentAidbox } from "@/lib/server/smart"; +import { + getCurrentAidbox, + getCurrentEncounter, + getCurrentPatient, + getCurrentUser, +} from "@/lib/server/smart"; import { Table, TableBody, @@ -14,7 +19,12 @@ import { PageSizeSelect } from "@/components/page-size-select"; import Link from "next/link"; import { Search } from "lucide-react"; import { Pager } from "@/components/pager"; -import { Bundle, Questionnaire } from "fhir/r4"; +import { + Bundle, + Questionnaire, + QuestionnaireResponse, + Parameters, +} from "fhir/r4"; import { isDefined } from "@/lib/utils"; import { decidePageSize } from "@/lib/server/utils"; import { QuestionnairesActions } from "@/components/questionnaires-actions"; @@ -60,6 +70,77 @@ export default async function QuestionnairesPage({ searchParams }: PageProps) { revalidatePath("/questionnaires"); } + async function createQuestionnaireResponse(questionnaire: Questionnaire) { + "use server"; + + const aidbox = await getCurrentAidbox(); + const subject = await getCurrentPatient().catch(() => null); + const encounter = await getCurrentEncounter().catch(() => null); + const author = await getCurrentUser().catch(() => null); + + const result = await aidbox + .post(`fhir/Questionnaire/$populate`, { + json: { + resourceType: "Parameters", + parameter: [ + { + name: "questionnaire", + resource: questionnaire, + }, + { + name: "subject", + resource: subject, + }, + { + name: "context", + part: [ + ...(encounter + ? [ + { + name: "name", + valueString: "encounter", + }, + { + name: "content", + resource: encounter, + }, + ] + : []), + ...(author + ? [ + { + name: "name", + valueString: "author", + }, + { + name: "content", + resource: author, + }, + ] + : []), + ], + }, + ], + }, + }) + .json(); + + const populated = result.parameter?.find(({ name }) => name === "response") + ?.resource as QuestionnaireResponse; + + populated.questionnaire = `${questionnaire.url}${questionnaire.version ? `|${questionnaire.version}` : ""}`; + + const saved = await aidbox + .post("fhir/QuestionnaireResponse", { + json: populated, + }) + .json(); + + revalidatePath("/questionnaire-responses"); + + return saved; + } + return ( <> diff --git a/aidbox-forms-smart-launch-2/src/components/questionnaires-actions.tsx b/aidbox-forms-smart-launch-2/src/components/questionnaires-actions.tsx index a8e3363..34599b9 100644 --- a/aidbox-forms-smart-launch-2/src/components/questionnaires-actions.tsx +++ b/aidbox-forms-smart-launch-2/src/components/questionnaires-actions.tsx @@ -1,6 +1,6 @@ "use client"; -import { Questionnaire } from "fhir/r4"; +import { Questionnaire, QuestionnaireResponse } from "fhir/r4"; import { DropdownMenu, DropdownMenuContent, @@ -38,11 +38,15 @@ export function QuestionnairesActions({ library, onDeleteAction, onImportAction, + onCreateResponseAction, }: { questionnaire: Questionnaire; library?: boolean; onDeleteAction?: (questionnaire: Questionnaire) => Promise; onImportAction?: (questionnaire: Questionnaire) => Promise; + onCreateResponseAction?: ( + questionnaire: Questionnaire, + ) => Promise; }) { const router = useRouter(); const [viewing, setViewing] = useState(false); @@ -104,7 +108,36 @@ export function QuestionnairesActions({ )} {!library && ( - {}}> + { + if (onCreateResponseAction) { + try { + const { id } = await onCreateResponseAction(questionnaire); + + toast({ + title: "Questionnaire response created", + description: `New questionnaire response created and populated`, + action: ( + { + router.push(`/questionnaire-responses/${id}`); + }} + > + Edit + + ), + }); + } catch { + toast({ + title: "Questionnaire response creation failed", + description: `Failed to create new questionnaire response`, + variant: "destructive", + }); + } + } + }} + > Create response diff --git a/aidbox-forms-smart-launch-2/src/lib/server/smart.ts b/aidbox-forms-smart-launch-2/src/lib/server/smart.ts index 9818fd3..cde20d0 100644 --- a/aidbox-forms-smart-launch-2/src/lib/server/smart.ts +++ b/aidbox-forms-smart-launch-2/src/lib/server/smart.ts @@ -9,6 +9,7 @@ import { cache } from "react"; import { CapabilityStatement, CapabilityStatementImplementation, + Encounter, Patient, Practitioner, } from "fhir/r4"; @@ -154,6 +155,12 @@ export const getCurrentUser = cache(async () => { return user as Patient | Practitioner; }); +export const getCurrentEncounter = cache(async () => { + const client = await getCurrentClient(); + const encounter = await client.encounter.read(); + return encounter as Encounter; +}); + export const getCurrentAidbox = cache(async () => { const client = await getCurrentClient(); return getOrganizationalAidbox(client.state.serverUrl);