uhc-portal-components-react 0.1.16 → 0.1.18
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 +16 -0
- package/README.md +3 -1
- package/dist/SoschainWorkspace.d.ts +27 -2
- package/dist/SoschainWorkspace.d.ts.map +1 -1
- package/dist/SoschainWorkspace.js +26 -8
- package/dist/SubjectAccessRequestPanel.d.ts +10 -2
- package/dist/SubjectAccessRequestPanel.d.ts.map +1 -1
- package/dist/SubjectAccessRequestPanel.js +13 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.18
|
|
4
|
+
|
|
5
|
+
- Add shared, read-only Health summary and Care journey areas to the SOSChain
|
|
6
|
+
subject workspace used by Personal and Professional portals.
|
|
7
|
+
- Render only host-authorized IPS content and bounded Encounter projections;
|
|
8
|
+
card or tab selection never exposes clinical mutation controls.
|
|
9
|
+
|
|
10
|
+
## 0.1.17
|
|
11
|
+
|
|
12
|
+
- Add provider-enabled microchip, tattoo, email and telephone subject locator
|
|
13
|
+
kinds without exposing any locator that the owning BFF has not enabled.
|
|
14
|
+
- Carry server-returned identifier evidence as presentation-only metadata and
|
|
15
|
+
add suitable browser input hints for ISO animal microchips and contacts.
|
|
16
|
+
|
|
3
17
|
## 0.1.16
|
|
4
18
|
|
|
5
19
|
- Add `IdentityEvidenceDocumentPanel`, a brand-neutral signed-PDF upload and
|
|
@@ -37,6 +51,8 @@
|
|
|
37
51
|
|
|
38
52
|
## Unreleased
|
|
39
53
|
|
|
54
|
+
- Add the repository-wide mandatory red-green-refactor contributor contract
|
|
55
|
+
and mark the existing component suites with an explicit TDD contract header.
|
|
40
56
|
- Correct the reuse contract: the package currently provides presentation
|
|
41
57
|
primitives, not the full UHC Personal route journeys. Document the extraction
|
|
42
58
|
required before PetChain can reuse login, protected profiles, individuals,
|
package/README.md
CHANGED
|
@@ -56,7 +56,9 @@ The package deliberately exposes modules instead of a cloned application:
|
|
|
56
56
|
- `InvitationAcceptancePanel`: controlled invitation-code UI for a related
|
|
57
57
|
individual member; the host refreshes the authorized-subject list after its
|
|
58
58
|
BFF accepts the invitation.
|
|
59
|
-
- `SubjectAccessRequestPanel`: controlled QR, numeric-code
|
|
59
|
+
- `SubjectAccessRequestPanel`: controlled provider-enabled QR, numeric-code,
|
|
60
|
+
`did:web`, microchip, tattoo, email or telephone locator. Resolution and
|
|
61
|
+
returned identifier evidence never grant subject access.
|
|
60
62
|
resolver plus section selector. It deliberately has no scanner role: the
|
|
61
63
|
same component is reusable by an individual member or a professional.
|
|
62
64
|
- `SoschainWorkspace`: subject-card picker and four-area workspace for Places,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type ProtectedIndexEmergencyCopy, type ProtectedIndexEmergencyItem } from './ProtectedIndexEmergencyData.js';
|
|
2
|
-
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
export declare const SOSCHAIN_SUBJECT_WORKSPACE_AREAS: readonly ["overview", "health-summary", "care-journey", "emergency-data", "communications", "places", "products"];
|
|
4
|
+
export type SoschainWorkspaceArea = typeof SOSCHAIN_SUBJECT_WORKSPACE_AREAS[number];
|
|
3
5
|
export type SoschainCardSummary = Readonly<{
|
|
4
6
|
identifier: string;
|
|
5
7
|
displayName: string;
|
|
@@ -23,6 +25,20 @@ export type SoschainCommunicationSummary = Readonly<{
|
|
|
23
25
|
occurredAt: string;
|
|
24
26
|
placeLabel?: string;
|
|
25
27
|
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Minimum Encounter projection suitable for a controller/member timeline.
|
|
30
|
+
* The host must already have removed room, bed, diagnosis and other details
|
|
31
|
+
* that the current actor is not authorized to read.
|
|
32
|
+
*/
|
|
33
|
+
export type SoschainCareJourneyEntry = Readonly<{
|
|
34
|
+
identifier: string;
|
|
35
|
+
statusLabel: string;
|
|
36
|
+
serviceLabel: string;
|
|
37
|
+
periodStart: string;
|
|
38
|
+
periodEnd?: string;
|
|
39
|
+
locationLabel?: string;
|
|
40
|
+
detail?: string;
|
|
41
|
+
}>;
|
|
26
42
|
export type SoschainWorkspaceCopy = Readonly<{
|
|
27
43
|
cardsTitle: string;
|
|
28
44
|
cardsDescription: string;
|
|
@@ -34,6 +50,12 @@ export type SoschainWorkspaceCopy = Readonly<{
|
|
|
34
50
|
areas: Record<SoschainWorkspaceArea, string>;
|
|
35
51
|
overviewTitle: string;
|
|
36
52
|
overviewBody: string;
|
|
53
|
+
healthSummaryTitle: string;
|
|
54
|
+
healthSummaryBody: string;
|
|
55
|
+
emptyHealthSummary: string;
|
|
56
|
+
careJourneyTitle: string;
|
|
57
|
+
careJourneyBody: string;
|
|
58
|
+
emptyCareJourney: string;
|
|
37
59
|
emergencyDataTitle: string;
|
|
38
60
|
emergencyDataBody: string;
|
|
39
61
|
emergencyData: ProtectedIndexEmergencyCopy;
|
|
@@ -60,6 +82,9 @@ export type SoschainWorkspaceProps = Readonly<{
|
|
|
60
82
|
places: readonly SoschainAssociationSummary[];
|
|
61
83
|
products: readonly SoschainAssociationSummary[];
|
|
62
84
|
communications: readonly SoschainCommunicationSummary[];
|
|
85
|
+
/** Host-authorized IPS/clinical projection, normally `IpsBundleSummary`. */
|
|
86
|
+
healthSummary?: ReactNode;
|
|
87
|
+
careJourney?: readonly SoschainCareJourneyEntry[];
|
|
63
88
|
emergencyData?: readonly ProtectedIndexEmergencyItem[];
|
|
64
89
|
canManageAssociations: boolean;
|
|
65
90
|
addPlaceHref?: string;
|
|
@@ -73,5 +98,5 @@ export type SoschainWorkspaceProps = Readonly<{
|
|
|
73
98
|
* communications. This presentational component never derives authority from
|
|
74
99
|
* a selected role, card, tab or browser-controlled value.
|
|
75
100
|
*/
|
|
76
|
-
export declare function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, emergencyData, canManageAssociations, addPlaceHref, addProductHref, importCardHref, }: SoschainWorkspaceProps): import("react").JSX.Element;
|
|
101
|
+
export declare function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, healthSummary, careJourney, emergencyData, canManageAssociations, addPlaceHref, addProductHref, importCardHref, }: SoschainWorkspaceProps): import("react").JSX.Element;
|
|
77
102
|
//# sourceMappingURL=SoschainWorkspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SoschainWorkspace.d.ts","sourceRoot":"","sources":["../src/SoschainWorkspace.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,2BAA2B,EAAE,KAAK,2BAA2B,EAAE,MAAM,kCAAkC,CAAA;
|
|
1
|
+
{"version":3,"file":"SoschainWorkspace.d.ts","sourceRoot":"","sources":["../src/SoschainWorkspace.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ProtectedIndexEmergencyData } from './ProtectedIndexEmergencyData.js';
|
|
3
|
+
export const SOSCHAIN_SUBJECT_WORKSPACE_AREAS = [
|
|
4
|
+
'overview',
|
|
5
|
+
'health-summary',
|
|
6
|
+
'care-journey',
|
|
7
|
+
'emergency-data',
|
|
8
|
+
'communications',
|
|
9
|
+
'places',
|
|
10
|
+
'products',
|
|
11
|
+
];
|
|
3
12
|
function AssociationList({ items, empty }) {
|
|
4
13
|
if (items.length === 0)
|
|
5
14
|
return _jsx("p", { className: "uhcp-sos-empty", children: empty });
|
|
@@ -12,7 +21,7 @@ function AssociationList({ items, empty }) {
|
|
|
12
21
|
* communications. This presentational component never derives authority from
|
|
13
22
|
* a selected role, card, tab or browser-controlled value.
|
|
14
23
|
*/
|
|
15
|
-
export function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, emergencyData = [], canManageAssociations, addPlaceHref, addProductHref, importCardHref, }) {
|
|
24
|
+
export function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, healthSummary, careJourney = [], emergencyData = [], canManageAssociations, addPlaceHref, addProductHref, importCardHref, }) {
|
|
16
25
|
if (!selectedCard) {
|
|
17
26
|
return (_jsxs("section", { className: "uhcp-sos-wrap", "aria-labelledby": "sos-card-picker-title", children: [_jsxs("header", { className: "uhcp-sos-heading", children: [_jsx("span", { children: copy.workspaceEyebrow }), _jsx("h1", { id: "sos-card-picker-title", children: copy.cardsTitle }), _jsx("p", { children: copy.cardsDescription }), importCardHref && copy.importCard ? _jsxs("a", { href: importCardHref, children: [copy.importCard, " \u2192"] }) : null] }), cards.length === 0 ? (_jsxs("div", { className: "uhcp-sos-empty-panel", children: [_jsx("h2", { children: copy.noCardTitle }), _jsx("p", { children: copy.noCardBody })] })) : (_jsx("ul", { className: "uhcp-sos-card-grid", children: cards.map((card) => (_jsx("li", { children: _jsxs("a", { href: card.openHref, children: [_jsx("span", { children: card.kindLabel }), _jsx("strong", { children: card.displayName }), _jsx("small", { children: card.identifier }), _jsxs("b", { children: [copy.openCard, " \u2192"] })] }) }, card.identifier))) }))] }));
|
|
18
27
|
}
|
|
@@ -22,17 +31,26 @@ export function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaH
|
|
|
22
31
|
? copy.productsTitle
|
|
23
32
|
: activeArea === 'communications'
|
|
24
33
|
? copy.communicationsTitle
|
|
25
|
-
: activeArea === '
|
|
26
|
-
? copy.
|
|
27
|
-
:
|
|
34
|
+
: activeArea === 'health-summary'
|
|
35
|
+
? copy.healthSummaryTitle
|
|
36
|
+
: activeArea === 'care-journey'
|
|
37
|
+
? copy.careJourneyTitle
|
|
38
|
+
: activeArea === 'emergency-data'
|
|
39
|
+
? copy.emergencyDataTitle
|
|
40
|
+
: copy.overviewTitle;
|
|
28
41
|
const body = activeArea === 'places'
|
|
29
42
|
? copy.placesBody
|
|
30
43
|
: activeArea === 'products'
|
|
31
44
|
? copy.productsBody
|
|
32
45
|
: activeArea === 'communications'
|
|
33
46
|
? copy.communicationsBody
|
|
34
|
-
: activeArea === '
|
|
35
|
-
? copy.
|
|
36
|
-
:
|
|
37
|
-
|
|
47
|
+
: activeArea === 'health-summary'
|
|
48
|
+
? copy.healthSummaryBody
|
|
49
|
+
: activeArea === 'care-journey'
|
|
50
|
+
? copy.careJourneyBody
|
|
51
|
+
: activeArea === 'emergency-data'
|
|
52
|
+
? copy.emergencyDataBody
|
|
53
|
+
: copy.overviewBody;
|
|
54
|
+
const clinicalAreaIsReadOnly = activeArea === 'health-summary' || activeArea === 'care-journey';
|
|
55
|
+
return (_jsxs("section", { className: "uhcp-sos-wrap", children: [_jsxs("header", { className: "uhcp-sos-heading", children: [_jsx("span", { children: copy.selectedCard }), _jsx("h1", { children: selectedCard.displayName }), _jsxs("p", { children: [selectedCard.kindLabel, " \u00B7 ", selectedCard.identifier] })] }), _jsx("nav", { className: "uhcp-sos-tabs", "aria-label": copy.workspaceEyebrow, children: SOSCHAIN_SUBJECT_WORKSPACE_AREAS.map((area) => (_jsx("a", { href: areaHrefs[area], "aria-current": activeArea === area ? 'page' : undefined, children: copy.areas[area] }, area))) }), _jsxs("div", { className: "uhcp-sos-panel", children: [_jsxs("header", { children: [_jsxs("div", { children: [_jsx("h2", { children: title }), _jsx("p", { children: body })] }), (clinicalAreaIsReadOnly || (!canManageAssociations && activeArea !== 'communications' && activeArea !== 'emergency-data')) && (_jsx("span", { className: "uhcp-sos-readonly", children: copy.readOnly })), canManageAssociations && activeArea === 'places' && addPlaceHref && _jsx("a", { href: addPlaceHref, children: copy.addPlace }), canManageAssociations && activeArea === 'products' && addProductHref && _jsx("a", { href: addProductHref, children: copy.addProduct })] }), activeArea === 'overview' && (_jsxs("div", { className: "uhcp-sos-overview-grid", children: [_jsxs("article", { children: [_jsx("strong", { children: places.length }), _jsx("span", { children: copy.areas.places })] }), _jsxs("article", { children: [_jsx("strong", { children: products.length }), _jsx("span", { children: copy.areas.products })] }), _jsxs("article", { children: [_jsx("strong", { children: communications.length }), _jsx("span", { children: copy.areas.communications })] }), _jsxs("article", { children: [_jsx("strong", { children: careJourney.length }), _jsx("span", { children: copy.areas['care-journey'] })] })] })), activeArea === 'health-summary' && (healthSummary ?? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyHealthSummary })), activeArea === 'care-journey' && (careJourney.length === 0 ? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyCareJourney }) : (_jsx("ol", { className: "uhcp-sos-timeline uhcp-sos-care-journey", children: careJourney.map((encounter) => (_jsxs("li", { children: [_jsxs("div", { children: [_jsx("span", { children: encounter.statusLabel }), _jsx("time", { dateTime: encounter.periodStart, children: encounter.periodStart })] }), _jsx("strong", { children: encounter.serviceLabel }), encounter.detail ? _jsx("p", { children: encounter.detail }) : null, encounter.locationLabel || encounter.periodEnd ? _jsx("small", { children: [encounter.locationLabel, encounter.periodEnd].filter(Boolean).join(' · ') }) : null] }, encounter.identifier))) }))), activeArea === 'emergency-data' && _jsx(ProtectedIndexEmergencyData, { copy: copy.emergencyData, items: emergencyData }), activeArea === 'places' && _jsx(AssociationList, { items: places, empty: copy.emptyPlaces }), activeArea === 'products' && _jsx(AssociationList, { items: products, empty: copy.emptyProducts }), activeArea === 'communications' && (communications.length === 0 ? _jsx("p", { className: "uhcp-sos-empty", children: copy.emptyCommunications }) : (_jsx("ol", { className: "uhcp-sos-timeline", children: communications.map((message) => (_jsxs("li", { children: [_jsxs("div", { children: [_jsx("span", { children: message.categoryLabel }), _jsx("time", { children: message.occurredAt })] }), _jsx("strong", { children: message.subject }), _jsx("p", { children: message.body }), _jsxs("small", { children: [message.sender, message.placeLabel ? ` · ${message.placeLabel}` : ''] })] }, message.identifier))) })))] })] }));
|
|
38
56
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SubjectLocatorKind = 'qr' | 'numeric-code' | 'did-web';
|
|
1
|
+
export type SubjectLocatorKind = 'qr' | 'numeric-code' | 'did-web' | 'microchip' | 'tattoo' | 'email-address' | 'phone-number';
|
|
2
2
|
export type SubjectAccessRequestStatus = 'idle' | 'resolving' | 'resolved' | 'requesting' | 'requested' | 'granted' | 'error';
|
|
3
3
|
export type SubjectAccessSectionOption = Readonly<{
|
|
4
4
|
code: string;
|
|
@@ -8,12 +8,20 @@ export type SubjectAccessSectionOption = Readonly<{
|
|
|
8
8
|
export type ResolvedSubjectAccessTarget = Readonly<{
|
|
9
9
|
subjectId: string;
|
|
10
10
|
display: string;
|
|
11
|
+
/** Server-returned evidence for presentation only; it grants no access. */
|
|
12
|
+
identifiers?: readonly Readonly<{
|
|
13
|
+
kind: SubjectLocatorKind;
|
|
14
|
+
system: string;
|
|
15
|
+
value: string;
|
|
16
|
+
attested: boolean;
|
|
17
|
+
}>[];
|
|
11
18
|
}>;
|
|
12
19
|
export type SubjectAccessRequestPanelCopy = Readonly<{
|
|
13
20
|
title: string;
|
|
14
21
|
description: string;
|
|
15
22
|
locatorKindLabel: string;
|
|
16
|
-
|
|
23
|
+
/** Only entries authorized and supported by the owning product are shown. */
|
|
24
|
+
locatorKinds: Partial<Record<SubjectLocatorKind, string>>;
|
|
17
25
|
locatorLabel: string;
|
|
18
26
|
resolve: string;
|
|
19
27
|
resolving: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubjectAccessRequestPanel.d.ts","sourceRoot":"","sources":["../src/SubjectAccessRequestPanel.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"SubjectAccessRequestPanel.d.ts","sourceRoot":"","sources":["../src/SubjectAccessRequestPanel.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAC1B,IAAI,GACJ,cAAc,GACd,SAAS,GACT,WAAW,GACX,QAAQ,GACR,eAAe,GACf,cAAc,CAAA;AAClB,MAAM,MAAM,0BAA0B,GAClC,MAAM,GACN,WAAW,GACX,UAAU,GACV,YAAY,GACZ,WAAW,GACX,SAAS,GACT,OAAO,CAAA;AAEX,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAC,CAAA;AAEF,MAAM,MAAM,2BAA2B,GAAG,QAAQ,CAAC;IACjD,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,2EAA2E;IAC3E,WAAW,CAAC,EAAE,SAAS,QAAQ,CAAC;QAC9B,IAAI,EAAE,kBAAkB,CAAA;QACxB,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,OAAO,CAAA;KAClB,CAAC,EAAE,CAAA;CACL,CAAC,CAAA;AAEF,MAAM,MAAM,6BAA6B,GAAG,QAAQ,CAAC;IACnD,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,6EAA6E;IAC7E,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAA;IACzD,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC,CAAA;AAEF,MAAM,MAAM,8BAA8B,GAAG,QAAQ,CAAC;IACpD,IAAI,EAAE,6BAA6B,CAAA;IACnC,WAAW,EAAE,kBAAkB,CAAA;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,0BAA0B,CAAA;IAClC,MAAM,CAAC,EAAE,2BAA2B,CAAA;IACpC,QAAQ,EAAE,SAAS,0BAA0B,EAAE,CAAA;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mBAAmB,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACvD,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC,CAAC,CAAA;AAEF;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,IAAI,EACJ,WAAW,EACX,OAAO,EACP,MAAM,EACN,MAAM,EACN,QAAQ,EACR,KAAK,EACL,mBAAmB,EACnB,eAAe,EACf,SAAS,EACT,eAAe,EACf,SAAS,GACV,EAAE,8BAA8B,+BAgFhC"}
|
|
@@ -7,6 +7,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
* component; the authenticated BFF and GW decide identity and authorization.
|
|
8
8
|
*/
|
|
9
9
|
export function SubjectAccessRequestPanel({ copy, locatorKind, locator, status, target, sections, error, onLocatorKindChange, onLocatorChange, onResolve, onToggleSection, onRequest, }) {
|
|
10
|
+
const locatorInput = locatorInputAttributes(locatorKind);
|
|
10
11
|
function resolve(event) {
|
|
11
12
|
event.preventDefault();
|
|
12
13
|
void onResolve();
|
|
@@ -15,7 +16,18 @@ export function SubjectAccessRequestPanel({ copy, locatorKind, locator, status,
|
|
|
15
16
|
event.preventDefault();
|
|
16
17
|
void onRequest();
|
|
17
18
|
}
|
|
18
|
-
return (_jsxs("section", { className: "uhcp-access-panel", "aria-labelledby": "uhcp-access-request-title", children: [_jsx("h2", { id: "uhcp-access-request-title", children: copy.title }), _jsx("p", { children: copy.description }), _jsxs("form", { onSubmit: resolve, children: [_jsxs("label", { children: [_jsx("span", { children: copy.locatorKindLabel }), _jsx("select", { value: locatorKind, onChange: (event) => onLocatorKindChange(event.currentTarget.value), disabled: status === 'resolving', children: Object.entries(copy.locatorKinds).map(([kind, label]) => _jsx("option", { value: kind, children: label }, kind)) })] }), _jsxs("label", { children: [_jsx("span", { children: copy.locatorLabel }), _jsx("input", { value: locator, onChange: (event) => onLocatorChange(event.currentTarget.value), required: true, disabled: status === 'resolving' })] }), _jsx("button", { type: "submit", disabled: status === 'resolving' || !locator.trim(), children: status === 'resolving' ? copy.resolving : copy.resolve })] }), target && (_jsxs("form", { onSubmit: request, children: [_jsx("p", { children: _jsx("bdi", { children: target.display }) }), _jsxs("fieldset", { children: [_jsx("legend", { children: copy.sectionsLabel }), sections.map((section) => (_jsxs("label", { "data-section-code": section.code, children: [_jsx("input", { type: "checkbox", checked: section.selected, onChange: () => onToggleSection(section.code), disabled: status === 'requesting' || status === 'granted' }), _jsx("span", { children: section.label })] }, section.code)))] }), _jsx("button", { type: "submit", disabled: status === 'requesting'
|
|
19
|
+
return (_jsxs("section", { className: "uhcp-access-panel", "aria-labelledby": "uhcp-access-request-title", children: [_jsx("h2", { id: "uhcp-access-request-title", children: copy.title }), _jsx("p", { children: copy.description }), _jsxs("form", { onSubmit: resolve, children: [_jsxs("label", { children: [_jsx("span", { children: copy.locatorKindLabel }), _jsx("select", { value: locatorKind, onChange: (event) => onLocatorKindChange(event.currentTarget.value), disabled: status === 'resolving', children: Object.entries(copy.locatorKinds).map(([kind, label]) => _jsx("option", { value: kind, children: label }, kind)) })] }), _jsxs("label", { children: [_jsx("span", { children: copy.locatorLabel }), _jsx("input", { value: locator, onChange: (event) => onLocatorChange(event.currentTarget.value), type: locatorInput.type, inputMode: locatorInput.inputMode, pattern: locatorInput.pattern, required: true, disabled: status === 'resolving' })] }), _jsx("button", { type: "submit", disabled: status === 'resolving' || !locator.trim(), children: status === 'resolving' ? copy.resolving : copy.resolve })] }), target && (_jsxs("form", { onSubmit: request, children: [_jsx("p", { children: _jsx("bdi", { children: target.display }) }), _jsxs("fieldset", { children: [_jsx("legend", { children: copy.sectionsLabel }), sections.map((section) => (_jsxs("label", { "data-section-code": section.code, children: [_jsx("input", { type: "checkbox", checked: section.selected, onChange: () => onToggleSection(section.code), disabled: status === 'requesting' || status === 'granted' }), _jsx("span", { children: section.label })] }, section.code)))] }), _jsx("button", { type: "submit", disabled: status === 'requesting'
|
|
19
20
|
|| status === 'granted'
|
|
20
21
|
|| !sections.some((section) => section.selected), children: status === 'requesting' ? copy.requesting : copy.request })] })), status === 'requested' && _jsx("p", { role: "status", children: copy.requested }), status === 'granted' && _jsx("p", { role: "status", children: copy.granted }), error && _jsx("p", { role: "alert", children: error })] }));
|
|
21
22
|
}
|
|
23
|
+
function locatorInputAttributes(kind) {
|
|
24
|
+
if (kind === 'microchip')
|
|
25
|
+
return { inputMode: 'numeric', pattern: '[0-9 -]{15,21}' };
|
|
26
|
+
if (kind === 'numeric-code')
|
|
27
|
+
return { inputMode: 'numeric' };
|
|
28
|
+
if (kind === 'email-address')
|
|
29
|
+
return { type: 'email', inputMode: 'email' };
|
|
30
|
+
if (kind === 'phone-number')
|
|
31
|
+
return { type: 'tel', inputMode: 'tel' };
|
|
32
|
+
return {};
|
|
33
|
+
}
|
package/package.json
CHANGED