-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Questionnaire actions #16618
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Questionnaire actions #16618
Changes from all commits
d542f80
a6d1f30
557cfcd
7417d94
32391c1
a9d590b
d2eaceb
5b2dd22
72b8bca
4dfeae9
1071a66
65a2d7d
1ae4c49
f57215d
8c8134f
bf60d4b
f541cab
44cbd39
4f9e182
e29514d
357eeb2
ef67cd6
b44ba45
b4f5c62
735cdb3
1d996d6
333136c
9fb5c26
bde5543
4ed36f1
ec5bc1d
07ccb7d
2e95b0f
dd42f9f
2f937e1
b7a4450
fc662fb
9cd756a
9fc2a74
be19a64
a6d02ef
2fed69d
540f73e
b0e173e
7845915
c01b13f
105789f
7d8636d
959185a
fd74541
875f9f4
144e9b5
dcc287e
2b26f69
8155ca8
c65651f
943f7b0
d4e1f34
a2bd4d7
dd69b31
3d97773
9d8d35b
1ed3ce8
1ae2829
a55033c
4ea57d6
e2ca7ed
7931b1b
4eacfe9
fb97e9c
78039aa
cafc5fb
2dfaa49
0dbe33b
b7c1dfa
5b13433
175f19d
3b99ce6
dc6e54b
ba0c368
2d1fb14
cd6407c
87b1201
fe64607
a6363c9
77d8127
bfc6838
4e4b2c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,10 @@ | ||
| import { navigate } from "raviger"; | ||
|
|
||
| import QuestionnaireEditor from "@/components/Questionnaire/QuestionnaireEditor"; | ||
| import { QuestionnaireList } from "@/components/Questionnaire/QuestionnaireList"; | ||
| import { QuestionnaireBuilderPage } from "@/components/QuestionnaireV2/builder/QuestionnaireBuilderPage"; | ||
| import { QuestionnaireCreatePage } from "@/components/QuestionnaireV2/manage/QuestionnaireCreatePage"; | ||
| import { QuestionnaireDetailPage } from "@/components/QuestionnaireV2/manage/QuestionnaireDetailPage"; | ||
| import { QuestionnaireListPage } from "@/components/QuestionnaireV2/manage/QuestionnaireListPage"; | ||
| import { QuestionnaireRevisionPage } from "@/components/QuestionnaireV2/manage/QuestionnaireRevisionPage"; | ||
| import { ValueSetEditor } from "@/components/ValueSet/ValueSetEditor"; | ||
| import { ValueSetList } from "@/components/ValueSet/ValueSetList"; | ||
|
|
||
|
|
@@ -16,17 +19,41 @@ import { PlugConfigList } from "@/pages/Apps/PlugConfigList"; | |
| import PatientIdentifierConfigForm from "@/pages/settings/patientIdentifierConfig/PatientIdentifierConfigForm"; | ||
| import PatientIdentifierConfigList from "@/pages/settings/patientIdentifierConfig/PatientIdentifierConfigList"; | ||
|
|
||
| const INSTANCE_SCOPE = { | ||
| authContext: "instance", | ||
| basePath: "/admin/questionnaires", | ||
| } as const; | ||
|
|
||
| const AdminRoutes: AppRoutes = { | ||
| "/admin/questionnaire": () => <QuestionnaireList />, | ||
| "/admin/questionnaire/create": () => <QuestionnaireEditor />, | ||
| "/admin/questionnaire/:slug/edit": ({ slug }) => ( | ||
| <QuestionnaireEditor slug={slug} /> | ||
| "/admin/questionnaires": () => ( | ||
| <QuestionnaireListPage scope={INSTANCE_SCOPE} /> | ||
| ), | ||
| // Must be registered before "/admin/questionnaires/:id" — raviger matches | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Routing correctness depending on JavaScript object property insertion order is fragile. The comment explains why, which is good, but the design is the problem. This is a footgun waiting to go off the next time someone does |
||
| // routes in object order, and "new" would otherwise be captured as an :id. | ||
| "/admin/questionnaires/new": () => ( | ||
| <QuestionnaireCreatePage scope={INSTANCE_SCOPE} /> | ||
| ), | ||
| // Must be registered before "/admin/questionnaires/:id" for the same | ||
| // reason — otherwise "edit" would be captured as an :id. | ||
| "/admin/questionnaires/:id/edit": ({ id }) => ( | ||
| <QuestionnaireBuilderPage scope={INSTANCE_SCOPE} id={id} /> | ||
| ), | ||
| // Registered before "/admin/questionnaires/:id" like the routes above. | ||
| "/admin/questionnaires/:id/versions/:revisionId": ({ id, revisionId }) => ( | ||
| <QuestionnaireRevisionPage | ||
| scope={INSTANCE_SCOPE} | ||
| id={id} | ||
| revisionId={revisionId} | ||
| /> | ||
| ), | ||
| "/admin/questionnaires/:id": ({ id }) => ( | ||
| <QuestionnaireDetailPage scope={INSTANCE_SCOPE} id={id} /> | ||
| ), | ||
| "/admin/valuesets": () => <ValueSetList />, | ||
| "/admin/valuesets/create": () => ( | ||
| <ValueSetEditor onSuccess={() => navigate(`/admin/valuesets`)} /> | ||
| ), | ||
| "/admin/valuesets/:slug/edit": ({ slug }) => <ValueSetEditor slug={slug} />, | ||
| "/admin/valuesets/:id/edit": ({ id }) => <ValueSetEditor id={id} />, | ||
| "/admin/patient_identifier_config": () => <PatientIdentifierConfigList />, | ||
| "/admin/patient_identifier_config/new": () => <PatientIdentifierConfigForm />, | ||
| "/admin/patient_identifier_config/:id": ({ id }) => ( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,7 @@ import { | |
| RotateCcw, | ||
| Users, | ||
| } from "lucide-react"; | ||
| import { useCallback, useEffect, useMemo, useState } from "react"; | ||
| import { useCallback, useMemo, useState } from "react"; | ||
|
|
||
| import { PLUGIN_Component } from "@/PluginEngine"; | ||
| import query from "@/Utils/request/query"; | ||
|
|
@@ -85,11 +85,15 @@ export function EncounterCommandDialog({ | |
| }), | ||
| }); | ||
|
|
||
| useEffect(() => { | ||
| if (!open) { | ||
| setSearch(""); | ||
| } | ||
| }, [open]); | ||
| const handleOpenChange = useCallback( | ||
| (nextOpen: boolean) => { | ||
| if (!nextOpen) { | ||
| setSearch(""); | ||
| } | ||
| onOpenChange(nextOpen); | ||
| }, | ||
| [onOpenChange], | ||
| ); | ||
|
|
||
| const getShortcutDisplay = useShortcutDisplay(); | ||
|
|
||
|
|
@@ -182,8 +186,8 @@ export function EncounterCommandDialog({ | |
|
|
||
| // Handle dynamic questionnaire actions | ||
| if (actionId.startsWith("questionnaire-")) { | ||
| const slug = actionId.replace("questionnaire-", ""); | ||
| navigate(buildEncounterUrl(`/questionnaire/${slug}`)); | ||
| const questionnaireId = actionId.replace("questionnaire-", ""); | ||
| navigate(buildEncounterUrl(`/questionnaire/${questionnaireId}`)); | ||
| } | ||
| }, | ||
| [navigate, buildEncounterUrl, actions, encounter], | ||
|
|
@@ -407,10 +411,10 @@ export function EncounterCommandDialog({ | |
| group: t("questionnaire"), | ||
| items: [ | ||
| ...(questionnaires?.results || []).map((option) => ({ | ||
| id: `questionnaire-${option.slug}`, | ||
| id: `questionnaire-${option.id}`, | ||
| label: option.title, | ||
| icon: <NotebookPen />, | ||
| shortcut: getShortcutDisplay(`questionnaire-${option.slug}`), | ||
| shortcut: getShortcutDisplay(`questionnaire-${option.id}`), | ||
| })), | ||
| ], | ||
| }); | ||
|
|
@@ -420,12 +424,10 @@ export function EncounterCommandDialog({ | |
| }, [ | ||
| t, | ||
| questionnaires, | ||
| search, | ||
| getShortcutDisplay, | ||
| canWriteSelectedEncounter, | ||
| canRestartSelectedEncounter, | ||
| encounter.encounter_class, | ||
| encounter.status, | ||
| encounter, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You replaced |
||
| ]); | ||
|
|
||
| const findRecentActions = useCallback( | ||
|
|
@@ -459,9 +461,9 @@ export function EncounterCommandDialog({ | |
| (actionId: string) => { | ||
| addRecentAction(actionId); | ||
| handleAction(actionId); | ||
| onOpenChange(false); | ||
| handleOpenChange(false); | ||
| }, | ||
| [handleAction, onOpenChange, addRecentAction], | ||
| [handleAction, handleOpenChange, addRecentAction], | ||
| ); | ||
|
|
||
| const careApps = useCareApps(); | ||
|
|
@@ -471,7 +473,7 @@ export function EncounterCommandDialog({ | |
| {trigger} | ||
| <CommandDialog | ||
| open={open} | ||
| onOpenChange={onOpenChange} | ||
| onOpenChange={handleOpenChange} | ||
| className="md:max-w-2xl" | ||
| > | ||
| <div className="border-b border-gray-100 shadow-xs"> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the questionnaire API performs the ID-based lookup introduced by this commit, existing callers that still put slugs in this route will pass the slug through as
questionnaireIdand receive the not-found state. In particular, the enable-when Playwright suites navigate to.../questionnaire/${QUESTIONNAIRE_SLUG}, whiletests/setup/questionnaire.setup.tsalso reads and updates the fixture through slug-based detail URLs. Update those flows to retain the created questionnaire ID, or provide an explicit slug-to-ID compatibility path; otherwise these existing questionnaire scenarios break under the new lookup semantics.Useful? React with 👍 / 👎.