uhc-portal-components-react 0.2.0 → 0.2.2
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 +27 -0
- package/README.md +2 -0
- package/dist/ClinicalActionButton.d.ts.map +1 -1
- package/dist/ClinicalActionButton.js +1 -1
- package/dist/ClinicalArtifactEditorV2.d.ts +2 -0
- package/dist/ClinicalArtifactEditorV2.d.ts.map +1 -1
- package/dist/ClinicalArtifactEditorV2.js +7 -2
- package/dist/ClinicalArtifactPropertiesV2.d.ts +1 -0
- package/dist/ClinicalArtifactPropertiesV2.d.ts.map +1 -1
- package/dist/ClinicalArtifactPropertiesV2.js +5 -2
- package/dist/ClinicalBundleDraftEditor.d.ts +20 -1
- package/dist/ClinicalBundleDraftEditor.d.ts.map +1 -1
- package/dist/ClinicalBundleDraftEditor.js +27 -7
- package/dist/ProfileProtectionGateV2.d.ts +21 -0
- package/dist/ProfileProtectionGateV2.d.ts.map +1 -0
- package/dist/ProfileProtectionGateV2.js +83 -0
- package/dist/SchemaClinicalArtifactEditorV2.d.ts +10 -0
- package/dist/SchemaClinicalArtifactEditorV2.d.ts.map +1 -0
- package/dist/SchemaClinicalArtifactEditorV2.js +60 -0
- package/dist/contracts.d.ts +16 -0
- package/dist/contracts.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/styles.css +33 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.2.2 - 2026-10-09
|
|
6
|
+
|
|
7
|
+
- Name the exact localized FHIR resource in the V2 editor heading without a
|
|
8
|
+
redundant resource-type subtitle.
|
|
9
|
+
- Keep terminology candidates in the existing selection dropdown and report a
|
|
10
|
+
successful zero-result search explicitly, clearing stale results whenever
|
|
11
|
+
the query or governed coding-system selection changes.
|
|
12
|
+
- Give the V2 profile-unlock panel an explicit light/dark accent surface and
|
|
13
|
+
support PIN-recovery actions inside the PIN fallback only after a rejected
|
|
14
|
+
PIN, while keeping unrelated profile actions separate.
|
|
15
|
+
- Use compact, accessible add/remove section actions with destructive
|
|
16
|
+
confirmation, semantic action colours and matching hover/focus hints.
|
|
17
|
+
- Let hosts place downloads, credential generation and update metadata in the
|
|
18
|
+
same responsive document footer as the final submit action.
|
|
19
|
+
|
|
20
|
+
## 0.2.1 - 2026-10-08
|
|
21
|
+
|
|
22
|
+
- Add the opt-in `ProfileProtectionGateV2`, which identifies the exact
|
|
23
|
+
host-authorized profile or subject with accessible human-readable metadata
|
|
24
|
+
before passkey or PIN unlock. V1 remains unchanged.
|
|
25
|
+
- Route every schema-backed IPS resource through the progressive V2 clinical
|
|
26
|
+
editor, with schema-owned coded dropdowns, terminology-backed concepts,
|
|
27
|
+
date/time controls, optional-field selection and mandatory canonical coding.
|
|
28
|
+
- Let hosts attach entry-level credential actions to a staged clinical record;
|
|
29
|
+
creation updates only the local draft and viewing does not cross the final
|
|
30
|
+
document submission boundary.
|
|
31
|
+
|
|
5
32
|
## 0.2.0 - 2026-10-08
|
|
6
33
|
|
|
7
34
|
- Promote the opt-in V2 clinical document authoring API to a minor release.
|
package/README.md
CHANGED
|
@@ -50,6 +50,8 @@ The package deliberately exposes modules instead of a cloned application:
|
|
|
50
50
|
- `PortalEntryHero`: identical product entry composition for every brand.
|
|
51
51
|
- `PortalAccessChooser`: real-page navigation for professional access paths.
|
|
52
52
|
- `ProfileProtectionGate`: fail-closed PIN unlock presentation.
|
|
53
|
+
- `ProfileProtectionGateV2`: opt-in passkey/PIN gate that identifies the exact
|
|
54
|
+
host-authorized target without exposing or selecting its technical id.
|
|
53
55
|
- `ClinicalSectionSummary`: brand-neutral rendering of already-resolved IPS
|
|
54
56
|
cards for personal and professional portals. Advanced viewers can set
|
|
55
57
|
`showHeader={false}` when they retain their own expandable heading.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClinicalActionButton.d.ts","sourceRoot":"","sources":["../src/ClinicalActionButton.tsx"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;AAE1D,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAgB,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC;IACxF,IAAI,EAAE,kBAAkB,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAC,+
|
|
1
|
+
{"version":3,"file":"ClinicalActionButton.d.ts","sourceRoot":"","sources":["../src/ClinicalActionButton.tsx"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;AAE1D,sFAAsF;AACtF,wBAAgB,oBAAoB,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAgB,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC;IACxF,IAAI,EAAE,kBAAkB,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAC,+BAUD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/** Compact clinical action; authorization and callback behavior remain host-owned. */
|
|
3
3
|
export function ClinicalActionButton({ kind, label, disabled = false, onClick }) {
|
|
4
|
-
return _jsx("button", { type: "button", className: `uhcp-clinical-icon-action uhcp-clinical-icon-action-${kind}`, "aria-label": label, title: label, disabled: disabled, onClick: onClick, children: _jsx(ActionIcon, { kind: kind }) });
|
|
4
|
+
return _jsx("button", { type: "button", className: `uhcp-clinical-icon-action uhcp-clinical-icon-action-${kind}`, "aria-label": label, title: label, "data-tooltip": label, disabled: disabled, onClick: onClick, children: _jsx(ActionIcon, { kind: kind }) });
|
|
5
5
|
}
|
|
6
6
|
function ActionIcon({ kind }) {
|
|
7
7
|
if (kind === 'add')
|
|
@@ -30,6 +30,7 @@ export type ClinicalArtifactEditorCopyV2 = Readonly<{
|
|
|
30
30
|
close: string;
|
|
31
31
|
terminologyLoading: string;
|
|
32
32
|
terminologyUnavailable: string;
|
|
33
|
+
terminologyEmpty?: string;
|
|
33
34
|
terminologySources: string;
|
|
34
35
|
readbackMissing: string;
|
|
35
36
|
addField: string;
|
|
@@ -41,6 +42,7 @@ export type ClinicalArtifactEditorCopyV2 = Readonly<{
|
|
|
41
42
|
selectCandidate: string;
|
|
42
43
|
canonicalCode: string;
|
|
43
44
|
canonicalDisplay: string;
|
|
45
|
+
codingRequired: string;
|
|
44
46
|
documents: string;
|
|
45
47
|
addDocuments: string;
|
|
46
48
|
removeDocument: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClinicalArtifactEditorV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditorV2.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kDAAkD,CAAA;AAGlG,OAAO,EAOL,KAAK,wBAAwB,EAC9B,MAAM,mCAAmC,CAAA;AAC1C,OAAO,KAAK,EAEV,gCAAgC,EAChC,qBAAqB,EACrB,6BAA6B,EAC7B,2BAA2B,EAC3B,4BAA4B,EAC5B,yBAAyB,EACzB,+BAA+B,EAChC,MAAM,6BAA6B,CAAA;AAEpC,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAC,CAAA;AAEF,MAAM,MAAM,uBAAuB,GAAG,qBAAqB,GAAG,QAAQ,CAAC;IACrE,cAAc,CAAC,EAAE,SAAS,8BAA8B,EAAE,CAAA;CAC3D,CAAC,CAAA;AAEF,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,kBAAkB,GAAG,cAAc,GAAG,eAAe,GAAG,WAAW,CAAA;IACzG,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,SAAS,wBAAwB,EAAE,CAAA;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,CAAA;AAEF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;IACtH,kBAAkB,EAAE,MAAM,CAAC;IAAC,sBAAsB,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"ClinicalArtifactEditorV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactEditorV2.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useId, useRef, useState } from 'react';
|
|
4
4
|
import { ClinicalEditorLayer } from './ClinicalEditorLayer.js';
|
|
5
5
|
import { readClinicalAttachment } from './ClinicalArtifactEditor.js';
|
|
@@ -19,6 +19,11 @@ export function ClinicalArtifactEditorV2({ request, authoringContext, copy, fiel
|
|
|
19
19
|
async function submit() {
|
|
20
20
|
setError('');
|
|
21
21
|
try {
|
|
22
|
+
for (const field of fields) {
|
|
23
|
+
if (field.required && field.kind === 'coded-concept' && field.codeClaim && !claims[field.codeClaim]) {
|
|
24
|
+
throw new TypeError(copy.codingRequired);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
22
27
|
validate?.(claims);
|
|
23
28
|
setSaving(true);
|
|
24
29
|
const draft = {
|
|
@@ -49,7 +54,7 @@ export function ClinicalArtifactEditorV2({ request, authoringContext, copy, fiel
|
|
|
49
54
|
setSaving(false);
|
|
50
55
|
}
|
|
51
56
|
}
|
|
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: [
|
|
57
|
+
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: [_jsxs("h2", { id: titleId, children: [copy.title, " ", 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
58
|
setAttachments([]); setClaims(current => { const next = { ...current }; delete next[field.claim]; if (field.codeClaim)
|
|
54
59
|
delete next[field.codeClaim]; if (field.displayClaim)
|
|
55
60
|
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)) })
|
|
@@ -33,6 +33,7 @@ export declare function CodedConceptPropertyV2({ resourceType, textClaim, codeCl
|
|
|
33
33
|
searchTerminology: string;
|
|
34
34
|
terminologyLoading: string;
|
|
35
35
|
terminologyUnavailable: string;
|
|
36
|
+
terminologyEmpty?: string;
|
|
36
37
|
terminologySources: string;
|
|
37
38
|
selectCandidate: string;
|
|
38
39
|
clearCoding: string;
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"ClinicalArtifactPropertiesV2.d.ts","sourceRoot":"","sources":["../src/ClinicalArtifactPropertiesV2.tsx"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
|
|
|
19
19
|
const [candidates, setCandidates] = useState([]);
|
|
20
20
|
const [busy, setBusy] = useState(false);
|
|
21
21
|
const [failed, setFailed] = useState(false);
|
|
22
|
+
const [searched, setSearched] = useState(false);
|
|
22
23
|
useEffect(() => {
|
|
23
24
|
if (!loadTerminologySources)
|
|
24
25
|
return;
|
|
@@ -38,6 +39,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
|
|
|
38
39
|
return;
|
|
39
40
|
setBusy(true);
|
|
40
41
|
setFailed(false);
|
|
42
|
+
setSearched(false);
|
|
41
43
|
try {
|
|
42
44
|
let governedSources = selectedSources;
|
|
43
45
|
if (!governedSources.length && loadTerminologySources) {
|
|
@@ -48,6 +50,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
|
|
|
48
50
|
setSelectedSources(governedSources);
|
|
49
51
|
}
|
|
50
52
|
setCandidates(await searchTerminology({ resourceType, claim: codeClaim, language: locale, text: query.trim(), taxonomyId, limit: 20, ...(governedSources.length ? { sources: governedSources } : {}) }));
|
|
53
|
+
setSearched(true);
|
|
51
54
|
}
|
|
52
55
|
catch {
|
|
53
56
|
setCandidates([]);
|
|
@@ -57,7 +60,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
|
|
|
57
60
|
setBusy(false);
|
|
58
61
|
}
|
|
59
62
|
};
|
|
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 =>
|
|
63
|
+
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); setCandidates([]); setSearched(false); setFailed(false); 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 => { const checked = event.currentTarget.checked; setSelectedSources(current => checked ? [...new Set([...current, source.id])] : current.filter(value => value !== source.id)); setCandidates([]); setSearched(false); setFailed(false); } }), 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, searched && !busy && !failed && candidates.length === 0 ? _jsx("small", { role: "status", children: copy.terminologyEmpty || copy.terminologyUnavailable }) : null, candidates.length ? _jsxs("label", { children: [copy.selectCandidate, _jsxs("select", { "aria-label": copy.selectCandidate, value: selectedToken, onChange: event => {
|
|
61
64
|
const candidate = candidates.find(value => `${value.system}|${value.code}` === event.currentTarget.value);
|
|
62
65
|
if (!candidate)
|
|
63
66
|
return;
|
|
@@ -65,7 +68,7 @@ export function CodedConceptPropertyV2({ resourceType, textClaim, codeClaim, dis
|
|
|
65
68
|
setQuery(localText);
|
|
66
69
|
onChange({ text: localText, code: `${candidate.system}|${candidate.code}`, display: candidate.display });
|
|
67
70
|
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] });
|
|
71
|
+
}, children: [_jsx("option", { value: "" }), candidates.map(candidate => _jsxs("option", { value: `${candidate.system}|${candidate.code}`, children: [candidate.text && candidate.text !== candidate.display ? `${candidate.text} — ${candidate.display}` : 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
72
|
}
|
|
70
73
|
export function CodedSelectPropertyV2({ label, value, required, options, onChange }) {
|
|
71
74
|
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))] })] });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
1
2
|
import 'gdc-common-utils-ts/utils/allergy-intolerance-entry-editor';
|
|
2
3
|
import 'gdc-common-utils-ts/utils/condition-entry-editor';
|
|
3
4
|
import 'gdc-common-utils-ts/utils/document-reference-entry-editor';
|
|
@@ -8,6 +9,7 @@ import 'gdc-common-utils-ts/utils/procedure-entry-editor';
|
|
|
8
9
|
import type { MultichannelOperationSchema } from 'sos-data-utils-ts/multichannel-operation-schemas';
|
|
9
10
|
import { type ClinicalArtifactAuthoringContext, type ClinicalArtifactDraft, type ClinicalArtifactEditorCopy, type ClinicalArtifactSchema, type ClinicalTerminologySearch, type ClinicalTerminologyCandidate, type ClinicalTerminologySourceSearch } from './ClinicalArtifactEditor.js';
|
|
10
11
|
import { type ImmunizationArtifactEditorCopyV2 } from './ImmunizationArtifactEditorV2.js';
|
|
12
|
+
import type { ClinicalArtifactDraftV2 } from './ClinicalArtifactEditorV2.js';
|
|
11
13
|
export type ClinicalBundleDraftSchema = Readonly<{
|
|
12
14
|
schema: ClinicalArtifactSchema;
|
|
13
15
|
operationSchema: MultichannelOperationSchema;
|
|
@@ -32,6 +34,8 @@ export type ClinicalBundleDraftEditorCopy = Readonly<{
|
|
|
32
34
|
resourceType?: string;
|
|
33
35
|
addSection?: string;
|
|
34
36
|
addEntry?: string;
|
|
37
|
+
removeSection?: string;
|
|
38
|
+
removeSectionConfirm?: string;
|
|
35
39
|
chooseResource?: string;
|
|
36
40
|
edit: string;
|
|
37
41
|
remove: string;
|
|
@@ -58,6 +62,21 @@ export type ClinicalBundleDraftEditorProps = Readonly<{
|
|
|
58
62
|
onSubmitDraft: (bundle: ClinicalBundleDraft) => Promise<ClinicalBundleDraftSubmitOutcome>;
|
|
59
63
|
editorVersion?: 'v1' | 'v2';
|
|
60
64
|
editorV2Copy?: ImmunizationArtifactEditorCopyV2;
|
|
65
|
+
artifactCredentialAction?: Readonly<{
|
|
66
|
+
createLabel: string;
|
|
67
|
+
viewLabel: string;
|
|
68
|
+
isCreated: (draft: ClinicalArtifactDraftV2) => boolean;
|
|
69
|
+
onCreate: (input: Readonly<{
|
|
70
|
+
draft: ClinicalArtifactDraftV2;
|
|
71
|
+
bundle: ClinicalBundleDraft;
|
|
72
|
+
}>) => ClinicalArtifactDraftV2 | Promise<ClinicalArtifactDraftV2>;
|
|
73
|
+
onView: (input: Readonly<{
|
|
74
|
+
draft: ClinicalArtifactDraftV2;
|
|
75
|
+
bundle: ClinicalBundleDraft;
|
|
76
|
+
}>) => void;
|
|
77
|
+
}>;
|
|
78
|
+
/** Host-owned document actions rendered beside the final submit action. */
|
|
79
|
+
documentActions?: ReactNode;
|
|
61
80
|
}>;
|
|
62
81
|
type StagedArtifact = Readonly<{
|
|
63
82
|
schema: ClinicalBundleDraftSchema;
|
|
@@ -70,7 +89,7 @@ type StagedArtifact = Readonly<{
|
|
|
70
89
|
* It owns no authorization or persistence: the host supplies subject and
|
|
71
90
|
* provenance and only `onSubmitDraft` may cross a persistence boundary.
|
|
72
91
|
*/
|
|
73
|
-
export declare function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale, timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onDraftChange, onSubmitDraft, editorVersion, editorV2Copy, }: ClinicalBundleDraftEditorProps): import("react").JSX.Element;
|
|
92
|
+
export declare function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale, timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onDraftChange, onSubmitDraft, editorVersion, editorV2Copy, artifactCredentialAction, documentActions, }: ClinicalBundleDraftEditorProps): import("react").JSX.Element;
|
|
74
93
|
export declare function combineClinicalDrafts(artifacts: readonly StagedArtifact[], authoringContext: ClinicalArtifactAuthoringContext, documentTitle: string): ClinicalBundleDraft;
|
|
75
94
|
export type ClinicalBundleDraftEditorV2Props = Omit<ClinicalBundleDraftEditorProps, 'editorVersion' | 'editorV2Copy'> & Readonly<{
|
|
76
95
|
editorV2Copy: ImmunizationArtifactEditorCopyV2;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClinicalBundleDraftEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalBundleDraftEditor.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ClinicalBundleDraftEditor.d.ts","sourceRoot":"","sources":["../src/ClinicalBundleDraftEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ import 'gdc-common-utils-ts/utils/procedure-entry-editor';
|
|
|
16
16
|
import { ClinicalArtifactEditor, } from './ClinicalArtifactEditor.js';
|
|
17
17
|
import { ClinicalActionButton } from './ClinicalActionButton.js';
|
|
18
18
|
import { ImmunizationArtifactEditorV2, } from './ImmunizationArtifactEditorV2.js';
|
|
19
|
+
import { SchemaClinicalArtifactEditorV2 } from './SchemaClinicalArtifactEditorV2.js';
|
|
19
20
|
/**
|
|
20
21
|
* Shared local-first IPS authoring workspace.
|
|
21
22
|
*
|
|
@@ -23,7 +24,7 @@ import { ImmunizationArtifactEditorV2, } from './ImmunizationArtifactEditorV2.js
|
|
|
23
24
|
* It owns no authorization or persistence: the host supplies subject and
|
|
24
25
|
* provenance and only `onSubmitDraft` may cross a persistence boundary.
|
|
25
26
|
*/
|
|
26
|
-
export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale = 'en', timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onDraftChange, onSubmitDraft, editorVersion = 'v1', editorV2Copy, }) {
|
|
27
|
+
export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, locale = 'en', timeZone, taxonomyId, fieldLabel, resourceTypeLabel, searchTerminology, loadTerminologySources, initialBundle, onDraftChange, onSubmitDraft, editorVersion = 'v1', editorV2Copy, artifactCredentialAction, documentActions, }) {
|
|
27
28
|
const [artifacts, setArtifacts] = useState(() => importedArtifacts(initialBundle, schemas));
|
|
28
29
|
const [editor, setEditor] = useState();
|
|
29
30
|
const [resourceChooser, setResourceChooser] = useState();
|
|
@@ -73,30 +74,49 @@ export function ClinicalBundleDraftEditor({ schemas, authoringContext, copy, loc
|
|
|
73
74
|
setSubmitting(false);
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
|
-
return _jsxs("section", { className: "uhcp-clinical-bundle-draft", "data-clinical-bundle-draft": true, children: [_jsxs("header", { children: [_jsx("h2", { children: copy.title }), _jsx("p", { children: copy.description })] }), notice ? _jsx("p", { role: "status", children: notice }) : null, error ? _jsx("p", { role: "alert", className: "uhcp-clinical-editor-error", children: error }) : null, availableSections.length ? _jsxs("div", { className: "uhcp-clinical-bundle-draft-create", children: [_jsxs("label", { children: [copy.section || 'Section', _jsx("select", { value: availableSections.some(section => section.label === selectedSection) ? selectedSection : availableSections[0]?.label, onChange: (event) => setSelectedSection(event.currentTarget.value), children: availableSections.map(section => _jsx("option", { value: section.label, children: section.label }, section.label)) })] }),
|
|
77
|
+
return _jsxs("section", { className: "uhcp-clinical-bundle-draft", "data-clinical-bundle-draft": true, children: [_jsxs("header", { children: [_jsx("h2", { children: copy.title }), _jsx("p", { children: copy.description })] }), notice ? _jsx("p", { role: "status", children: notice }) : null, error ? _jsx("p", { role: "alert", className: "uhcp-clinical-editor-error", children: error }) : null, availableSections.length ? _jsxs("div", { className: "uhcp-clinical-bundle-draft-create", children: [_jsxs("label", { children: [copy.section || 'Section', _jsx("select", { value: availableSections.some(section => section.label === selectedSection) ? selectedSection : availableSections[0]?.label, onChange: (event) => setSelectedSection(event.currentTarget.value), children: availableSections.map(section => _jsx("option", { value: section.label, children: section.label }, section.label)) })] }), _jsx("button", { type: "button", onClick: () => {
|
|
77
78
|
const label = availableSections.some(section => section.label === selectedSection) ? selectedSection : availableSections[0]?.label;
|
|
78
79
|
if (!label)
|
|
79
80
|
return;
|
|
80
81
|
setActiveSections(current => [...current, label]);
|
|
81
82
|
const nextAvailable = availableSections.find(section => section.label !== label);
|
|
82
83
|
setSelectedSection(nextAvailable?.label ?? '');
|
|
83
|
-
},
|
|
84
|
+
}, className: "uhcp-add-section-button", children: copy.addSection || copy.add })] }) : null, sections.filter(section => activeSections.includes(section.label)).map(({ label, schemas: sectionSchemas }) => {
|
|
84
85
|
const sectionArtifacts = artifacts.filter((artifact) => artifact.schema.sectionLabel === label);
|
|
85
|
-
return _jsxs("details", { open: true, children: [_jsxs("summary", { children: [label, " (", sectionArtifacts.length, ")"] }),
|
|
86
|
+
return _jsxs("details", { open: true, children: [_jsxs("summary", { children: [label, " (", sectionArtifacts.length, ")"] }), _jsx("button", { type: "button", className: "uhcp-remove-section-button", "aria-label": `${copy.removeSection || copy.remove} ${label}`, title: `${copy.removeSection || copy.remove} ${label}`, "data-tooltip": `${copy.removeSection || copy.remove} ${label}`, onClick: () => {
|
|
87
|
+
if (sectionArtifacts.length && !window.confirm(copy.removeSectionConfirm || `Removing this section will delete all its draft entries. Continue?`))
|
|
88
|
+
return;
|
|
89
|
+
setArtifacts(current => current.filter(artifact => artifact.schema.sectionLabel !== label));
|
|
90
|
+
setActiveSections(current => current.filter(section => section !== label));
|
|
91
|
+
if (resourceChooser?.sectionLabel === label)
|
|
92
|
+
setResourceChooser(undefined);
|
|
93
|
+
if (editor?.schema.sectionLabel === label)
|
|
94
|
+
setEditor(undefined);
|
|
95
|
+
}, children: "\u2212" }), _jsx("button", { type: "button", className: "uhcp-add-entry-button", "aria-label": copy.addEntry || copy.add, title: copy.addEntry || copy.add, "data-tooltip": copy.addEntry || copy.add, onClick: () => {
|
|
86
96
|
if (sectionSchemas.length === 1)
|
|
87
97
|
setEditor({ schema: sectionSchemas[0] });
|
|
88
98
|
else
|
|
89
99
|
setResourceChooser({ sectionLabel: label, schemaKey: schemaKey(sectionSchemas[0]) });
|
|
90
|
-
}, children:
|
|
100
|
+
}, children: "+" }), resourceChooser?.sectionLabel === label ? _jsxs("div", { className: "uhcp-clinical-bundle-resource-choice", children: [_jsxs("label", { children: [copy.resourceType || 'Resource type', _jsx("select", { value: resourceChooser.schemaKey, onChange: event => setResourceChooser({ sectionLabel: label, schemaKey: event.currentTarget.value }), children: sectionSchemas.map(candidate => _jsx("option", { value: schemaKey(candidate), children: resourceTypeLabel?.(candidate.schema.resourceType) || candidate.artifactLabel }, schemaKey(candidate))) })] }), _jsx("button", { type: "button", onClick: () => {
|
|
91
101
|
const selected = sectionSchemas.find(candidate => schemaKey(candidate) === resourceChooser.schemaKey);
|
|
92
102
|
if (selected)
|
|
93
103
|
setEditor({ schema: selected });
|
|
94
104
|
setResourceChooser(undefined);
|
|
95
105
|
}, children: copy.chooseResource || copy.add })] }) : null, sectionArtifacts.length === 0 ? _jsx("p", { children: copy.empty }) : _jsx("ul", { children: sectionArtifacts.map((artifact) => {
|
|
96
106
|
const title = artifactTitle(artifact.draft);
|
|
97
|
-
return _jsxs("li", { children: [_jsxs("span", { children: [_jsx("strong", { children: title }), _jsx("small", { children: artifact.draft.resourceType })] }), _jsxs("span", { children: [_jsx(
|
|
107
|
+
return _jsxs("li", { children: [_jsxs("span", { children: [_jsx("strong", { children: title }), _jsx("small", { children: artifact.draft.resourceType })] }), _jsxs("span", { children: [artifactCredentialAction ? _jsx("button", { type: "button", className: "uhcp-clinical-entry-credential-action", onClick: () => {
|
|
108
|
+
const draft = artifact.draft;
|
|
109
|
+
const bundle = combineClinicalDrafts([artifact], authoringContext, copy.title);
|
|
110
|
+
if (artifactCredentialAction.isCreated(draft)) {
|
|
111
|
+
artifactCredentialAction.onView({ draft, bundle });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
void Promise.resolve(artifactCredentialAction.onCreate({ draft, bundle })).then(nextDraft => {
|
|
115
|
+
setArtifacts(current => current.map(candidate => candidate.draft.id === draft.id ? { ...candidate, draft: nextDraft } : candidate));
|
|
116
|
+
}).catch(reason => setError(reason instanceof Error ? reason.message : String(reason)));
|
|
117
|
+
}, children: artifactCredentialAction.isCreated(artifact.draft) ? artifactCredentialAction.viewLabel : artifactCredentialAction.createLabel }) : null, _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);
|
|
98
118
|
}) })] }, label);
|
|
99
|
-
}), activeSections.length === 0 ? _jsx("p", { children: copy.empty }) : null,
|
|
119
|
+
}), activeSections.length === 0 ? _jsx("p", { children: copy.empty }) : null, _jsxs("footer", { "data-testid": "clinical-document-actions", children: [documentActions ? _jsx("div", { className: "uhcp-clinical-document-secondary-actions", children: documentActions }) : null, _jsx("button", { type: "button", className: "uhcp-clinical-document-submit", 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 && editorVersion === 'v2' && editorV2Copy ? _jsx(SchemaClinicalArtifactEditorV2, { request: editorRequest(editor), schema: editor.schema.schema, 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] });
|
|
100
120
|
}
|
|
101
121
|
function editorRequest(editor) {
|
|
102
122
|
return {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { ProfileProtectionCopyV2, ProfileProtectionState, ProfileProtectionTargetV2, ProfileUnlockResult } from './contracts.js';
|
|
3
|
+
export type ProfileProtectionGateV2Props = Readonly<{
|
|
4
|
+
state: ProfileProtectionState;
|
|
5
|
+
target: ProfileProtectionTargetV2;
|
|
6
|
+
copy: ProfileProtectionCopyV2;
|
|
7
|
+
onUnlock?: (pin: string) => ProfileUnlockResult | Promise<ProfileUnlockResult>;
|
|
8
|
+
onPasskeyUnlock?: () => void | Promise<void>;
|
|
9
|
+
onRetry?: () => void;
|
|
10
|
+
pinFailureActions?: ReactNode;
|
|
11
|
+
secondaryActions?: ReactNode;
|
|
12
|
+
children: ReactNode;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Presentation-only profile gate that identifies the host-authorized target.
|
|
16
|
+
*
|
|
17
|
+
* The host resolves translations, authority and the opaque profile id. This
|
|
18
|
+
* component renders only human-readable metadata and never selects a target.
|
|
19
|
+
*/
|
|
20
|
+
export declare function ProfileProtectionGateV2({ state, target, copy, onUnlock, onPasskeyUnlock, onRetry, pinFailureActions, secondaryActions, children, }: ProfileProtectionGateV2Props): import("react").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=ProfileProtectionGateV2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProfileProtectionGateV2.d.ts","sourceRoot":"","sources":["../src/ProfileProtectionGateV2.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACnF,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,EACzB,mBAAmB,EACpB,MAAM,gBAAgB,CAAA;AAEvB,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,KAAK,EAAE,sBAAsB,CAAA;IAC7B,MAAM,EAAE,yBAAyB,CAAA;IACjC,IAAI,EAAE,uBAAuB,CAAA;IAC7B,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;IAC9E,eAAe,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,iBAAiB,CAAC,EAAE,SAAS,CAAA;IAC7B,gBAAgB,CAAC,EAAE,SAAS,CAAA;IAC5B,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAC,CAAA;AAEF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,eAAe,EACf,OAAO,EACP,iBAAiB,EACjB,gBAAgB,EAChB,QAAQ,GACT,EAAE,4BAA4B,+BAuH9B"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Presentation-only profile gate that identifies the host-authorized target.
|
|
6
|
+
*
|
|
7
|
+
* The host resolves translations, authority and the opaque profile id. This
|
|
8
|
+
* component renders only human-readable metadata and never selects a target.
|
|
9
|
+
*/
|
|
10
|
+
export function ProfileProtectionGateV2({ state, target, copy, onUnlock, onPasskeyUnlock, onRetry, pinFailureActions, secondaryActions, children, }) {
|
|
11
|
+
const [pin, setPin] = useState('');
|
|
12
|
+
const [error, setError] = useState('');
|
|
13
|
+
const [busy, setBusy] = useState(false);
|
|
14
|
+
const [pinRejected, setPinRejected] = useState(false);
|
|
15
|
+
const input = useRef(null);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setPin('');
|
|
18
|
+
setError('');
|
|
19
|
+
setPinRejected(false);
|
|
20
|
+
}, [state, target.title, target.subtitle]);
|
|
21
|
+
async function unlock(event) {
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
if (pin.length < 6) {
|
|
24
|
+
setError(copy.pinRequired);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!onUnlock) {
|
|
28
|
+
setError(copy.unlockUnavailable);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
setBusy(true);
|
|
32
|
+
try {
|
|
33
|
+
const result = await onUnlock(pin);
|
|
34
|
+
if (result === 'unlocked') {
|
|
35
|
+
setPin('');
|
|
36
|
+
setError('');
|
|
37
|
+
setPinRejected(false);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
setPinRejected(result === 'invalid-pin');
|
|
41
|
+
setError(result === 'invalid-pin'
|
|
42
|
+
? copy.invalidPin
|
|
43
|
+
: result === 'temporarily-locked'
|
|
44
|
+
? copy.temporarilyLocked
|
|
45
|
+
: copy.unlockUnavailable);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
setBusy(false);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function unlockWithPasskey() {
|
|
52
|
+
if (!onPasskeyUnlock)
|
|
53
|
+
return;
|
|
54
|
+
setBusy(true);
|
|
55
|
+
setError('');
|
|
56
|
+
try {
|
|
57
|
+
await onPasskeyUnlock();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
setError(copy.unlockUnavailable);
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
setBusy(false);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (state === 'not-required')
|
|
67
|
+
return _jsx(_Fragment, { children: children });
|
|
68
|
+
const title = state === 'checking'
|
|
69
|
+
? copy.checkingTitle
|
|
70
|
+
: state === 'setup-required'
|
|
71
|
+
? copy.setupTitle
|
|
72
|
+
: state === 'unavailable'
|
|
73
|
+
? copy.unavailableTitle
|
|
74
|
+
: copy.unlockTitle;
|
|
75
|
+
const body = state === 'checking'
|
|
76
|
+
? copy.checkingBody
|
|
77
|
+
: state === 'setup-required'
|
|
78
|
+
? copy.setupBody
|
|
79
|
+
: state === 'unavailable'
|
|
80
|
+
? copy.unavailableBody
|
|
81
|
+
: copy.unlockBody;
|
|
82
|
+
return (_jsxs("section", { className: "uhcp-profile-gate uhcp-profile-gate-v2", "aria-live": "polite", children: [_jsxs("div", { className: "uhcp-profile-target", children: [target.icon && _jsx("img", { src: target.icon.src, alt: target.icon.alt, width: target.icon.width, height: target.icon.height }), _jsxs("div", { className: "uhcp-profile-target-copy", children: [_jsx("span", { className: "uhcp-profile-target-eyebrow", children: target.eyebrow }), _jsx("strong", { children: target.title }), target.subtitle && _jsx("span", { children: target.subtitle })] }), target.badges?.length ? _jsx("ul", { className: "uhcp-profile-target-badges", "aria-label": target.eyebrow, children: target.badges.map(badge => _jsx("li", { children: badge }, badge)) }) : null, target.details?.length ? _jsx("dl", { className: "uhcp-profile-target-details", children: target.details.map(detail => _jsxs("div", { children: [_jsx("dt", { children: detail.label }), _jsx("dd", { children: detail.value })] }, `${detail.label}:${detail.value}`)) }) : null] }), _jsxs("div", { className: "uhcp-profile-gate-copy", children: [_jsx("h1", { children: title }), _jsx("p", { children: body })] }), state === 'locked' && onPasskeyUnlock && _jsx("button", { type: "button", "data-portal-action": "unlock-profile-with-passkey", disabled: busy, onClick: unlockWithPasskey, children: copy.unlockWithPasskey }), state === 'locked' && _jsxs("details", { className: "uhcp-profile-pin-fallback", open: !onPasskeyUnlock, children: [_jsx("summary", { children: onPasskeyUnlock ? copy.usePinInstead : copy.pinLabel }), _jsxs("form", { onSubmit: unlock, children: [_jsxs("label", { children: [copy.pinLabel, _jsx("input", { ref: input, type: "password", inputMode: "numeric", minLength: 6, autoComplete: "current-password", value: pin, onChange: (event) => setPin(event.target.value) })] }), error && _jsx("p", { role: "alert", className: "uhcp-error", children: error }), _jsx("button", { type: "submit", "data-portal-action": "unlock-profile", disabled: busy, children: copy.unlock })] }), pinRejected && pinFailureActions ? _jsx("div", { className: "uhcp-profile-pin-recovery", children: pinFailureActions }) : null] }), state === 'unavailable' && onRetry && _jsx("button", { type: "button", onClick: onRetry, children: copy.retry }), secondaryActions && _jsx("div", { className: "uhcp-profile-gate-secondary", children: secondaryActions })] }));
|
|
83
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ClinicalArtifactEditorV2Props, type ClinicalArtifactFieldV2 } from './ClinicalArtifactEditorV2.js';
|
|
2
|
+
import type { ClinicalArtifactSchema } from './ClinicalArtifactEditor.js';
|
|
3
|
+
export type SchemaClinicalArtifactEditorV2Props = Omit<ClinicalArtifactEditorV2Props, 'fields' | 'initialVisibleClaims' | 'initialClaims'> & Readonly<{
|
|
4
|
+
schema: ClinicalArtifactSchema;
|
|
5
|
+
}>;
|
|
6
|
+
/** Adapts every schema-backed IPS resource to the same progressive V2 editor. */
|
|
7
|
+
export declare function SchemaClinicalArtifactEditorV2({ schema, locale, ...props }: SchemaClinicalArtifactEditorV2Props): import("react").JSX.Element;
|
|
8
|
+
/** Keeps form control selection deterministic and owned by the canonical schema/catalog. */
|
|
9
|
+
export declare function clinicalArtifactFieldsV2FromSchema(schema: ClinicalArtifactSchema, locale?: string): readonly ClinicalArtifactFieldV2[];
|
|
10
|
+
//# sourceMappingURL=SchemaClinicalArtifactEditorV2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaClinicalArtifactEditorV2.d.ts","sourceRoot":"","sources":["../src/SchemaClinicalArtifactEditorV2.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAC7B,MAAM,+BAA+B,CAAA;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAEzE,MAAM,MAAM,mCAAmC,GAAG,IAAI,CAAC,6BAA6B,EAAE,QAAQ,GAAG,sBAAsB,GAAG,eAAe,CAAC,GAAG,QAAQ,CAAC;IACpJ,MAAM,EAAE,sBAAsB,CAAA;CAC/B,CAAC,CAAA;AAEF,iFAAiF;AACjF,wBAAgB,8BAA8B,CAAC,EAAE,MAAM,EAAE,MAAa,EAAE,GAAG,KAAK,EAAE,EAAE,mCAAmC,+BAQtH;AAED,4FAA4F;AAC5F,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,sBAAsB,EAAE,MAAM,SAAO,GAAG,SAAS,uBAAuB,EAAE,CA8BpI"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { clinicalArtifactCodedOptionsForClaim } from 'fhir-data-utils-ts';
|
|
4
|
+
import { ClinicalArtifactEditorV2, } from './ClinicalArtifactEditorV2.js';
|
|
5
|
+
/** Adapts every schema-backed IPS resource to the same progressive V2 editor. */
|
|
6
|
+
export function SchemaClinicalArtifactEditorV2({ schema, locale = 'en', ...props }) {
|
|
7
|
+
return _jsx(ClinicalArtifactEditorV2, { ...props, locale: locale, fields: clinicalArtifactFieldsV2FromSchema(schema, locale), initialVisibleClaims: schema.requiredClaims, initialClaims: schema.initialClaims });
|
|
8
|
+
}
|
|
9
|
+
/** Keeps form control selection deterministic and owned by the canonical schema/catalog. */
|
|
10
|
+
export function clinicalArtifactFieldsV2FromSchema(schema, locale = 'en') {
|
|
11
|
+
const required = new Set(schema.requiredClaims);
|
|
12
|
+
const terminologyText = new Set(schema.terminologyTextClaims ?? []);
|
|
13
|
+
const pairedClaims = new Set();
|
|
14
|
+
const fields = [];
|
|
15
|
+
for (const textClaim of terminologyText) {
|
|
16
|
+
const pair = codedClaimPair(textClaim);
|
|
17
|
+
pairedClaims.add(pair.codeClaim);
|
|
18
|
+
pairedClaims.add(pair.displayClaim);
|
|
19
|
+
}
|
|
20
|
+
for (const claim of [...schema.requiredClaims, ...schema.optionalClaims]) {
|
|
21
|
+
if (pairedClaims.has(claim))
|
|
22
|
+
continue;
|
|
23
|
+
const options = clinicalArtifactCodedOptionsForClaim(claim, locale);
|
|
24
|
+
if (terminologyText.has(claim)) {
|
|
25
|
+
const pair = codedClaimPair(claim);
|
|
26
|
+
fields.push({ claim, textClaim: claim, codeClaim: pair.codeClaim, displayClaim: pair.displayClaim, kind: 'coded-concept', required: required.has(claim) });
|
|
27
|
+
}
|
|
28
|
+
else if (options.length) {
|
|
29
|
+
fields.push({ claim, kind: 'coded-select', required: required.has(claim), options: options.map(option => ({ value: option.code, label: option.label })) });
|
|
30
|
+
}
|
|
31
|
+
else if (isDateTimeClaim(claim)) {
|
|
32
|
+
fields.push({ claim, kind: 'date-time', required: required.has(claim) });
|
|
33
|
+
}
|
|
34
|
+
else if (isPositiveIntegerClaim(claim)) {
|
|
35
|
+
fields.push({ claim, kind: 'positive-integer', required: required.has(claim) });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
fields.push({ claim, kind: 'text', required: required.has(claim) });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
fields.push({ claim: '__documents', kind: 'documents', transient: true });
|
|
42
|
+
return Object.freeze(fields);
|
|
43
|
+
}
|
|
44
|
+
function codedClaimPair(textClaim) {
|
|
45
|
+
if (textClaim.endsWith('-text')) {
|
|
46
|
+
const base = textClaim.slice(0, -'-text'.length);
|
|
47
|
+
return { codeClaim: base, displayClaim: `${base}-display` };
|
|
48
|
+
}
|
|
49
|
+
if (textClaim.endsWith('.code-text')) {
|
|
50
|
+
const base = textClaim.slice(0, -'-text'.length);
|
|
51
|
+
return { codeClaim: base, displayClaim: `${base}-display` };
|
|
52
|
+
}
|
|
53
|
+
return { codeClaim: `${textClaim}-code`, displayClaim: `${textClaim}-display` };
|
|
54
|
+
}
|
|
55
|
+
function isDateTimeClaim(claim) {
|
|
56
|
+
return /(?:^|[-.])(date|datetime|effective|onset)(?:$|[-.])/.test(claim);
|
|
57
|
+
}
|
|
58
|
+
function isPositiveIntegerClaim(claim) {
|
|
59
|
+
return /(?:dose-sequence|series-doses|timing-frequency)$/.test(claim);
|
|
60
|
+
}
|
package/dist/contracts.d.ts
CHANGED
|
@@ -87,4 +87,20 @@ export type ProfileProtectionCopy = Readonly<{
|
|
|
87
87
|
unlock: string;
|
|
88
88
|
retry: string;
|
|
89
89
|
}>;
|
|
90
|
+
/** Human-readable metadata for a host-authorized profile or subject target. */
|
|
91
|
+
export type ProfileProtectionTargetV2 = Readonly<{
|
|
92
|
+
eyebrow: string;
|
|
93
|
+
title: string;
|
|
94
|
+
subtitle?: string;
|
|
95
|
+
icon?: PortalBrandAsset;
|
|
96
|
+
badges?: readonly string[];
|
|
97
|
+
details?: readonly Readonly<{
|
|
98
|
+
label: string;
|
|
99
|
+
value: string;
|
|
100
|
+
}>[];
|
|
101
|
+
}>;
|
|
102
|
+
export type ProfileProtectionCopyV2 = ProfileProtectionCopy & Readonly<{
|
|
103
|
+
unlockWithPasskey: string;
|
|
104
|
+
usePinInstead: string;
|
|
105
|
+
}>;
|
|
90
106
|
//# sourceMappingURL=contracts.d.ts.map
|
package/dist/contracts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,eAAO,MAAM,iBAAiB,uCAAwC,CAAA;AACtE,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEhE,eAAO,MAAM,cAAc,sCAAuC,CAAA;AAClE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,WAAW,EAAE,gBAAgB,CAAA;IAC7B,YAAY,EAAE,gBAAgB,CAAA;CAC/B,CAAC,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,6EAA6E;IAC7E,MAAM,EAAE,UAAU,GAAG,cAAc,CAAA;IACnC,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,mDAAmD;IACnD,IAAI,EAAE,qBAAqB,CAAA;IAC3B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC,SAAS,CAAC,EAAE,aAAa,CAAA;CAC1B,CAAC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAC,CAAA;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC,CAAC,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,qBAAqB,EAAE,MAAM,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAC9B,cAAc,GACd,UAAU,GACV,gBAAgB,GAChB,QAAQ,GACR,aAAa,CAAA;AAEjB,MAAM,MAAM,mBAAmB,GAC3B,UAAU,GACV,aAAa,GACb,oBAAoB,GACpB,aAAa,CAAA;AAEjB,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../src/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,eAAO,MAAM,iBAAiB,uCAAwC,CAAA;AACtE,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEhE,eAAO,MAAM,cAAc,sCAAuC,CAAA;AAClE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAC,CAAA;AAEF;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,WAAW,EAAE,gBAAgB,CAAA;IAC7B,YAAY,EAAE,gBAAgB,CAAA;CAC/B,CAAC,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,6EAA6E;IAC7E,MAAM,EAAE,UAAU,GAAG,cAAc,CAAA;IACnC,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,mDAAmD;IACnD,IAAI,EAAE,qBAAqB,CAAA;IAC3B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC,SAAS,CAAC,EAAE,aAAa,CAAA;CAC1B,CAAC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB,CAAC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAC,CAAA;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC,CAAC,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,qBAAqB,EAAE,MAAM,CAAA;IAC7B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAA;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAC9B,cAAc,GACd,UAAU,GACV,gBAAgB,GAChB,QAAQ,GACR,aAAa,CAAA;AAEjB,MAAM,MAAM,mBAAmB,GAC3B,UAAU,GACV,aAAa,GACb,oBAAoB,GACpB,aAAa,CAAA;AAEjB,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd,CAAC,CAAA;AAEF,+EAA+E;AAC/E,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,gBAAgB,CAAA;IACvB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,OAAO,CAAC,EAAE,SAAS,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAA;CAChE,CAAC,CAAA;AAEF,MAAM,MAAM,uBAAuB,GAAG,qBAAqB,GAAG,QAAQ,CAAC;IACrE,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;CACtB,CAAC,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export * from './PortalCurrentSubject.js';
|
|
|
6
6
|
export * from './PortalShell.js';
|
|
7
7
|
export * from './PortalEntry.js';
|
|
8
8
|
export * from './ProfileProtectionGate.js';
|
|
9
|
+
export * from './ProfileProtectionGateV2.js';
|
|
9
10
|
export * from './PortalLoadingSkeleton.js';
|
|
10
11
|
export * from './ClinicalSectionSummary.js';
|
|
11
12
|
export * from './IpsBundleSummary.js';
|
|
@@ -15,6 +16,7 @@ export * from './ClinicalTimeline.js';
|
|
|
15
16
|
export * from './ClinicalArtifactEditor.js';
|
|
16
17
|
export * from './ClinicalArtifactPropertiesV2.js';
|
|
17
18
|
export * from './ClinicalArtifactEditorV2.js';
|
|
19
|
+
export * from './SchemaClinicalArtifactEditorV2.js';
|
|
18
20
|
export * from './ImmunizationArtifactEditorV2.js';
|
|
19
21
|
export * from './ClinicalBundleDraftEditor.js';
|
|
20
22
|
export * from './ClinicalSpeechInput.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,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,yBAAyB,CAAA;AACvC,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,8BAA8B,CAAA;AAC5C,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,qCAAqC,CAAA;AACnD,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,yBAAyB,CAAA;AACvC,cAAc,uCAAuC,CAAA;AACrD,cAAc,uBAAuB,CAAA;AACrC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,8BAA8B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export * from './PortalCurrentSubject.js';
|
|
|
6
6
|
export * from './PortalShell.js';
|
|
7
7
|
export * from './PortalEntry.js';
|
|
8
8
|
export * from './ProfileProtectionGate.js';
|
|
9
|
+
export * from './ProfileProtectionGateV2.js';
|
|
9
10
|
export * from './PortalLoadingSkeleton.js';
|
|
10
11
|
export * from './ClinicalSectionSummary.js';
|
|
11
12
|
export * from './IpsBundleSummary.js';
|
|
@@ -15,6 +16,7 @@ export * from './ClinicalTimeline.js';
|
|
|
15
16
|
export * from './ClinicalArtifactEditor.js';
|
|
16
17
|
export * from './ClinicalArtifactPropertiesV2.js';
|
|
17
18
|
export * from './ClinicalArtifactEditorV2.js';
|
|
19
|
+
export * from './SchemaClinicalArtifactEditorV2.js';
|
|
18
20
|
export * from './ImmunizationArtifactEditorV2.js';
|
|
19
21
|
export * from './ClinicalBundleDraftEditor.js';
|
|
20
22
|
export * from './ClinicalSpeechInput.js';
|
package/dist/styles.css
CHANGED
|
@@ -161,6 +161,27 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
|
|
|
161
161
|
.uhcp-profile-gate label { color: var(--uhcp-muted); display: grid; gap: .45rem; }
|
|
162
162
|
.uhcp-profile-gate input { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: .75rem; color: var(--uhcp-text); padding: .8rem; }
|
|
163
163
|
.uhcp-profile-gate button { background: linear-gradient(135deg, var(--uhcp-action-start), var(--uhcp-action-end)); border: 0; border-radius: .75rem; color: #fff; cursor: pointer; font: inherit; font-weight: 800; padding: .8rem 1rem; }
|
|
164
|
+
.uhcp-profile-gate-v2 { background: linear-gradient(145deg, color-mix(in srgb, var(--uhcp-surface-accent) 76%, var(--uhcp-panel)), var(--uhcp-panel-muted)); border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 30%, var(--uhcp-border)); border-radius: 1.5rem; box-shadow: 0 1.2rem 3rem color-mix(in srgb, var(--uhcp-text) 10%, transparent); gap: 1rem; }
|
|
165
|
+
.uhcp-profile-target { background: linear-gradient(135deg, color-mix(in srgb, var(--uhcp-surface-accent) 80%, var(--uhcp-panel)), color-mix(in srgb, var(--uhcp-turquoise) 12%, var(--uhcp-panel))); border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 38%, var(--uhcp-border)); border-radius: 1rem; display: grid; gap: .8rem; padding: 1rem; }
|
|
166
|
+
.uhcp-profile-target > img { border-radius: .75rem; object-fit: contain; }
|
|
167
|
+
.uhcp-profile-target-copy { display: grid; gap: .2rem; }
|
|
168
|
+
.uhcp-profile-target-copy > strong { color: var(--uhcp-text); font-size: 1.2rem; }
|
|
169
|
+
.uhcp-profile-target-copy > span:last-child { color: var(--uhcp-muted); }
|
|
170
|
+
.uhcp-profile-target-eyebrow { color: var(--uhcp-muted); font-size: .78rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
|
|
171
|
+
.uhcp-profile-target-badges { display: flex; flex-wrap: wrap; gap: .45rem; list-style: none; margin: 0; padding: 0; }
|
|
172
|
+
.uhcp-profile-target-badges li { background: color-mix(in srgb, var(--uhcp-turquoise) 13%, var(--uhcp-panel)); border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 36%, var(--uhcp-border)); border-radius: 999px; color: var(--uhcp-text); padding: .35rem .65rem; }
|
|
173
|
+
.uhcp-profile-target-details { margin: 0; }
|
|
174
|
+
.uhcp-profile-target-details > div { display: grid; gap: .2rem; grid-template-columns: minmax(8rem, auto) 1fr; }
|
|
175
|
+
.uhcp-profile-target-details dt { color: var(--uhcp-muted); }
|
|
176
|
+
.uhcp-profile-target-details dd { color: var(--uhcp-text); font-weight: 700; margin: 0; }
|
|
177
|
+
.uhcp-profile-pin-fallback { border-top: 1px solid var(--uhcp-border); padding-top: .8rem; }
|
|
178
|
+
.uhcp-profile-pin-fallback summary { color: var(--uhcp-text); cursor: pointer; font-weight: 700; }
|
|
179
|
+
.uhcp-profile-pin-fallback form { margin-top: .8rem; }
|
|
180
|
+
.uhcp-profile-pin-recovery { display: flex; justify-content: flex-start; margin-top: .7rem; }
|
|
181
|
+
.uhcp-profile-pin-recovery button { background: transparent; border: 1px solid var(--uhcp-border); color: var(--uhcp-text); }
|
|
182
|
+
.uhcp-profile-gate-secondary { border-top: 1px solid var(--uhcp-border); display: grid; gap: .6rem; padding-top: .8rem; }
|
|
183
|
+
.uhcp-profile-gate-secondary .uhcp-add-profile-action { align-items: center; background: transparent; border: 1px solid color-mix(in srgb, var(--uhcp-turquoise) 35%, var(--uhcp-border)); color: var(--uhcp-text); display: inline-flex; gap: .65rem; justify-content: flex-start; }
|
|
184
|
+
.uhcp-profile-gate-secondary .uhcp-add-profile-action::first-letter { color: var(--uhcp-turquoise); font-size: 1.25em; }
|
|
164
185
|
.uhcp-error { color: #c64747 !important; }
|
|
165
186
|
.uhcp-shell { background: var(--uhcp-surface); color: var(--uhcp-text); min-height: 100vh; }
|
|
166
187
|
.uhcp-main { min-height: calc(100vh - 4.5rem); }
|
|
@@ -503,29 +524,35 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
|
|
|
503
524
|
.uhcp-clinical-bundle-draft { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:1.5rem; color:var(--uhcp-text); display:grid; gap:1rem; padding:1.25rem; }
|
|
504
525
|
.uhcp-clinical-bundle-draft>header h2,.uhcp-clinical-bundle-draft>header p { margin:.15rem 0; }
|
|
505
526
|
.uhcp-clinical-bundle-draft>header p,.uhcp-clinical-bundle-draft details>p { color:var(--uhcp-muted); }
|
|
506
|
-
.uhcp-clinical-bundle-draft details { background:var(--uhcp-panel-muted); border:1px solid var(--uhcp-border); border-radius:1rem; padding:.85rem 1rem; }
|
|
527
|
+
.uhcp-clinical-bundle-draft details { background:var(--uhcp-panel-muted); border:1px solid var(--uhcp-border); border-radius:1rem; padding:.85rem 1rem; position:relative; }
|
|
507
528
|
.uhcp-clinical-bundle-draft summary { cursor:pointer; font-weight:800; }
|
|
508
529
|
.uhcp-clinical-bundle-draft-create { align-items:end; background:var(--uhcp-panel-muted); border:1px solid var(--uhcp-border); border-radius:1rem; display:grid; gap:.8rem; grid-template-columns:minmax(10rem,1fr) minmax(10rem,1fr) auto; padding:1rem; }
|
|
509
530
|
.uhcp-clinical-bundle-draft-create label { display:grid; gap:.35rem; font-weight:700; }
|
|
510
531
|
.uhcp-clinical-bundle-draft-create select { background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.7rem; color:var(--uhcp-text); font:inherit; min-height:2.75rem; padding:.55rem .7rem; }
|
|
511
|
-
.uhcp-clinical-bundle-draft-create button { background:
|
|
532
|
+
.uhcp-clinical-bundle-draft-create button.uhcp-add-section-button { background:color-mix(in srgb,var(--uhcp-turquoise) 13%,var(--uhcp-panel)); border:1px solid color-mix(in srgb,var(--uhcp-turquoise) 45%,var(--uhcp-border)); border-radius:.75rem; color:var(--uhcp-text); cursor:pointer; font:inherit; font-weight:800; min-height:2.75rem; padding:.65rem 1rem; }
|
|
512
533
|
.uhcp-clinical-bundle-draft-create button:disabled { cursor:not-allowed; opacity:.5; }
|
|
534
|
+
.uhcp-clinical-bundle-draft .uhcp-add-entry-button { background:var(--uhcp-emerald); border:0; border-radius:.65rem; color:#fff; cursor:pointer; font-size:1.3rem; font-weight:900; height:2.5rem; margin-top:.65rem; width:2.5rem; }
|
|
535
|
+
.uhcp-clinical-bundle-draft .uhcp-remove-section-button { background:color-mix(in srgb,#c64747 12%,var(--uhcp-panel)); border:1px solid color-mix(in srgb,#c64747 42%,var(--uhcp-border)); border-radius:.6rem; color:#a72f2f; cursor:pointer; font-size:1.25rem; font-weight:900; height:2.25rem; position:absolute; right:.7rem; top:.55rem; width:2.25rem; }
|
|
513
536
|
.uhcp-clinical-bundle-draft ul { display:grid; gap:.55rem; list-style:none; margin:.8rem 0 0; padding:0; }
|
|
514
537
|
.uhcp-clinical-bundle-draft li { align-items:center; background:var(--uhcp-panel); border:1px solid var(--uhcp-border); border-radius:.8rem; display:flex; gap:1rem; justify-content:space-between; padding:.7rem; }
|
|
515
538
|
.uhcp-clinical-bundle-draft li>span { display:flex; gap:.45rem; }
|
|
516
539
|
.uhcp-clinical-bundle-draft li>span:first-child { align-items:flex-start; flex-direction:column; min-width:0; }
|
|
517
540
|
.uhcp-clinical-bundle-draft li strong { overflow-wrap:anywhere; }
|
|
518
541
|
.uhcp-clinical-bundle-draft li small { color:var(--uhcp-muted); }
|
|
519
|
-
.uhcp-clinical-bundle-draft>footer { display:flex; justify-content:
|
|
520
|
-
.uhcp-clinical-
|
|
521
|
-
.uhcp-clinical-bundle-draft>footer
|
|
542
|
+
.uhcp-clinical-bundle-draft>footer { align-items:center; background:var(--uhcp-panel-muted); border:1px solid var(--uhcp-border); border-radius:1rem; display:flex; gap:.75rem; justify-content:space-between; padding:.7rem .8rem; }
|
|
543
|
+
.uhcp-clinical-document-secondary-actions { align-items:center; display:flex; flex:1; flex-wrap:wrap; gap:.65rem; min-width:0; }
|
|
544
|
+
.uhcp-clinical-bundle-draft>footer .uhcp-clinical-document-submit { background:var(--uhcp-emerald); border:0; border-radius:.75rem; color:#fff; cursor:pointer; flex:0 0 auto; font:inherit; font-weight:800; padding:.75rem 1rem; }
|
|
545
|
+
.uhcp-clinical-bundle-draft>footer .uhcp-clinical-document-submit:disabled { cursor:not-allowed; opacity:.5; }
|
|
546
|
+
.uhcp-clinical-bundle-draft .uhcp-clinical-entry-credential-action { background:color-mix(in srgb,var(--uhcp-attention) 24%,var(--uhcp-panel)); border:1px solid color-mix(in srgb,var(--uhcp-attention) 58%,var(--uhcp-border)); color:var(--uhcp-text); }
|
|
547
|
+
.uhcp-clinical-bundle-draft button[data-tooltip],.uhcp-clinical-icon-action[data-tooltip] { position:relative; }
|
|
548
|
+
.uhcp-clinical-bundle-draft button[data-tooltip]:is(:hover,:focus-visible)::after,.uhcp-clinical-icon-action[data-tooltip]:is(:hover,:focus-visible)::after { background:var(--uhcp-text); border-radius:.45rem; bottom:calc(100% + .45rem); color:var(--uhcp-panel); content:attr(data-tooltip); font-size:.78rem; font-weight:700; left:50%; max-width:16rem; padding:.35rem .5rem; pointer-events:none; position:absolute; transform:translateX(-50%); white-space:nowrap; z-index:50; }
|
|
522
549
|
.uhcp-clinical-editor-attachments { border:1px solid var(--uhcp-border); border-radius:.85rem; display:grid; gap:.65rem; grid-column:1/-1; padding:.85rem; }
|
|
523
550
|
.uhcp-clinical-editor-attachments label { display:grid; gap:.35rem; }
|
|
524
551
|
.uhcp-clinical-editor-attachments input[type=file] { border:1px dashed var(--uhcp-border); border-radius:.7rem; padding:.65rem; }
|
|
525
552
|
.uhcp-clinical-editor-attachments ul { display:grid; gap:.4rem; list-style:none; margin:0; padding:0; }
|
|
526
553
|
.uhcp-clinical-editor-attachments li { align-items:center; background:var(--uhcp-panel-muted); border-radius:.65rem; display:flex; justify-content:space-between; padding:.5rem .65rem; }
|
|
527
554
|
.uhcp-clinical-editor-attachments li button { background:transparent; border:0; color:var(--uhcp-text); cursor:pointer; font-size:1.2rem; }
|
|
528
|
-
@media (max-width:720px) { .uhcp-clinical-bundle-draft-create { grid-template-columns:1fr; } }
|
|
555
|
+
@media (max-width:720px) { .uhcp-clinical-bundle-draft-create { grid-template-columns:1fr; } .uhcp-clinical-bundle-draft>footer { align-items:stretch; flex-direction:column; } .uhcp-clinical-bundle-draft>footer .uhcp-clinical-document-submit { align-self:flex-end; } }
|
|
529
556
|
.uhcp-clinical-title { font-weight: 800; margin: 0; }
|
|
530
557
|
.uhcp-clinical-type { color: var(--uhcp-muted); font-size: .72rem; font-weight: 800; letter-spacing: .06em; margin: .35rem 0 0; text-transform: uppercase; }
|
|
531
558
|
.uhcp-clinical-date, .uhcp-clinical-empty { color: var(--uhcp-muted); margin: .35rem 0 0; }
|
package/package.json
CHANGED