Skip to content

Commit

Permalink
Add create questionnaire response
Browse files Browse the repository at this point in the history
  • Loading branch information
olimsaidov committed Nov 22, 2024
1 parent 934c4ab commit 5aaedf5
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<{
Expand Down Expand Up @@ -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<Questionnaire>();

revalidatePath("/questionnaires");

return created;
}

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { getCurrentAidbox } from "@/lib/server/smart";
import {
getCurrentAidbox,
getCurrentEncounter,
getCurrentPatient,
getCurrentUser,
} from "@/lib/server/smart";
import {
Table,
TableBody,
Expand All @@ -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";
Expand Down Expand Up @@ -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<Parameters>();

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<QuestionnaireResponse>();

revalidatePath("/questionnaire-responses");

return saved;
}

return (
<>
<PageHeader
Expand Down Expand Up @@ -107,6 +188,7 @@ export default async function QuestionnairesPage({ searchParams }: PageProps) {
<QuestionnairesActions
questionnaire={resource}
onDeleteAction={deleteQuestionnaire}
onCreateResponseAction={createQuestionnaireResponse}
/>
</TableCell>
</TableRow>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { Questionnaire } from "fhir/r4";
import { Questionnaire, QuestionnaireResponse } from "fhir/r4";
import {
DropdownMenu,
DropdownMenuContent,
Expand Down Expand Up @@ -38,11 +38,15 @@ export function QuestionnairesActions({
library,
onDeleteAction,
onImportAction,
onCreateResponseAction,
}: {
questionnaire: Questionnaire;
library?: boolean;
onDeleteAction?: (questionnaire: Questionnaire) => Promise<void>;
onImportAction?: (questionnaire: Questionnaire) => Promise<Questionnaire>;
onCreateResponseAction?: (
questionnaire: Questionnaire,
) => Promise<QuestionnaireResponse>;
}) {
const router = useRouter();
const [viewing, setViewing] = useState(false);
Expand Down Expand Up @@ -104,7 +108,36 @@ export function QuestionnairesActions({
)}

{!library && (
<DropdownMenuItem onClick={() => {}}>
<DropdownMenuItem
onClick={async () => {
if (onCreateResponseAction) {
try {
const { id } = await onCreateResponseAction(questionnaire);

toast({
title: "Questionnaire response created",
description: `New questionnaire response created and populated`,
action: (
<ToastAction
altText="Edit"
onClick={() => {
router.push(`/questionnaire-responses/${id}`);
}}
>
Edit
</ToastAction>
),
});
} catch {
toast({
title: "Questionnaire response creation failed",
description: `Failed to create new questionnaire response`,
variant: "destructive",
});
}
}
}}
>
<Plus />
Create response
</DropdownMenuItem>
Expand Down
7 changes: 7 additions & 0 deletions aidbox-forms-smart-launch-2/src/lib/server/smart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { cache } from "react";
import {
CapabilityStatement,
CapabilityStatementImplementation,
Encounter,
Patient,
Practitioner,
} from "fhir/r4";
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 5aaedf5

Please sign in to comment.