uhc-portal-components-react 0.1.46 → 0.1.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/README.md +7 -0
- package/dist/ClinicalArtifactEditor.d.ts +4 -1
- package/dist/ClinicalArtifactEditor.d.ts.map +1 -1
- package/dist/ClinicalArtifactEditor.js +6 -3
- package/dist/ClinicalArtifactEditorV2.d.ts +74 -0
- package/dist/ClinicalArtifactEditorV2.d.ts.map +1 -0
- package/dist/ClinicalArtifactEditorV2.js +78 -0
- package/dist/ClinicalArtifactPropertiesV2.d.ts +82 -0
- package/dist/ClinicalArtifactPropertiesV2.d.ts.map +1 -0
- package/dist/ClinicalArtifactPropertiesV2.js +95 -0
- package/dist/ClinicalBundleDraftEditor.d.ts +17 -2
- package/dist/ClinicalBundleDraftEditor.d.ts.map +1 -1
- package/dist/ClinicalBundleDraftEditor.js +18 -6
- package/dist/ImmunizationArtifactEditorV2.d.ts +14 -0
- package/dist/ImmunizationArtifactEditorV2.d.ts.map +1 -0
- package/dist/ImmunizationArtifactEditorV2.js +58 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/styles.css +27 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.1.48 - 2026-10-08
|
|
6
|
+
|
|
7
|
+
- Add an opt-in V2 clinical authoring shell without changing the existing V1
|
|
8
|
+
editor. Its reusable date/time, coded-concept, coded-select, positive-integer,
|
|
9
|
+
document-reference and progressive optional-field properties support
|
|
10
|
+
resource-specific editors.
|
|
11
|
+
- Add `ImmunizationArtifactEditorV2` with a minimal initial form, explicit
|
|
12
|
+
terminology search and selection, locked canonical coding, removable
|
|
13
|
+
optional flat claims, dose-series validation and automatic next-dose
|
|
14
|
+
ImmunizationRecommendation staging.
|
|
15
|
+
|
|
16
|
+
## 0.1.47 - 2026-10-08
|
|
17
|
+
|
|
18
|
+
- Show the localized FHIR resource type in the shared Bundle selector and in
|
|
19
|
+
the clinical-entry dialog so users always know which resource they are
|
|
20
|
+
adding.
|
|
21
|
+
- Keep terminology lookup on the human-readable clinical concept while hiding
|
|
22
|
+
the legacy split code-system and code-value inputs when the canonical coded
|
|
23
|
+
claim is available.
|
|
24
|
+
- Render governed coded options, including Observation categories, with their
|
|
25
|
+
localized display and a compact system/code suffix while persisting the full
|
|
26
|
+
canonical token.
|
|
27
|
+
|
|
5
28
|
## 0.1.46 - 2026-10-08
|
|
6
29
|
|
|
7
30
|
- Create clinical Bundle entries through explicit section and resource-type
|
package/README.md
CHANGED
|
@@ -86,6 +86,13 @@ The package deliberately exposes modules instead of a cloned application:
|
|
|
86
86
|
terminology candidate preserves source text and adds only the confirmed
|
|
87
87
|
`system|code` and display. Success requires a fresh provider readback Bundle;
|
|
88
88
|
local form state is never presented as a persisted write.
|
|
89
|
+
- `ClinicalArtifactEditorV2` is an explicit opt-in progressive shell; it does
|
|
90
|
+
not replace `ClinicalArtifactEditor`. Resource specializations such as
|
|
91
|
+
`ImmunizationArtifactEditorV2` compose reusable `DateTimePropertyV2`,
|
|
92
|
+
`CodedConceptPropertyV2`, `CodedSelectPropertyV2`,
|
|
93
|
+
`PositiveIntegerPropertyV2`, `DocumentReferencesPropertyV2` and
|
|
94
|
+
`OptionalFieldsV2` controls. `ClinicalBundleDraftEditorV2` uses a V2
|
|
95
|
+
specialization only when one exists and retains V1 for other resources.
|
|
89
96
|
- `ClinicalSpeechInputProvider`: lets the owning portal publish one
|
|
90
97
|
speech-recognition capability and model phase to every nested clinical
|
|
91
98
|
editor. Compatible IPS text fields show an accessible microphone only when
|
|
@@ -90,6 +90,7 @@ export type ClinicalTerminologySourceSearch = (input: Readonly<{
|
|
|
90
90
|
export type ClinicalArtifactEditorCopy = Readonly<{
|
|
91
91
|
title: string;
|
|
92
92
|
description: string;
|
|
93
|
+
resourceType?: string;
|
|
93
94
|
save: string;
|
|
94
95
|
saving: string;
|
|
95
96
|
cancel: string;
|
|
@@ -128,6 +129,7 @@ export type ClinicalArtifactEditorProps = Readonly<{
|
|
|
128
129
|
timeZone?: string;
|
|
129
130
|
taxonomyId?: string;
|
|
130
131
|
fieldLabel: (claim: string) => string;
|
|
132
|
+
resourceTypeLabel?: string;
|
|
131
133
|
searchTerminology?: (input: ClinicalTerminologySearch) => Promise<readonly ClinicalTerminologyCandidate[]>;
|
|
132
134
|
loadTerminologySources?: ClinicalTerminologySourceSearch;
|
|
133
135
|
saveArtifact: (draft: ClinicalArtifactDraft) => Promise<ClinicalResourceBundleLike | ClinicalArtifactSaveOutcome | undefined>;
|
|
@@ -139,5 +141,6 @@ export type ClinicalArtifactEditorProps = Readonly<{
|
|
|
139
141
|
* persistence and terminology service access. A successful form submission is
|
|
140
142
|
* published only after the host returns a fresh provider readback Bundle.
|
|
141
143
|
*/
|
|
142
|
-
export declare function ClinicalArtifactEditor({ request, schema, operationSchema, authoringContext, copy, locale, timeZone, taxonomyId, fieldLabel, searchTerminology, loadTerminologySources, saveArtifact, onCancel, onReadback, }: ClinicalArtifactEditorProps): import("react").JSX.Element;
|
|
144
|
+
export declare function ClinicalArtifactEditor({ request, schema, operationSchema, authoringContext, copy, locale, timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, saveArtifact, onCancel, onReadback, }: ClinicalArtifactEditorProps): import("react").JSX.Element;
|
|
145
|
+
export declare function readClinicalAttachment(file: File): Promise<ClinicalArtifactAttachment>;
|
|
143
146
|
//# sourceMappingURL=ClinicalArtifactEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClinicalArtifactEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditor.tsx"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ClinicalArtifactEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ import { ClinicalSpeechInputButton } from './ClinicalSpeechInput.js';
|
|
|
10
10
|
* persistence and terminology service access. A successful form submission is
|
|
11
11
|
* published only after the host returns a fresh provider readback Bundle.
|
|
12
12
|
*/
|
|
13
|
-
export function ClinicalArtifactEditor({ request, schema, operationSchema, authoringContext, copy, locale = 'en', timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone, taxonomyId, fieldLabel, searchTerminology, loadTerminologySources, saveArtifact, onCancel, onReadback, }) {
|
|
13
|
+
export function ClinicalArtifactEditor({ request, schema, operationSchema, authoringContext, copy, locale = 'en', timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, saveArtifact, onCancel, onReadback, }) {
|
|
14
14
|
const titleId = useId();
|
|
15
15
|
const descriptionId = useId();
|
|
16
16
|
const acceptedClaims = useMemo(() => operationSchema
|
|
@@ -163,7 +163,7 @@ export function ClinicalArtifactEditor({ request, schema, operationSchema, autho
|
|
|
163
163
|
return next.length ? next : current;
|
|
164
164
|
});
|
|
165
165
|
}
|
|
166
|
-
return _jsx(ClinicalEditorLayer, { onDismiss: onCancel, children: _jsxs("section", { className: "uhcp-clinical-editor", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": descriptionId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: titleId, children: copy.title }), _jsx("p", { id: descriptionId, children: copy.description })] }), _jsx("button", { type: "button", onClick: onCancel, "aria-label": copy.close, children: "\u00D7" })] }), _jsxs("form", { onSubmit: (event) => { event.preventDefault(); void submit(); }, children: [fields.map((claim) => {
|
|
166
|
+
return _jsx(ClinicalEditorLayer, { onDismiss: onCancel, children: _jsxs("section", { className: "uhcp-clinical-editor", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, "aria-describedby": descriptionId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: titleId, children: copy.title }), _jsxs("p", { className: "uhcp-clinical-editor-resource-type", children: [copy.resourceType || 'FHIR resource', ": ", resourceTypeLabel || request.resourceType] }), _jsx("p", { id: descriptionId, children: copy.description })] }), _jsx("button", { type: "button", onClick: onCancel, "aria-label": copy.close, children: "\u00D7" })] }), _jsxs("form", { onSubmit: (event) => { event.preventDefault(); void submit(); }, children: [fields.map((claim) => {
|
|
167
167
|
const parameter = claim.slice(request.resourceType.length + 1);
|
|
168
168
|
const label = fieldLabel(claim);
|
|
169
169
|
const terminologyEnabled = Boolean(searchTerminology && terminologyCodeClaim(request.resourceType, claim));
|
|
@@ -201,7 +201,7 @@ export function ClinicalArtifactEditor({ request, schema, operationSchema, autho
|
|
|
201
201
|
}).catch((reason) => setError(reason instanceof Error ? reason.message : String(reason)));
|
|
202
202
|
} })] }), attachments.length ? _jsx("ul", { children: attachments.map((attachment) => _jsxs("li", { children: [_jsx("span", { children: attachment.name }), _jsx("button", { type: "button", "aria-label": `${copy.removeAttachment || 'Remove document'} ${attachment.name}`, onClick: () => setAttachments(current => current.filter(candidate => candidate.id !== attachment.id)), children: "\u00D7" })] }, attachment.id)) }) : null] }), error ? _jsx("p", { className: "uhcp-clinical-editor-error", role: "alert", children: error }) : null, pending ? _jsx("p", { className: "uhcp-clinical-editor-pending", role: "status", children: copy.pending || pending }) : null, _jsxs("footer", { children: [_jsx("button", { type: "button", onClick: onCancel, children: copy.cancel }), _jsx("button", { type: "submit", disabled: saving, children: saving ? copy.saving : pending ? (copy.retry || copy.save) : copy.save })] })] })] }) });
|
|
203
203
|
}
|
|
204
|
-
async function readClinicalAttachment(file) {
|
|
204
|
+
export async function readClinicalAttachment(file) {
|
|
205
205
|
const contentType = normalizeClinicalAttachmentType(file);
|
|
206
206
|
const bytes = new Uint8Array(await readFileBytes(file));
|
|
207
207
|
const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', bytes));
|
|
@@ -351,6 +351,9 @@ function isHiddenCodingCompanion(resourceType, claim, acceptedClaims) {
|
|
|
351
351
|
return true;
|
|
352
352
|
if (acceptedClaims.includes(`${claim}-text`))
|
|
353
353
|
return true;
|
|
354
|
+
const canonicalCodingClaim = claim.replace(/-(?:system|value)$/, '');
|
|
355
|
+
if (canonicalCodingClaim !== claim && acceptedClaims.includes(canonicalCodingClaim) && acceptedClaims.includes(`${canonicalCodingClaim}-text`))
|
|
356
|
+
return true;
|
|
354
357
|
return resourceType === 'MedicationStatement' && claim === 'MedicationStatement.code'
|
|
355
358
|
&& acceptedClaims.includes('MedicationStatement.medication-text');
|
|
356
359
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ClinicalResourceBundleLike } from 'gdc-common-utils-ts/utils/clinical-resource-view';
|
|
2
|
+
import { type ClinicalPropertyOptionV2 } from './ClinicalArtifactPropertiesV2.js';
|
|
3
|
+
import type { ClinicalArtifactAuthoringContext, ClinicalArtifactDraft, ClinicalArtifactEditorRequest, ClinicalArtifactSaveOutcome, ClinicalTerminologyCandidate, ClinicalTerminologySearch, ClinicalTerminologySourceSearch } from './ClinicalArtifactEditor.js';
|
|
4
|
+
export type ClinicalArtifactRelatedEntryV2 = Readonly<{
|
|
5
|
+
entryId: string;
|
|
6
|
+
resourceType: string;
|
|
7
|
+
claims: Readonly<Record<string, string>>;
|
|
8
|
+
sectionCode?: string;
|
|
9
|
+
}>;
|
|
10
|
+
export type ClinicalArtifactDraftV2 = ClinicalArtifactDraft & Readonly<{
|
|
11
|
+
relatedEntries?: readonly ClinicalArtifactRelatedEntryV2[];
|
|
12
|
+
}>;
|
|
13
|
+
export type ClinicalArtifactFieldV2 = Readonly<{
|
|
14
|
+
claim: string;
|
|
15
|
+
kind: 'text' | 'date' | 'date-time' | 'positive-integer' | 'coded-select' | 'coded-concept' | 'documents';
|
|
16
|
+
required?: boolean;
|
|
17
|
+
transient?: boolean;
|
|
18
|
+
options?: readonly ClinicalPropertyOptionV2[];
|
|
19
|
+
textClaim?: string;
|
|
20
|
+
codeClaim?: string;
|
|
21
|
+
displayClaim?: string;
|
|
22
|
+
}>;
|
|
23
|
+
export type ClinicalArtifactEditorCopyV2 = Readonly<{
|
|
24
|
+
title: string;
|
|
25
|
+
description: string;
|
|
26
|
+
resourceType?: string;
|
|
27
|
+
save: string;
|
|
28
|
+
saving: string;
|
|
29
|
+
cancel: string;
|
|
30
|
+
close: string;
|
|
31
|
+
terminologyLoading: string;
|
|
32
|
+
terminologyUnavailable: string;
|
|
33
|
+
terminologySources: string;
|
|
34
|
+
readbackMissing: string;
|
|
35
|
+
addField: string;
|
|
36
|
+
chooseField: string;
|
|
37
|
+
addSelectedField: string;
|
|
38
|
+
removeField: string;
|
|
39
|
+
searchTerminology: string;
|
|
40
|
+
clearCoding: string;
|
|
41
|
+
selectCandidate: string;
|
|
42
|
+
canonicalCode: string;
|
|
43
|
+
canonicalDisplay: string;
|
|
44
|
+
documents: string;
|
|
45
|
+
addDocuments: string;
|
|
46
|
+
removeDocument: string;
|
|
47
|
+
date: string;
|
|
48
|
+
time: string;
|
|
49
|
+
useToday: string;
|
|
50
|
+
useCurrentTime: string;
|
|
51
|
+
}>;
|
|
52
|
+
export type ClinicalArtifactEditorV2Props = Readonly<{
|
|
53
|
+
request: ClinicalArtifactEditorRequest;
|
|
54
|
+
authoringContext: ClinicalArtifactAuthoringContext;
|
|
55
|
+
copy: ClinicalArtifactEditorCopyV2;
|
|
56
|
+
fields: readonly ClinicalArtifactFieldV2[];
|
|
57
|
+
initialVisibleClaims: readonly string[];
|
|
58
|
+
initialClaims?: Readonly<Record<string, string>>;
|
|
59
|
+
locale?: string;
|
|
60
|
+
timeZone?: string;
|
|
61
|
+
taxonomyId?: string;
|
|
62
|
+
fieldLabel: (claim: string) => string;
|
|
63
|
+
resourceTypeLabel?: string;
|
|
64
|
+
searchTerminology?: (input: ClinicalTerminologySearch) => Promise<readonly ClinicalTerminologyCandidate[]>;
|
|
65
|
+
loadTerminologySources?: ClinicalTerminologySourceSearch;
|
|
66
|
+
validate?: (claims: Readonly<Record<string, string>>) => void;
|
|
67
|
+
buildRelatedEntries?: (claims: Readonly<Record<string, string>>, draftId: string) => readonly ClinicalArtifactRelatedEntryV2[];
|
|
68
|
+
saveArtifact: (draft: ClinicalArtifactDraftV2) => Promise<ClinicalResourceBundleLike | ClinicalArtifactSaveOutcome | undefined>;
|
|
69
|
+
onCancel: () => void;
|
|
70
|
+
onReadback: (bundle: ClinicalResourceBundleLike) => void;
|
|
71
|
+
}>;
|
|
72
|
+
/** Progressive reusable V2 shell. Resource rules are supplied by a specialized editor. */
|
|
73
|
+
export declare function ClinicalArtifactEditorV2({ request, authoringContext, copy, fields, initialVisibleClaims, initialClaims, locale, timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, validate, buildRelatedEntries, saveArtifact, onCancel, onReadback }: ClinicalArtifactEditorV2Props): import("react").JSX.Element;
|
|
74
|
+
//# sourceMappingURL=ClinicalArtifactEditorV2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClinicalArtifactEditorV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditorV2.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useId, useRef, useState } from 'react';
|
|
4
|
+
import { ClinicalEditorLayer } from './ClinicalEditorLayer.js';
|
|
5
|
+
import { readClinicalAttachment } from './ClinicalArtifactEditor.js';
|
|
6
|
+
import { CodedConceptPropertyV2, CodedSelectPropertyV2, DateTimePropertyV2, DocumentReferencesPropertyV2, OptionalFieldsV2, PositiveIntegerPropertyV2, } from './ClinicalArtifactPropertiesV2.js';
|
|
7
|
+
/** Progressive reusable V2 shell. Resource rules are supplied by a specialized editor. */
|
|
8
|
+
export function ClinicalArtifactEditorV2({ request, authoringContext, copy, fields, initialVisibleClaims, initialClaims = {}, locale = 'en', timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, validate, buildRelatedEntries, saveArtifact, onCancel, onReadback }) {
|
|
9
|
+
const titleId = useId();
|
|
10
|
+
const [claims, setClaims] = useState({ ...initialClaims, ...stringClaims(request.initialClaims) });
|
|
11
|
+
const [visibleClaims, setVisibleClaims] = useState(() => [...new Set([...initialVisibleClaims, ...Object.keys(request.initialClaims ?? {}).filter(claim => fields.some(field => field.claim === claim))])]);
|
|
12
|
+
const [selectedOptional, setSelectedOptional] = useState('');
|
|
13
|
+
const [saving, setSaving] = useState(false);
|
|
14
|
+
const [attachments, setAttachments] = useState(request.initialAttachments ?? []);
|
|
15
|
+
const [error, setError] = useState('');
|
|
16
|
+
const draftId = useRef(request.artifactId ?? crypto.randomUUID());
|
|
17
|
+
const optional = fields.filter(field => !field.required && !visibleClaims.includes(field.claim)).map(field => ({ value: field.claim, label: fieldLabel(field.claim) }));
|
|
18
|
+
const update = (claim, value) => setClaims(current => ({ ...current, [claim]: value }));
|
|
19
|
+
async function submit() {
|
|
20
|
+
setError('');
|
|
21
|
+
try {
|
|
22
|
+
validate?.(claims);
|
|
23
|
+
setSaving(true);
|
|
24
|
+
const draft = {
|
|
25
|
+
resourceType: request.resourceType,
|
|
26
|
+
id: draftId.current,
|
|
27
|
+
sectionCode: request.sectionCode,
|
|
28
|
+
mode: request.mode,
|
|
29
|
+
claims: cleanClaims(claims, fields),
|
|
30
|
+
attachments,
|
|
31
|
+
relatedEntries: buildRelatedEntries?.(claims, draftId.current) ?? [],
|
|
32
|
+
};
|
|
33
|
+
const result = await saveArtifact(draft);
|
|
34
|
+
if (!result)
|
|
35
|
+
throw new Error(copy.readbackMissing);
|
|
36
|
+
if ('state' in result) {
|
|
37
|
+
if (result.state === 'confirmed')
|
|
38
|
+
onReadback(result.bundle);
|
|
39
|
+
else if (result.state === 'rejected')
|
|
40
|
+
throw new Error(result.message);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
onReadback(result);
|
|
44
|
+
}
|
|
45
|
+
catch (reason) {
|
|
46
|
+
setError(reason instanceof Error ? reason.message : String(reason));
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
setSaving(false);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return _jsx(ClinicalEditorLayer, { onDismiss: onCancel, children: _jsxs("section", { className: "uhcp-clinical-editor uhcp-clinical-editor-v2", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { id: titleId, children: copy.title }), _jsxs("p", { className: "uhcp-clinical-editor-resource-type", children: [copy.resourceType || 'FHIR resource', ": ", resourceTypeLabel || request.resourceType] }), _jsx("p", { children: copy.description })] }), _jsx("button", { type: "button", "aria-label": copy.close, onClick: onCancel, children: "\u00D7" })] }), _jsxs("form", { onSubmit: event => { event.preventDefault(); void submit(); }, children: [fields.filter(field => visibleClaims.includes(field.claim)).map(field => _jsxs("div", { className: "uhcp-progressive-field-v2", children: [!field.required ? _jsx("button", { type: "button", className: "uhcp-remove-field-v2", "aria-label": `${copy.removeField}: ${fieldLabel(field.claim)}`, onClick: () => { setVisibleClaims(current => current.filter(claim => claim !== field.claim)); if (field.kind === 'documents')
|
|
53
|
+
setAttachments([]); setClaims(current => { const next = { ...current }; delete next[field.claim]; if (field.codeClaim)
|
|
54
|
+
delete next[field.codeClaim]; if (field.displayClaim)
|
|
55
|
+
delete next[field.displayClaim]; return next; }); }, children: "\u00D7" }) : null, field.kind === 'documents' ? _jsx(DocumentReferencesPropertyV2, { copy: copy, attachments: attachments, onFiles: files => { void Promise.all(files.map(readClinicalAttachment)).then(next => setAttachments(current => [...current, ...next])).catch(reason => setError(reason instanceof Error ? reason.message : String(reason))); }, onRemove: id => setAttachments(current => current.filter(attachment => attachment.id !== id)) })
|
|
56
|
+
: _jsx(ClinicalProperty, { field: field, label: fieldLabel(field.claim), resourceType: request.resourceType, value: claims[field.claim] ?? '', claims: claims, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, copy: copy, update: update, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources })] }, field.claim)), _jsx(OptionalFieldsV2, { label: copy.addField, choose: copy.chooseField, add: copy.addSelectedField, options: optional, value: selectedOptional, onValueChange: setSelectedOptional, onAdd: () => { if (!selectedOptional)
|
|
57
|
+
return; setVisibleClaims(current => [...current, selectedOptional]); setSelectedOptional(''); } }), error ? _jsx("p", { className: "uhcp-clinical-editor-error", role: "alert", children: error }) : null, _jsxs("footer", { children: [_jsx("button", { type: "button", onClick: onCancel, children: copy.cancel }), _jsx("button", { type: "submit", disabled: saving, children: saving ? copy.saving : copy.save })] })] })] }) });
|
|
58
|
+
}
|
|
59
|
+
function ClinicalProperty({ field, label, resourceType, value, claims, locale, timeZone, taxonomyId, copy, update, searchTerminology, loadTerminologySources }) {
|
|
60
|
+
if (field.kind === 'date-time')
|
|
61
|
+
return _jsx(DateTimePropertyV2, { label: label, value: value, required: field.required, locale: locale, timeZone: timeZone, copy: copy, onChange: next => update(field.claim, next) });
|
|
62
|
+
if (field.kind === 'date')
|
|
63
|
+
return _jsxs("label", { className: "uhcp-clinical-property-v2", children: [label, field.required ? ' *' : '', _jsx("input", { "aria-label": label, type: "date", required: field.required, value: value, onChange: event => update(field.claim, event.currentTarget.value) })] });
|
|
64
|
+
if (field.kind === 'positive-integer')
|
|
65
|
+
return _jsx(PositiveIntegerPropertyV2, { label: label, value: value, required: field.required, onChange: next => update(field.claim, next) });
|
|
66
|
+
if (field.kind === 'coded-select')
|
|
67
|
+
return _jsx(CodedSelectPropertyV2, { label: label, value: value, required: field.required, options: field.options ?? [], onChange: next => update(field.claim, next) });
|
|
68
|
+
if (field.kind === 'coded-concept' && field.codeClaim)
|
|
69
|
+
return _jsx(CodedConceptPropertyV2, { resourceType: resourceType, textClaim: field.textClaim, codeClaim: field.codeClaim, displayClaim: field.displayClaim, label: label, locale: locale, taxonomyId: taxonomyId, text: field.textClaim ? claims[field.textClaim] ?? '' : '', code: claims[field.codeClaim] ?? '', display: field.displayClaim ? claims[field.displayClaim] ?? '' : '', required: field.required, copy: copy, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, onChange: next => { if (field.textClaim)
|
|
70
|
+
update(field.textClaim, next.text); update(field.codeClaim, next.code); if (field.displayClaim)
|
|
71
|
+
update(field.displayClaim, next.display); } });
|
|
72
|
+
return _jsxs("label", { className: "uhcp-clinical-property-v2", children: [label, field.required ? ' *' : '', _jsx("input", { "aria-label": label, required: field.required, value: value, onChange: event => update(field.claim, event.currentTarget.value) })] });
|
|
73
|
+
}
|
|
74
|
+
function stringClaims(value) { return Object.fromEntries(Object.entries(value ?? {}).map(([claim, item]) => [claim, String(item ?? '')])); }
|
|
75
|
+
function cleanClaims(value, fields) {
|
|
76
|
+
const transient = new Set(fields.filter(field => field.transient).map(field => field.claim));
|
|
77
|
+
return Object.fromEntries(Object.entries(value).filter(([claim, item]) => item !== '' && !transient.has(claim)));
|
|
78
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { ClinicalArtifactAttachment, ClinicalTerminologyCandidate, ClinicalTerminologySearch, ClinicalTerminologySourceSearch } from './ClinicalArtifactEditor.js';
|
|
2
|
+
export type ClinicalPropertyOptionV2 = Readonly<{
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare function DateTimePropertyV2({ label, value, required, locale, timeZone, copy, onChange }: Readonly<{
|
|
7
|
+
label: string;
|
|
8
|
+
value: string;
|
|
9
|
+
required?: boolean;
|
|
10
|
+
locale: string;
|
|
11
|
+
timeZone: string;
|
|
12
|
+
copy: Readonly<{
|
|
13
|
+
date: string;
|
|
14
|
+
time: string;
|
|
15
|
+
useToday: string;
|
|
16
|
+
useCurrentTime: string;
|
|
17
|
+
}>;
|
|
18
|
+
onChange: (value: string) => void;
|
|
19
|
+
}>): import("react").JSX.Element;
|
|
20
|
+
export declare function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, displayClaim, label, locale, taxonomyId, text, code, display, required, copy, searchTerminology, loadTerminologySources, onChange }: Readonly<{
|
|
21
|
+
resourceType: string;
|
|
22
|
+
textClaim?: string;
|
|
23
|
+
codeClaim: string;
|
|
24
|
+
displayClaim?: string;
|
|
25
|
+
label: string;
|
|
26
|
+
locale: string;
|
|
27
|
+
taxonomyId?: string;
|
|
28
|
+
text: string;
|
|
29
|
+
code: string;
|
|
30
|
+
display: string;
|
|
31
|
+
required?: boolean;
|
|
32
|
+
copy: Readonly<{
|
|
33
|
+
searchTerminology: string;
|
|
34
|
+
terminologyLoading: string;
|
|
35
|
+
terminologyUnavailable: string;
|
|
36
|
+
terminologySources: string;
|
|
37
|
+
selectCandidate: string;
|
|
38
|
+
clearCoding: string;
|
|
39
|
+
canonicalCode: string;
|
|
40
|
+
canonicalDisplay: string;
|
|
41
|
+
}>;
|
|
42
|
+
searchTerminology?: (input: ClinicalTerminologySearch) => Promise<readonly ClinicalTerminologyCandidate[]>;
|
|
43
|
+
loadTerminologySources?: ClinicalTerminologySourceSearch;
|
|
44
|
+
onChange: (value: Readonly<{
|
|
45
|
+
text: string;
|
|
46
|
+
code: string;
|
|
47
|
+
display: string;
|
|
48
|
+
}>) => void;
|
|
49
|
+
}>): import("react").JSX.Element;
|
|
50
|
+
export declare function CodedSelectPropertyV2({ label, value, required, options, onChange }: Readonly<{
|
|
51
|
+
label: string;
|
|
52
|
+
value: string;
|
|
53
|
+
required?: boolean;
|
|
54
|
+
options: readonly ClinicalPropertyOptionV2[];
|
|
55
|
+
onChange: (value: string) => void;
|
|
56
|
+
}>): import("react").JSX.Element;
|
|
57
|
+
export declare function PositiveIntegerPropertyV2({ label, value, required, onChange }: Readonly<{
|
|
58
|
+
label: string;
|
|
59
|
+
value: string;
|
|
60
|
+
required?: boolean;
|
|
61
|
+
onChange: (value: string) => void;
|
|
62
|
+
}>): import("react").JSX.Element;
|
|
63
|
+
export declare function OptionalFieldsV2({ label, choose, add, options, value, onValueChange, onAdd }: Readonly<{
|
|
64
|
+
label: string;
|
|
65
|
+
choose: string;
|
|
66
|
+
add: string;
|
|
67
|
+
options: readonly ClinicalPropertyOptionV2[];
|
|
68
|
+
value: string;
|
|
69
|
+
onValueChange: (value: string) => void;
|
|
70
|
+
onAdd: () => void;
|
|
71
|
+
}>): import("react").JSX.Element | null;
|
|
72
|
+
export declare function DocumentReferencesPropertyV2({ copy, attachments, onFiles, onRemove }: Readonly<{
|
|
73
|
+
copy: Readonly<{
|
|
74
|
+
documents: string;
|
|
75
|
+
addDocuments: string;
|
|
76
|
+
removeDocument: string;
|
|
77
|
+
}>;
|
|
78
|
+
attachments: readonly ClinicalArtifactAttachment[];
|
|
79
|
+
onFiles: (files: readonly File[]) => void;
|
|
80
|
+
onRemove: (id: string) => void;
|
|
81
|
+
}>): import("react").JSX.Element;
|
|
82
|
+
//# sourceMappingURL=ClinicalArtifactPropertiesV2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClinicalArtifactPropertiesV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactPropertiesV2.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC5B,yBAAyB,EACzB,+BAA+B,EAChC,MAAM,6BAA6B,CAAA;AAEpC,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAEjF,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IACxG,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACxF,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC,CAAC,+BAcD;AAED,wBAAgB,sBAAsB,CAAC,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IACzN,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,QAAQ,CAAC;QAAE,iBAAiB,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAC;QAAC,sBAAsB,EAAE,MAAM,CAAC;QAAC,kBAAkB,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACpO,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,yBAAyB,KAAK,OAAO,CAAC,SAAS,4BAA4B,EAAE,CAAC,CAAA;IAC1G,sBAAsB,CAAC,EAAE,+BAA+B,CAAA;IACxD,QAAQ,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,IAAI,CAAA;CACrF,CAAC,+BAmDD;AAED,wBAAgB,qBAAqB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC,+BAEnO;AAED,wBAAgB,yBAAyB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC,+BAEhL;AAED,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC,sCAG9Q;AAED,wBAAgB,4BAA4B,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC;IAC9F,IAAI,EAAE,QAAQ,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACnF,WAAW,EAAE,SAAS,0BAA0B,EAAE,CAAA;IAClD,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,KAAK,IAAI,CAAA;IACzC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B,CAAC,+BAKD"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
4
|
+
import { composeFhirDateTimeFromLocalParts, splitFhirDateTimeForInput, } from 'fhir-data-utils-ts/fhir-temporal-presentation';
|
|
5
|
+
import { ClinicalSpeechInputButton } from './ClinicalSpeechInput.js';
|
|
6
|
+
export function DateTimePropertyV2({ label, value, required, locale, timeZone, copy, onChange }) {
|
|
7
|
+
const [parts, setParts] = useState(() => splitDateTime(value, timeZone));
|
|
8
|
+
const current = splitFhirDateTimeForInput(new Date(), timeZone);
|
|
9
|
+
const update = (next) => {
|
|
10
|
+
setParts(next);
|
|
11
|
+
onChange(!next.date ? '' : next.time ? composeFhirDateTimeFromLocalParts({ ...next, timeZone }) : next.date);
|
|
12
|
+
};
|
|
13
|
+
return _jsxs("fieldset", { className: "uhcp-clinical-property-v2 uhcp-date-time-property-v2", children: [_jsxs("legend", { children: [label, required ? ' *' : ''] }), _jsxs("label", { children: [_jsx("span", { children: copy.date }), _jsx("input", { "aria-label": `${label}: ${copy.date}`, type: "date", required: required, value: parts.date, onChange: event => update({ ...parts, date: event.currentTarget.value }) })] }), _jsx("button", { type: "button", onClick: () => update({ ...parts, date: current.date }), children: copy.useToday }), _jsxs("label", { children: [_jsx("span", { children: copy.time }), _jsx("input", { "aria-label": `${label}: ${copy.time}`, type: "time", step: "60", value: parts.time.slice(0, 5), onChange: event => update({ ...parts, time: event.currentTarget.value }) })] }), _jsx("button", { type: "button", onClick: () => update({ ...parts, time: current.time.slice(0, 5) }), children: copy.useCurrentTime })] });
|
|
14
|
+
}
|
|
15
|
+
export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, displayClaim, label, locale, taxonomyId, text, code, display, required, copy, searchTerminology, loadTerminologySources, onChange }) {
|
|
16
|
+
const [query, setQuery] = useState(text || display);
|
|
17
|
+
const [sources, setSources] = useState([]);
|
|
18
|
+
const [selectedSources, setSelectedSources] = useState([]);
|
|
19
|
+
const [candidates, setCandidates] = useState([]);
|
|
20
|
+
const [busy, setBusy] = useState(false);
|
|
21
|
+
const [failed, setFailed] = useState(false);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!loadTerminologySources)
|
|
24
|
+
return;
|
|
25
|
+
let current = true;
|
|
26
|
+
void loadTerminologySources({ resourceType, claim: codeClaim, language: locale, taxonomyId }).then(next => {
|
|
27
|
+
if (!current)
|
|
28
|
+
return;
|
|
29
|
+
setSources(next);
|
|
30
|
+
const defaults = next.filter(source => source.default).map(source => source.id);
|
|
31
|
+
setSelectedSources(defaults.length ? defaults : next[0] ? [next[0].id] : []);
|
|
32
|
+
}).catch(() => current && setSources([]));
|
|
33
|
+
return () => { current = false; };
|
|
34
|
+
}, [codeClaim, loadTerminologySources, locale, resourceType, taxonomyId]);
|
|
35
|
+
const selectedToken = useMemo(() => code, [code]);
|
|
36
|
+
const search = async () => {
|
|
37
|
+
if (!searchTerminology || query.trim().length < 2 || busy)
|
|
38
|
+
return;
|
|
39
|
+
setBusy(true);
|
|
40
|
+
setFailed(false);
|
|
41
|
+
try {
|
|
42
|
+
let governedSources = selectedSources;
|
|
43
|
+
if (!governedSources.length && loadTerminologySources) {
|
|
44
|
+
const loaded = await loadTerminologySources({ resourceType, claim: codeClaim, language: locale, taxonomyId });
|
|
45
|
+
const defaults = loaded.filter(source => source.default).map(source => source.id);
|
|
46
|
+
governedSources = defaults.length ? defaults : loaded[0] ? [loaded[0].id] : [];
|
|
47
|
+
setSources(loaded);
|
|
48
|
+
setSelectedSources(governedSources);
|
|
49
|
+
}
|
|
50
|
+
setCandidates(await searchTerminology({ resourceType, claim: codeClaim, language: locale, text: query.trim(), taxonomyId, limit: 20, ...(governedSources.length ? { sources: governedSources } : {}) }));
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
setCandidates([]);
|
|
54
|
+
setFailed(true);
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
setBusy(false);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return _jsxs("div", { className: "uhcp-clinical-property-v2 uhcp-coded-concept-property-v2", children: [_jsxs("span", { className: "uhcp-clinical-editor-field-heading", children: [_jsxs("label", { htmlFor: `${codeClaim}-query`, children: [label, required ? ' *' : ''] }), textClaim ? _jsx(ClinicalSpeechInputButton, { resourceType: resourceType, claim: textClaim, locale: locale, fieldLabel: label, onTranscript: transcript => { setQuery(transcript); onChange({ text: transcript, code: '', display: '' }); } }) : null] }), _jsxs("div", { className: "uhcp-coded-concept-query-v2", children: [_jsx("input", { id: `${codeClaim}-query`, "aria-label": label, required: required, readOnly: Boolean(code), value: code ? (text || query || display) : query, onChange: event => { setQuery(event.currentTarget.value); onChange({ text: event.currentTarget.value, code: '', display: '' }); } }), _jsx("button", { type: "button", className: "uhcp-icon-button-v2", "aria-label": copy.searchTerminology, title: copy.searchTerminology, disabled: Boolean(code) || busy || query.trim().length < 2, onClick: () => void search(), children: _jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", children: _jsx("path", { d: "m21 21-4.35-4.35m1.35-5.65a7 7 0 1 1-14 0 7 7 0 0 1 14 0Z" }) }) }), code ? _jsx("button", { type: "button", className: "uhcp-clear-code-v2", "aria-label": copy.clearCoding, title: copy.clearCoding, onClick: () => { setQuery(''); setCandidates([]); onChange({ text: '', code: '', display: '' }); }, children: "\u00D7" }) : null] }), sources.length ? _jsxs("fieldset", { className: "uhcp-coding-sources-v2", children: [_jsx("legend", { children: copy.terminologySources }), sources.map(source => _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: selectedSources.includes(source.id), onChange: event => setSelectedSources(current => event.currentTarget.checked ? [...new Set([...current, source.id])] : current.filter(value => value !== source.id)) }), source.label || source.id] }, source.id))] }) : null, busy ? _jsx("small", { role: "status", children: copy.terminologyLoading }) : null, failed ? _jsx("small", { role: "alert", children: copy.terminologyUnavailable }) : null, candidates.length ? _jsxs("label", { children: [copy.selectCandidate, _jsxs("select", { "aria-label": copy.selectCandidate, value: selectedToken, onChange: event => {
|
|
61
|
+
const candidate = candidates.find(value => `${value.system}|${value.code}` === event.currentTarget.value);
|
|
62
|
+
if (!candidate)
|
|
63
|
+
return;
|
|
64
|
+
const localText = candidate.text || query || candidate.display;
|
|
65
|
+
setQuery(localText);
|
|
66
|
+
onChange({ text: localText, code: `${candidate.system}|${candidate.code}`, display: candidate.display });
|
|
67
|
+
setCandidates([]);
|
|
68
|
+
}, children: [_jsx("option", { value: "" }), candidates.map(candidate => _jsxs("option", { value: `${candidate.system}|${candidate.code}`, children: [candidate.display, " (", candidate.code, ")"] }, `${candidate.system}|${candidate.code}`))] })] }) : null, code ? _jsxs("div", { className: "uhcp-selected-code-v2", children: [_jsxs("label", { children: [copy.canonicalCode, _jsx("input", { "aria-label": copy.canonicalCode, readOnly: true, value: code })] }), _jsxs("label", { children: [copy.canonicalDisplay, _jsx("input", { "aria-label": copy.canonicalDisplay, readOnly: true, value: display })] })] }) : null] });
|
|
69
|
+
}
|
|
70
|
+
export function CodedSelectPropertyV2({ label, value, required, options, onChange }) {
|
|
71
|
+
return _jsxs("label", { className: "uhcp-clinical-property-v2", children: [label, required ? ' *' : '', _jsxs("select", { "aria-label": label, required: required, value: value, onChange: event => onChange(event.currentTarget.value), children: [_jsx("option", { value: "" }), options.map(option => _jsx("option", { value: option.value, children: option.label }, option.value))] })] });
|
|
72
|
+
}
|
|
73
|
+
export function PositiveIntegerPropertyV2({ label, value, required, onChange }) {
|
|
74
|
+
return _jsxs("label", { className: "uhcp-clinical-property-v2", children: [label, required ? ' *' : '', _jsx("input", { "aria-label": label, type: "number", min: "1", step: "1", required: required, value: value, onChange: event => onChange(event.currentTarget.value) })] });
|
|
75
|
+
}
|
|
76
|
+
export function OptionalFieldsV2({ label, choose, add, options, value, onValueChange, onAdd }) {
|
|
77
|
+
if (!options.length)
|
|
78
|
+
return null;
|
|
79
|
+
return _jsxs("fieldset", { className: "uhcp-optional-fields-v2", children: [_jsx("legend", { children: label }), _jsxs("select", { "aria-label": choose, value: value, onChange: event => onValueChange(event.currentTarget.value), children: [_jsx("option", { value: "", children: choose }), options.map(option => _jsx("option", { value: option.value, children: option.label }, option.value))] }), _jsx("button", { type: "button", disabled: !value, onClick: onAdd, children: add })] });
|
|
80
|
+
}
|
|
81
|
+
export function DocumentReferencesPropertyV2({ copy, attachments, onFiles, onRemove }) {
|
|
82
|
+
return _jsxs("fieldset", { className: "uhcp-clinical-property-v2 uhcp-document-references-property-v2", children: [_jsx("legend", { children: copy.documents }), _jsxs("label", { children: [copy.addDocuments, _jsx("input", { "aria-label": copy.addDocuments, type: "file", multiple: true, accept: "application/pdf,image/png,image/jpeg,.pdf,.png,.jpg,.jpeg", onChange: event => { const files = [...(event.currentTarget.files ?? [])]; event.currentTarget.value = ''; onFiles(files); } })] }), attachments.length ? _jsx("ul", { children: attachments.map(attachment => _jsxs("li", { children: [_jsx("span", { children: attachment.name }), _jsx("button", { type: "button", "aria-label": `${copy.removeDocument}: ${attachment.name}`, onClick: () => onRemove(attachment.id), children: "\u00D7" })] }, attachment.id)) }) : null] });
|
|
83
|
+
}
|
|
84
|
+
function splitDateTime(value, timeZone) {
|
|
85
|
+
if (!value)
|
|
86
|
+
return { date: '', time: '' };
|
|
87
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value))
|
|
88
|
+
return { date: value, time: '' };
|
|
89
|
+
try {
|
|
90
|
+
return splitFhirDateTimeForInput(value, timeZone);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return { date: '', time: '' };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -6,7 +6,8 @@ import 'gdc-common-utils-ts/utils/medication-statement-entry-editor';
|
|
|
6
6
|
import 'gdc-common-utils-ts/utils/observation-entry-editor';
|
|
7
7
|
import 'gdc-common-utils-ts/utils/procedure-entry-editor';
|
|
8
8
|
import type { MultichannelOperationSchema } from 'sos-data-utils-ts/multichannel-operation-schemas';
|
|
9
|
-
import { type ClinicalArtifactAuthoringContext, type ClinicalArtifactEditorCopy, type ClinicalArtifactSchema, type ClinicalTerminologySearch, type ClinicalTerminologyCandidate, type ClinicalTerminologySourceSearch } from './ClinicalArtifactEditor.js';
|
|
9
|
+
import { type ClinicalArtifactAuthoringContext, type ClinicalArtifactDraft, type ClinicalArtifactEditorCopy, type ClinicalArtifactSchema, type ClinicalTerminologySearch, type ClinicalTerminologyCandidate, type ClinicalTerminologySourceSearch } from './ClinicalArtifactEditor.js';
|
|
10
|
+
import { type ImmunizationArtifactEditorCopyV2 } from './ImmunizationArtifactEditorV2.js';
|
|
10
11
|
export type ClinicalBundleDraftSchema = Readonly<{
|
|
11
12
|
schema: ClinicalArtifactSchema;
|
|
12
13
|
operationSchema: MultichannelOperationSchema;
|
|
@@ -45,11 +46,18 @@ export type ClinicalBundleDraftEditorProps = Readonly<{
|
|
|
45
46
|
timeZone?: string;
|
|
46
47
|
taxonomyId?: string;
|
|
47
48
|
fieldLabel: (claim: string) => string;
|
|
49
|
+
resourceTypeLabel?: (resourceType: string) => string;
|
|
48
50
|
searchTerminology?: (input: ClinicalTerminologySearch) => Promise<readonly ClinicalTerminologyCandidate[]>;
|
|
49
51
|
loadTerminologySources?: ClinicalTerminologySourceSearch;
|
|
50
52
|
/** Optional claims-first document Bundle loaded into the local draft; loading it never persists. */
|
|
51
53
|
initialBundle?: ClinicalBundleDraft;
|
|
52
54
|
onSubmitDraft: (bundle: ClinicalBundleDraft) => Promise<ClinicalBundleDraftSubmitOutcome>;
|
|
55
|
+
editorVersion?: 'v1' | 'v2';
|
|
56
|
+
editorV2Copy?: ImmunizationArtifactEditorCopyV2;
|
|
57
|
+
}>;
|
|
58
|
+
type StagedArtifact = Readonly<{
|
|
59
|
+
schema: ClinicalBundleDraftSchema;
|
|
60
|
+
draft: ClinicalArtifactDraft;
|
|
53
61
|
}>;
|
|
54
62
|
/**
|
|
55
63
|
* Shared local-first IPS authoring workspace.
|
|
@@ -58,5 +66,12 @@ export type ClinicalBundleDraftEditorProps = Readonly<{
|
|
|
58
66
|
* It owns no authorization or persistence: the host supplies subject and
|
|
59
67
|
* provenance and only `onSubmitDraft` may cross a persistence boundary.
|
|
60
68
|
*/
|
|
61
|
-
export declare function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale, timeZone, taxonomyId, fieldLabel, searchTerminology, loadTerminologySources, initialBundle, onSubmitDraft, }: ClinicalBundleDraftEditorProps): import("react").JSX.Element;
|
|
69
|
+
export declare function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale, timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onSubmitDraft, editorVersion, editorV2Copy, }: ClinicalBundleDraftEditorProps): import("react").JSX.Element;
|
|
70
|
+
export declare function combineClinicalDrafts(artifacts: readonly StagedArtifact[], authoringContext: ClinicalArtifactAuthoringContext, documentTitle: string): ClinicalBundleDraft;
|
|
71
|
+
export type ClinicalBundleDraftEditorV2Props = Omit<ClinicalBundleDraftEditorProps, 'editorVersion' | 'editorV2Copy'> & Readonly<{
|
|
72
|
+
editorV2Copy: ImmunizationArtifactEditorCopyV2;
|
|
73
|
+
}>;
|
|
74
|
+
/** V2 opt-in wrapper; the original editor remains the default everywhere else. */
|
|
75
|
+
export declare function ClinicalBundleDraftEditorV2(props: ClinicalBundleDraftEditorV2Props): import("react").JSX.Element;
|
|
76
|
+
export {};
|
|
62
77
|
//# sourceMappingURL=ClinicalBundleDraftEditor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClinicalBundleDraftEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalBundleDraftEditor.tsx"],"names":[],"mappings":"AAQA,OAAO,4DAA4D,CAAA;AACnE,OAAO,kDAAkD,CAAA;AACzD,OAAO,2DAA2D,CAAA;AAClE,OAAO,qDAAqD,CAAA;AAC5D,OAAO,6DAA6D,CAAA;AACpE,OAAO,oDAAoD,CAAA;AAC3D,OAAO,kDAAkD,CAAA;AACzD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kDAAkD,CAAA;AACnG,OAAO,EAEL,KAAK,gCAAgC,
|
|
1
|
+
{"version":3,"file":"ClinicalBundleDraftEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalBundleDraftEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ import 'gdc-common-utils-ts/utils/observation-entry-editor';
|
|
|
15
15
|
import 'gdc-common-utils-ts/utils/procedure-entry-editor';
|
|
16
16
|
import { ClinicalArtifactEditor, } from './ClinicalArtifactEditor.js';
|
|
17
17
|
import { ClinicalActionButton } from './ClinicalActionButton.js';
|
|
18
|
+
import { ImmunizationArtifactEditorV2, } from './ImmunizationArtifactEditorV2.js';
|
|
18
19
|
/**
|
|
19
20
|
* Shared local-first IPS authoring workspace.
|
|
20
21
|
*
|
|
@@ -22,7 +23,7 @@ import { ClinicalActionButton } from './ClinicalActionButton.js';
|
|
|
22
23
|
* It owns no authorization or persistence: the host supplies subject and
|
|
23
24
|
* provenance and only `onSubmitDraft` may cross a persistence boundary.
|
|
24
25
|
*/
|
|
25
|
-
export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale = 'en', timeZone, taxonomyId, fieldLabel, searchTerminology, loadTerminologySources, initialBundle, onSubmitDraft, }) {
|
|
26
|
+
export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale = 'en', timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onSubmitDraft, editorVersion = 'v1', editorV2Copy, }) {
|
|
26
27
|
const [artifacts, setArtifacts] = useState(() => importedArtifacts(initialBundle, schemas));
|
|
27
28
|
const [editor, setEditor] = useState();
|
|
28
29
|
const [notice, setNotice] = useState('');
|
|
@@ -49,7 +50,7 @@ export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, loc
|
|
|
49
50
|
setSubmitting(true);
|
|
50
51
|
setError('');
|
|
51
52
|
try {
|
|
52
|
-
const outcome = await onSubmitDraft(
|
|
53
|
+
const outcome = await onSubmitDraft(combineClinicalDrafts(artifacts, authoringContext, copy.title));
|
|
53
54
|
if (outcome.state === 'confirmed') {
|
|
54
55
|
setArtifacts([]);
|
|
55
56
|
setNotice(outcome.message || '');
|
|
@@ -73,13 +74,13 @@ export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, loc
|
|
|
73
74
|
const firstSchema = sections.find(section => section.label === nextSection)?.schemas[0];
|
|
74
75
|
setSelectedSection(nextSection);
|
|
75
76
|
setSelectedSchemaKey(firstSchema ? schemaKey(firstSchema) : '');
|
|
76
|
-
}, children: sections.map(section => _jsx("option", { value: section.label, children: section.label }, section.label)) })] }), _jsxs("label", { children: [copy.resourceType || 'Resource type', _jsx("select", { value: selectedSchema ? schemaKey(selectedSchema) : '', onChange: (event) => setSelectedSchemaKey(event.currentTarget.value), children: selectedSectionSchemas.map(candidate => _jsx("option", { value: schemaKey(candidate), children: candidate.artifactLabel }, schemaKey(candidate))) })] }), _jsxs("button", { type: "button", disabled: !selectedSchema, onClick: () => selectedSchema && setEditor({ schema: selectedSchema }), children: ["+ ", copy.addEntry || copy.add] })] }) : null, sections.map(({ label }) => {
|
|
77
|
+
}, children: sections.map(section => _jsx("option", { value: section.label, children: section.label }, section.label)) })] }), _jsxs("label", { children: [copy.resourceType || 'Resource type', _jsx("select", { value: selectedSchema ? schemaKey(selectedSchema) : '', onChange: (event) => setSelectedSchemaKey(event.currentTarget.value), children: selectedSectionSchemas.map(candidate => _jsx("option", { value: schemaKey(candidate), children: resourceTypeLabel?.(candidate.schema.resourceType) || candidate.artifactLabel }, schemaKey(candidate))) })] }), _jsxs("button", { type: "button", disabled: !selectedSchema, onClick: () => selectedSchema && setEditor({ schema: selectedSchema }), children: ["+ ", copy.addEntry || copy.add] })] }) : null, sections.map(({ label }) => {
|
|
77
78
|
const sectionArtifacts = artifacts.filter((artifact) => artifact.schema.sectionLabel === label);
|
|
78
79
|
return _jsxs("details", { open: true, children: [_jsxs("summary", { children: [label, " (", sectionArtifacts.length, ")"] }), sectionArtifacts.length === 0 ? _jsx("p", { children: copy.empty }) : _jsx("ul", { children: sectionArtifacts.map((artifact) => {
|
|
79
80
|
const title = artifactTitle(artifact.draft);
|
|
80
81
|
return _jsxs("li", { children: [_jsxs("span", { children: [_jsx("strong", { children: title }), _jsx("small", { children: artifact.draft.resourceType })] }), _jsxs("span", { children: [_jsx(ClinicalActionButton, { kind: "edit", label: `${copy.edit} ${title}`, onClick: () => setEditor({ schema: artifact.schema, draft: artifact.draft }) }), _jsx(ClinicalActionButton, { kind: "delete", label: `${copy.remove} ${title}`, onClick: () => setArtifacts((current) => current.filter((candidate) => candidate.draft.id !== artifact.draft.id)) })] })] }, artifact.draft.id);
|
|
81
82
|
}) })] }, label);
|
|
82
|
-
}), artifacts.length === 0 && sections.length === 0 ? _jsx("p", { children: copy.empty }) : null, _jsx("footer", { children: _jsx("button", { type: "button", disabled: artifacts.length === 0 || submitting, onClick: () => void submitDraft(), children: submitting ? copy.submitting : copy.submit }) }), editor ? _jsx(ClinicalArtifactEditor, { request: editorRequest(editor), schema: editor.schema.schema, operationSchema: editor.schema.operationSchema, authoringContext: authoringContext, copy: copy.editor, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, fieldLabel: fieldLabel, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, saveArtifact: async (draft) => stageArtifact(draft), onCancel: () => setEditor(undefined), onReadback: () => setEditor(undefined) }) : null] });
|
|
83
|
+
}), artifacts.length === 0 && sections.length === 0 ? _jsx("p", { children: copy.empty }) : null, _jsx("footer", { children: _jsx("button", { type: "button", disabled: artifacts.length === 0 || submitting, onClick: () => void submitDraft(), children: submitting ? copy.submitting : copy.submit }) }), editor && editorVersion === 'v2' && editor.schema.schema.resourceType === 'Immunization' && editorV2Copy ? _jsx(ImmunizationArtifactEditorV2, { request: editorRequest(editor), authoringContext: authoringContext, copy: editorV2Copy, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, fieldLabel: fieldLabel, resourceTypeLabel: resourceTypeLabel?.(editor.schema.schema.resourceType) || editor.schema.artifactLabel, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, saveArtifact: async (draft) => stageArtifact(draft), onCancel: () => setEditor(undefined), onReadback: () => setEditor(undefined) }) : editor ? _jsx(ClinicalArtifactEditor, { request: editorRequest(editor), schema: editor.schema.schema, operationSchema: editor.schema.operationSchema, authoringContext: authoringContext, copy: copy.editor, locale: locale, timeZone: timeZone, taxonomyId: taxonomyId, fieldLabel: fieldLabel, resourceTypeLabel: resourceTypeLabel?.(editor.schema.schema.resourceType) || editor.schema.artifactLabel, searchTerminology: searchTerminology, loadTerminologySources: loadTerminologySources, saveArtifact: async (draft) => stageArtifact(draft), onCancel: () => setEditor(undefined), onReadback: () => setEditor(undefined) }) : null] });
|
|
83
84
|
}
|
|
84
85
|
function editorRequest(editor) {
|
|
85
86
|
return {
|
|
@@ -89,7 +90,7 @@ function editorRequest(editor) {
|
|
|
89
90
|
...(editor.draft ? { artifactId: editor.draft.id, initialClaims: editor.draft.claims, initialAttachments: editor.draft.attachments } : { initialClaims: editor.schema.schema.initialClaims }),
|
|
90
91
|
};
|
|
91
92
|
}
|
|
92
|
-
function
|
|
93
|
+
export function combineClinicalDrafts(artifacts, authoringContext, documentTitle) {
|
|
93
94
|
const editor = new BundleEditor()
|
|
94
95
|
.setBundleType(BundleTypes.document)
|
|
95
96
|
.setCompositionSubject(authoringContext.subjectReference)
|
|
@@ -110,7 +111,7 @@ function combineDrafts(artifacts, authoringContext, documentTitle) {
|
|
|
110
111
|
for (const { draft } of artifacts) {
|
|
111
112
|
const attachments = draft.attachments ?? [];
|
|
112
113
|
const claims = {
|
|
113
|
-
...operationClaims(draft),
|
|
114
|
+
...(draft.changesBundle ? operationClaims(draft) : draft.claims),
|
|
114
115
|
...(attachments.length ? { [`${draft.resourceType}.contained-reference-list`]: attachments.map(attachment => `DocumentReference/${attachment.id}`).join(',') } : {}),
|
|
115
116
|
};
|
|
116
117
|
const entry = editor.newEntryAs(draft.resourceType, draft.id);
|
|
@@ -135,9 +136,20 @@ function combineDrafts(artifacts, authoringContext, documentTitle) {
|
|
|
135
136
|
documentEntry.setClaim('DocumentReference.subject', authoringContext.subjectReference);
|
|
136
137
|
documentEntry.setClaim('DocumentReference.author', authoringContext.dataAuthorReference);
|
|
137
138
|
}
|
|
139
|
+
for (const related of draft.relatedEntries ?? []) {
|
|
140
|
+
const relatedEntry = editor.newEntryAs(related.resourceType, related.entryId);
|
|
141
|
+
for (const [claim, value] of Object.entries(related.claims))
|
|
142
|
+
relatedEntry.setClaim(claim, value);
|
|
143
|
+
if (related.sectionCode && relatedEntry instanceof ClinicalResourceEntryEditor)
|
|
144
|
+
relatedEntry.setSectionList([related.sectionCode]);
|
|
145
|
+
}
|
|
138
146
|
}
|
|
139
147
|
return editor.buildDocument();
|
|
140
148
|
}
|
|
149
|
+
/** V2 opt-in wrapper; the original editor remains the default everywhere else. */
|
|
150
|
+
export function ClinicalBundleDraftEditorV2(props) {
|
|
151
|
+
return _jsx(ClinicalBundleDraftEditor, { ...props, editorVersion: "v2" });
|
|
152
|
+
}
|
|
141
153
|
function operationClaims(draft) {
|
|
142
154
|
const entries = draft.changesBundle?.data ?? draft.changesBundle?.entry ?? [];
|
|
143
155
|
const first = entries[0];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ClinicalArtifactEditorCopyV2, type ClinicalArtifactEditorV2Props } from './ClinicalArtifactEditorV2.js';
|
|
2
|
+
export declare const ImmunizationArtifactEditorV2Claim: Readonly<{
|
|
3
|
+
readonly NextDoseDate: "Immunization.next-dose-date";
|
|
4
|
+
}>;
|
|
5
|
+
export type ImmunizationArtifactEditorCopyV2 = ClinicalArtifactEditorCopyV2 & Readonly<{
|
|
6
|
+
doseSequenceInvalid: string;
|
|
7
|
+
seriesDosesInvalid: string;
|
|
8
|
+
}>;
|
|
9
|
+
export type ImmunizationArtifactEditorV2Props = Omit<ClinicalArtifactEditorV2Props, 'fields' | 'initialVisibleClaims' | 'initialClaims' | 'validate' | 'buildRelatedEntries' | 'copy'> & Readonly<{
|
|
10
|
+
copy: ImmunizationArtifactEditorCopyV2;
|
|
11
|
+
}>;
|
|
12
|
+
/** Demo-first Immunization specialization over the reusable progressive V2 shell. */
|
|
13
|
+
export declare function ImmunizationArtifactEditorV2({ copy, locale, ...props }: ImmunizationArtifactEditorV2Props): import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=ImmunizationArtifactEditorV2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImmunizationArtifactEditorV2.d.ts","sourceRoot":"","sources":["../src/ImmunizationArtifactEditorV2.tsx"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,4BAA4B,EACjC,KAAK,6BAA6B,EAEnC,MAAM,+BAA+B,CAAA;AAEtC,eAAO,MAAM,iCAAiC;;EAEnC,CAAA;AAEX,MAAM,MAAM,gCAAgC,GAAG,4BAA4B,GAAG,QAAQ,CAAC;IACrF,mBAAmB,EAAE,MAAM,CAAA;IAC3B,kBAAkB,EAAE,MAAM,CAAA;CAC3B,CAAC,CAAA;AAEF,MAAM,MAAM,iCAAiC,GAAG,IAAI,CAAC,6BAA6B,EAAE,QAAQ,GAAG,sBAAsB,GAAG,eAAe,GAAG,UAAU,GAAG,qBAAqB,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC;IAChM,IAAI,EAAE,gCAAgC,CAAA;CACvC,CAAC,CAAA;AAEF,qFAAqF;AACrF,wBAAgB,4BAA4B,CAAC,EAAE,IAAI,EAAE,MAAa,EAAE,GAAG,KAAK,EAAE,EAAE,iCAAiC,+BAoChH"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { ImmunizationClaim, buildImmunizationRecommendationFlatEntry, clinicalArtifactCodedOptionsForClaim, validateImmunizationDoseSeries, } from 'fhir-data-utils-ts';
|
|
4
|
+
import { ClinicalArtifactEditorV2, } from './ClinicalArtifactEditorV2.js';
|
|
5
|
+
export const ImmunizationArtifactEditorV2Claim = Object.freeze({
|
|
6
|
+
NextDoseDate: 'Immunization.next-dose-date',
|
|
7
|
+
});
|
|
8
|
+
/** Demo-first Immunization specialization over the reusable progressive V2 shell. */
|
|
9
|
+
export function ImmunizationArtifactEditorV2({ copy, locale = 'en', ...props }) {
|
|
10
|
+
const fields = immunizationFields(locale);
|
|
11
|
+
return _jsx(ClinicalArtifactEditorV2, { ...props, locale: locale, copy: copy, fields: fields, initialVisibleClaims: [ImmunizationClaim.Status, ImmunizationClaim.VaccineCodeText, ImmunizationClaim.Date], initialClaims: {
|
|
12
|
+
[ImmunizationClaim.Status]: 'completed',
|
|
13
|
+
[ImmunizationClaim.Patient]: props.authoringContext.subjectReference,
|
|
14
|
+
[ImmunizationClaim.Performer]: props.authoringContext.dataAuthorReference,
|
|
15
|
+
}, validate: claims => {
|
|
16
|
+
try {
|
|
17
|
+
validateImmunizationDoseSeries(claims[ImmunizationClaim.DoseSequence], claims[ImmunizationClaim.SeriesDoses]);
|
|
18
|
+
}
|
|
19
|
+
catch (reason) {
|
|
20
|
+
if (reason instanceof Error && reason.message === 'immunization_dose_sequence_invalid')
|
|
21
|
+
throw new TypeError(copy.doseSequenceInvalid);
|
|
22
|
+
throw new TypeError(copy.seriesDosesInvalid);
|
|
23
|
+
}
|
|
24
|
+
}, buildRelatedEntries: (claims, draftId) => {
|
|
25
|
+
const nextDoseDate = claims[ImmunizationArtifactEditorV2Claim.NextDoseDate];
|
|
26
|
+
const vaccineToken = claims[ImmunizationClaim.VaccineCode];
|
|
27
|
+
if (!nextDoseDate || !vaccineToken)
|
|
28
|
+
return [];
|
|
29
|
+
const separator = vaccineToken.indexOf('|');
|
|
30
|
+
if (separator <= 0 || separator === vaccineToken.length - 1)
|
|
31
|
+
return [];
|
|
32
|
+
const recommendation = buildImmunizationRecommendationFlatEntry({
|
|
33
|
+
entryId: `${draftId}-recommendation`, immunizationEntryId: draftId,
|
|
34
|
+
subjectReference: props.authoringContext.subjectReference,
|
|
35
|
+
recommendationDate: props.authoringContext.createdAt,
|
|
36
|
+
nextDoseDate,
|
|
37
|
+
vaccineCode: { system: vaccineToken.slice(0, separator), code: vaccineToken.slice(separator + 1), display: claims[ImmunizationClaim.VaccineCodeDisplay], text: claims[ImmunizationClaim.VaccineCodeText] },
|
|
38
|
+
});
|
|
39
|
+
return [recommendation];
|
|
40
|
+
} });
|
|
41
|
+
}
|
|
42
|
+
function immunizationFields(locale) {
|
|
43
|
+
return Object.freeze([
|
|
44
|
+
{ claim: ImmunizationClaim.Status, kind: 'coded-select', required: true, options: clinicalArtifactCodedOptionsForClaim(ImmunizationClaim.Status, locale).map(option => ({ value: option.code, label: option.label })) },
|
|
45
|
+
{ claim: ImmunizationClaim.VaccineCodeText, textClaim: ImmunizationClaim.VaccineCodeText, codeClaim: ImmunizationClaim.VaccineCode, displayClaim: ImmunizationClaim.VaccineCodeDisplay, kind: 'coded-concept', required: true },
|
|
46
|
+
{ claim: ImmunizationClaim.Date, kind: 'date-time', required: true },
|
|
47
|
+
{ claim: ImmunizationClaim.TargetDiseaseText, textClaim: ImmunizationClaim.TargetDiseaseText, codeClaim: ImmunizationClaim.TargetDisease, displayClaim: ImmunizationClaim.TargetDiseaseDisplay, kind: 'coded-concept' },
|
|
48
|
+
{ claim: ImmunizationClaim.LotNumber, kind: 'text' },
|
|
49
|
+
{ claim: ImmunizationClaim.DoseSequence, kind: 'positive-integer' },
|
|
50
|
+
{ claim: ImmunizationClaim.SeriesDoses, kind: 'positive-integer' },
|
|
51
|
+
{ claim: ImmunizationClaim.Series, kind: 'text' },
|
|
52
|
+
{ claim: ImmunizationArtifactEditorV2Claim.NextDoseDate, kind: 'date', transient: true },
|
|
53
|
+
{ claim: ImmunizationClaim.Route, codeClaim: ImmunizationClaim.Route, displayClaim: ImmunizationClaim.RouteDisplay, kind: 'coded-concept' },
|
|
54
|
+
{ claim: ImmunizationClaim.Site, codeClaim: ImmunizationClaim.Site, displayClaim: ImmunizationClaim.SiteDisplay, kind: 'coded-concept' },
|
|
55
|
+
{ claim: ImmunizationClaim.Note, kind: 'text' },
|
|
56
|
+
{ claim: '__documents', kind: 'documents', transient: true },
|
|
57
|
+
]);
|
|
58
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ export * from './ClinicalDocumentEncounterExplorer.js';
|
|
|
13
13
|
export * from './AllClinicalSections.js';
|
|
14
14
|
export * from './ClinicalTimeline.js';
|
|
15
15
|
export * from './ClinicalArtifactEditor.js';
|
|
16
|
+
export * from './ClinicalArtifactPropertiesV2.js';
|
|
17
|
+
export * from './ClinicalArtifactEditorV2.js';
|
|
18
|
+
export * from './ImmunizationArtifactEditorV2.js';
|
|
16
19
|
export * from './ClinicalBundleDraftEditor.js';
|
|
17
20
|
export * from './ClinicalSpeechInput.js';
|
|
18
21
|
export * from './BrowserClinicalSpeechInput.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wCAAwC,CAAA;AACtD,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0CAA0C,CAAA;AACxD,cAAc,kCAAkC,CAAA;AAChD,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,sCAAsC,CAAA;AACpD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uCAAuC,CAAA;AACrD,cAAc,uBAAuB,CAAA;AACrC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8BAA8B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAA;AAC9B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,wCAAwC,CAAA;AACtD,cAAc,0BAA0B,CAAA;AACxC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,mCAAmC,CAAA;AACjD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,mCAAmC,CAAA;AACjD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,0BAA0B,CAAA;AACxC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,2BAA2B,CAAA;AACzC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA;AACtC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,0CAA0C,CAAA;AACxD,cAAc,kCAAkC,CAAA;AAChD,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,sCAAsC,CAAA;AACpD,cAAc,+BAA+B,CAAA;AAC7C,cAAc,uCAAuC,CAAA;AACrD,cAAc,uBAAuB,CAAA;AACrC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8BAA8B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,9 @@ export * from './ClinicalDocumentEncounterExplorer.js';
|
|
|
13
13
|
export * from './AllClinicalSections.js';
|
|
14
14
|
export * from './ClinicalTimeline.js';
|
|
15
15
|
export * from './ClinicalArtifactEditor.js';
|
|
16
|
+
export * from './ClinicalArtifactPropertiesV2.js';
|
|
17
|
+
export * from './ClinicalArtifactEditorV2.js';
|
|
18
|
+
export * from './ImmunizationArtifactEditorV2.js';
|
|
16
19
|
export * from './ClinicalBundleDraftEditor.js';
|
|
17
20
|
export * from './ClinicalSpeechInput.js';
|
|
18
21
|
export * from './BrowserClinicalSpeechInput.js';
|
package/dist/styles.css
CHANGED
|
@@ -246,6 +246,33 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
|
|
|
246
246
|
.uhcp-terminology-source-picker label { align-items:center; display:flex; gap:.55rem; }
|
|
247
247
|
.uhcp-terminology-source-picker input { margin:0; width:auto; }
|
|
248
248
|
.uhcp-sr-only { clip:rect(0,0,0,0); clip-path:inset(50%); height:1px; overflow:hidden; position:absolute; white-space:nowrap; width:1px; }
|
|
249
|
+
.uhcp-clinical-editor-v2 { max-width:44rem; }
|
|
250
|
+
.uhcp-clinical-editor-v2 form { grid-template-columns:1fr; }
|
|
251
|
+
.uhcp-progressive-field-v2 { background:var(--uhcp-surface-muted); border:1px solid var(--uhcp-border); border-radius:1rem; display:grid; gap:.45rem; padding:.85rem; position:relative; }
|
|
252
|
+
.uhcp-progressive-field-v2>.uhcp-remove-field-v2 { align-items:center; background:#fff1f0; border:1px solid #fda29b; border-radius:50%; color:#b42318; cursor:pointer; display:flex; font-size:1.1rem; height:1.8rem; justify-content:center; position:absolute; right:.55rem; top:.55rem; width:1.8rem; z-index:1; }
|
|
253
|
+
.uhcp-clinical-property-v2 { display:grid; gap:.45rem; min-width:0; }
|
|
254
|
+
.uhcp-clinical-property-v2 input,.uhcp-clinical-property-v2 select { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.7rem; color:inherit; font:inherit; min-width:0; padding:.7rem; width:100%; }
|
|
255
|
+
.uhcp-date-time-property-v2 { align-items:end; border:0; grid-template-columns:minmax(9rem,1fr) auto minmax(7rem,.65fr) auto; margin:0; padding:0; }
|
|
256
|
+
.uhcp-date-time-property-v2 legend { font-weight:800; margin-bottom:.35rem; }
|
|
257
|
+
.uhcp-date-time-property-v2 label { display:grid; gap:.3rem; }
|
|
258
|
+
.uhcp-date-time-property-v2 button,.uhcp-optional-fields-v2 button { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.7rem; color:inherit; cursor:pointer; font:inherit; min-height:2.7rem; padding:.55rem .75rem; }
|
|
259
|
+
.uhcp-coded-concept-query-v2 { display:grid; gap:.4rem; grid-template-columns:minmax(0,1fr) auto auto; }
|
|
260
|
+
.uhcp-icon-button-v2,.uhcp-clear-code-v2 { align-items:center; background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:50%; color:inherit; cursor:pointer; display:flex; height:2.75rem; justify-content:center; padding:.65rem; width:2.75rem; }
|
|
261
|
+
.uhcp-icon-button-v2 svg { fill:none; height:1.2rem; stroke:currentColor; stroke-linecap:round; stroke-width:2; width:1.2rem; }
|
|
262
|
+
.uhcp-clear-code-v2 { background:#fff1f0; border-color:#fda29b; color:#b42318; font-size:1.15rem; }
|
|
263
|
+
.uhcp-coding-sources-v2 { border:0; display:flex; flex-wrap:wrap; gap:.45rem .8rem; margin:0; padding:.2rem 0; }
|
|
264
|
+
.uhcp-coding-sources-v2 legend { color:var(--uhcp-muted); font-size:.8rem; width:100%; }
|
|
265
|
+
.uhcp-coding-sources-v2 label { align-items:center; display:flex; font-size:.85rem; gap:.3rem; }
|
|
266
|
+
.uhcp-coding-sources-v2 input { width:auto; }
|
|
267
|
+
.uhcp-selected-code-v2 { display:grid; gap:.6rem; grid-template-columns:1fr 1fr; }
|
|
268
|
+
.uhcp-selected-code-v2 input[readonly] { background:var(--uhcp-panel-muted); color:var(--uhcp-muted); }
|
|
269
|
+
.uhcp-optional-fields-v2 { align-items:end; border:1px dashed var(--uhcp-border); border-radius:1rem; display:grid; gap:.6rem; grid-template-columns:minmax(0,1fr) auto; margin:0; padding:.8rem; }
|
|
270
|
+
.uhcp-optional-fields-v2 legend { font-weight:800; padding:0 .35rem; }
|
|
271
|
+
.uhcp-optional-fields-v2 select { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.7rem; color:inherit; font:inherit; padding:.7rem; }
|
|
272
|
+
.uhcp-document-references-property-v2 ul { display:grid; gap:.4rem; list-style:none; margin:.2rem 0 0; padding:0; }
|
|
273
|
+
.uhcp-document-references-property-v2 li { align-items:center; display:flex; justify-content:space-between; }
|
|
274
|
+
.uhcp-document-references-property-v2 li button { background:#fff1f0; border:1px solid #fda29b; border-radius:50%; color:#b42318; cursor:pointer; height:1.8rem; width:1.8rem; }
|
|
275
|
+
@media (max-width:620px) { .uhcp-date-time-property-v2,.uhcp-selected-code-v2 { grid-template-columns:minmax(0,1fr) auto; } .uhcp-date-time-property-v2 legend,.uhcp-selected-code-v2 label { grid-column:1/-1; } .uhcp-optional-fields-v2 { grid-template-columns:1fr; } }
|
|
249
276
|
@media (max-width:44rem) { .uhcp-clinical-editor form,.uhcp-emergency-contact-editor { grid-template-columns:1fr; } .uhcp-emergency-contact-directory>ul>li { align-items:stretch; flex-direction:column; } .uhcp-emergency-contact-directory nav { justify-content:flex-start; } }
|
|
250
277
|
|
|
251
278
|
.uhcp-transfer-console { background:#fff; color:#102754; display:grid; font-family:Inter,ui-sans-serif,system-ui,sans-serif; grid-template-columns:minmax(16rem,23rem) minmax(0,1fr); min-height:calc(100vh - 4.5rem); }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "uhc-portal-components-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.48",
|
|
4
4
|
"description": "Brand-neutral React portal shell, account preferences and protected-profile UI for UHC and VetChain portals.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"react-dom": ">=18.3.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"fhir-data-utils-ts": "0.6.
|
|
34
|
+
"fhir-data-utils-ts": "0.6.18",
|
|
35
35
|
"gdc-common-utils-ts": "2.9.30",
|
|
36
36
|
"sos-data-utils-ts": "0.6.3"
|
|
37
37
|
},
|