uhc-portal-components-react 0.1.44 → 0.1.45
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
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.1.45 - 2026-10-07
|
|
6
|
+
|
|
7
|
+
- Present governed terminology sources as a compact dropdown with checkboxes,
|
|
8
|
+
retaining the server default while allowing several systems at once.
|
|
9
|
+
- Resolve each terminology default from the exact resource and coded claim;
|
|
10
|
+
no coding system is assumed globally. Render required FHIR R4 code bindings
|
|
11
|
+
from `fhir-data-utils-ts` with localized labels while persisting their
|
|
12
|
+
canonical codes.
|
|
13
|
+
|
|
5
14
|
## 0.1.44 - 2026-10-07
|
|
6
15
|
|
|
7
16
|
- Let the shared IPS editor hydrate claims-first resources from an imported
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClinicalArtifactEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditor.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kDAAkD,CAAA;
|
|
1
|
+
{"version":3,"file":"ClinicalArtifactEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
4
|
-
import { clinicalArtifactEditorClaimsFromFhirR4, clinicalArtifactFhirR4ToFlat, composeFhirDateTimeFromLocalParts, splitFhirDateTimeForInput, } from 'fhir-data-utils-ts';
|
|
4
|
+
import { clinicalArtifactEditorClaimsFromFhirR4, clinicalArtifactFhirR4ToFlat, clinicalArtifactCodedOptionsForClaim, composeFhirDateTimeFromLocalParts, splitFhirDateTimeForInput, } from 'fhir-data-utils-ts';
|
|
5
5
|
import { buildMultichannelOperationBundle, MultichannelOperationMode, readMultichannelOperationFromBundle, selectMultichannelOperationClaimValues, } from 'sos-data-utils-ts/multichannel-operation-schemas';
|
|
6
6
|
import { ClinicalEditorLayer } from './ClinicalEditorLayer.js';
|
|
7
7
|
import { ClinicalSpeechInputButton } from './ClinicalSpeechInput.js';
|
|
@@ -155,12 +155,19 @@ export function ClinicalArtifactEditor({ request, schema, operationSchema, autho
|
|
|
155
155
|
setSaving(false);
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
|
+
function toggleTerminologySource(sourceId, selected) {
|
|
159
|
+
setSelectedTerminologySources(current => {
|
|
160
|
+
const next = selected ? [...new Set([...current, sourceId])] : current.filter(candidate => candidate !== sourceId);
|
|
161
|
+
return next.length ? next : current;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
158
164
|
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) => {
|
|
159
165
|
const parameter = claim.slice(request.resourceType.length + 1);
|
|
160
166
|
const label = fieldLabel(claim);
|
|
161
167
|
const terminologyEnabled = Boolean(searchTerminology && terminologyCodeClaim(request.resourceType, claim));
|
|
162
168
|
const inputId = `${titleId}-${claim}`;
|
|
163
169
|
const value = claims[claim] ?? '';
|
|
170
|
+
const codedOptions = clinicalArtifactCodedOptionsForClaim(claim, locale);
|
|
164
171
|
const schemaNode = operationSchema?.properties.claims?.properties?.[claim];
|
|
165
172
|
const update = (event) => {
|
|
166
173
|
setClaims((current) => ({ ...current, [claim]: event.target.value }));
|
|
@@ -178,8 +185,8 @@ export function ClinicalArtifactEditor({ request, schema, operationSchema, autho
|
|
|
178
185
|
if (terminologyEnabled)
|
|
179
186
|
setActiveTerminologyClaim(claim);
|
|
180
187
|
};
|
|
181
|
-
return _jsxs("div", { className: fieldClassName, children: [_jsxs("span", { className: "uhcp-clinical-editor-field-heading", children: [_jsxs("label", { htmlFor: inputId, children: [label, requiredClaims.has(claim) ? ' *' : ''] }), isSpeechCompatibleField(parameter, schemaNode) ? _jsx(ClinicalSpeechInputButton, { resourceType: request.resourceType, claim: claim, locale: locale, fieldLabel: label, onTranscript: appendTranscript }) : null] }),
|
|
182
|
-
: _jsx("input", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), type: fieldInputType(parameter, operationSchema?.properties.claims?.properties?.[claim]), onChange: update }), terminologyEnabled && activeTerminologyClaim === claim ? _jsxs("div", { className: "uhcp-terminology-results", children: [terminologySources.length ? _jsxs("
|
|
188
|
+
return _jsxs("div", { className: fieldClassName, children: [_jsxs("span", { className: "uhcp-clinical-editor-field-heading", children: [_jsxs("label", { htmlFor: inputId, children: [label, requiredClaims.has(claim) ? ' *' : ''] }), isSpeechCompatibleField(parameter, schemaNode, codedOptions.length > 0) ? _jsx(ClinicalSpeechInputButton, { resourceType: request.resourceType, claim: claim, locale: locale, fieldLabel: label, onTranscript: appendTranscript }) : null] }), codedOptions.length ? _jsxs("select", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), onChange: update, children: [!requiredClaims.has(claim) ? _jsx("option", { value: "" }) : null, codedOptions.map((option) => _jsx("option", { value: option.code, children: option.label }, option.code))] }) : isMultiline(parameter) ? _jsx("textarea", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), rows: 3, onChange: update })
|
|
189
|
+
: _jsx("input", { id: inputId, "aria-label": label, value: value, required: requiredClaims.has(claim), type: fieldInputType(parameter, operationSchema?.properties.claims?.properties?.[claim]), onChange: update }), terminologyEnabled && activeTerminologyClaim === claim ? _jsxs("div", { className: "uhcp-terminology-results", children: [terminologySources.length ? _jsxs("details", { className: "uhcp-terminology-source-picker", children: [_jsxs("summary", { children: [copy.terminologySources || 'Coding systems', ": ", terminologySources.filter(source => selectedTerminologySources.includes(source.id)).map(source => source.label || source.id).join(', ')] }), _jsxs("fieldset", { "aria-label": copy.terminologySources || 'Coding systems', children: [_jsx("legend", { className: "uhcp-sr-only", children: copy.terminologySources || 'Coding systems' }), terminologySources.map(source => _jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: selectedTerminologySources.includes(source.id), onChange: event => toggleTerminologySource(source.id, event.currentTarget.checked) }), _jsx("span", { children: source.label || source.id })] }, source.id))] })] }) : null, terminologyBusy ? _jsx("small", { role: "status", children: copy.terminologyLoading }) : null, terminologyError ? _jsx("small", { role: "alert", children: copy.terminologyUnavailable }) : null, candidates.length ? _jsx("ul", { children: candidates.map((candidate) => _jsx("li", { children: _jsxs("button", { type: "button", onClick: () => {
|
|
183
190
|
setClaims((current) => selectedCodingClaims(request.resourceType, claim, candidate, acceptedClaims, current));
|
|
184
191
|
setCandidates([]);
|
|
185
192
|
setActiveTerminologyClaim(undefined);
|
|
@@ -223,8 +230,8 @@ function composeTemporalClaim(parts, timeZone) {
|
|
|
223
230
|
function isDateTimeSchemaNode(schemaNode) {
|
|
224
231
|
return schemaNode?.format === 'date-time' || schemaNode?.format === 'fhir-date-time';
|
|
225
232
|
}
|
|
226
|
-
function isSpeechCompatibleField(parameter, schemaNode) {
|
|
227
|
-
if (
|
|
233
|
+
function isSpeechCompatibleField(parameter, schemaNode, hasCodedOptions = false) {
|
|
234
|
+
if (hasCodedOptions)
|
|
228
235
|
return false;
|
|
229
236
|
if (schemaNode?.type === 'number' || schemaNode?.type === 'integer' || schemaNode?.type === 'boolean')
|
|
230
237
|
return false;
|
|
@@ -275,15 +282,6 @@ function defaultClaims(resourceType) {
|
|
|
275
282
|
return { [`${resourceType}.clinical-status`]: 'active' };
|
|
276
283
|
return {};
|
|
277
284
|
}
|
|
278
|
-
function statusOptions(resourceType, parameter) {
|
|
279
|
-
if (parameter !== 'status' && !parameter.endsWith('-status'))
|
|
280
|
-
return undefined;
|
|
281
|
-
if (resourceType === 'Immunization')
|
|
282
|
-
return ['completed', 'not-done', 'entered-in-error'];
|
|
283
|
-
if (resourceType === 'Observation' || resourceType === 'DiagnosticReport')
|
|
284
|
-
return ['final', 'preliminary', 'amended', 'entered-in-error'];
|
|
285
|
-
return ['active', 'completed', 'inactive', 'entered-in-error'];
|
|
286
|
-
}
|
|
287
285
|
function terminologyCodeClaim(resourceType, inputClaim) {
|
|
288
286
|
const parameter = inputClaim.slice(resourceType.length + 1);
|
|
289
287
|
// `code-text` is the generic primary-concept alias. Immunization deliberately
|
package/dist/styles.css
CHANGED
|
@@ -237,6 +237,15 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
|
|
|
237
237
|
.uhcp-terminology-results ul { display:grid; gap:.35rem; list-style:none; margin:.25rem 0 0; padding:0; }
|
|
238
238
|
.uhcp-terminology-results button { background:var(--uhcp-surface-muted); color:inherit; display:grid; text-align:start; width:100%; }
|
|
239
239
|
.uhcp-terminology-results small { color:var(--uhcp-muted); display:block; font-weight:400; }
|
|
240
|
+
.uhcp-terminology-source-picker { border:1px solid var(--uhcp-border); border-radius:.7rem; margin:.25rem 0; position:relative; }
|
|
241
|
+
.uhcp-terminology-source-picker summary { cursor:pointer; font-weight:750; list-style:none; padding:.7rem .8rem; }
|
|
242
|
+
.uhcp-terminology-source-picker summary::-webkit-details-marker { display:none; }
|
|
243
|
+
.uhcp-terminology-source-picker summary::after { content:'▾'; float:inline-end; }
|
|
244
|
+
.uhcp-terminology-source-picker[open] summary::after { content:'▴'; }
|
|
245
|
+
.uhcp-terminology-source-picker fieldset { background:var(--uhcp-panel); border:0; border-top:1px solid var(--uhcp-border); display:grid; gap:.45rem; margin:0; padding:.7rem .8rem; }
|
|
246
|
+
.uhcp-terminology-source-picker label { align-items:center; display:flex; gap:.55rem; }
|
|
247
|
+
.uhcp-terminology-source-picker input { margin:0; width:auto; }
|
|
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; }
|
|
240
249
|
@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; } }
|
|
241
250
|
|
|
242
251
|
.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.45",
|
|
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.16",
|
|
35
35
|
"gdc-common-utils-ts": "2.9.30",
|
|
36
36
|
"sos-data-utils-ts": "0.6.3"
|
|
37
37
|
},
|