uhc-portal-components-react 0.1.7 → 0.1.8
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 +7 -0
- package/README.md +3 -0
- package/dist/SoschainWorkspace.d.ts +70 -0
- package/dist/SoschainWorkspace.d.ts.map +1 -0
- package/dist/SoschainWorkspace.js +33 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/styles.css +33 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.8 - 2026-08-02
|
|
4
|
+
|
|
5
|
+
- Add the shared subject-first SOSChain card picker and workspace for Places,
|
|
6
|
+
IndividualProducts and emergency/civil-protection communications.
|
|
7
|
+
- Keep authorization host-owned: the component receives server-resolved cards
|
|
8
|
+
and capabilities and never treats a browser selection as authority.
|
|
9
|
+
|
|
3
10
|
## 0.1.7 - 2026-07-30
|
|
4
11
|
|
|
5
12
|
- Add controlled, actor-neutral invitation-acceptance and subject-access
|
package/README.md
CHANGED
|
@@ -59,6 +59,9 @@ The package deliberately exposes modules instead of a cloned application:
|
|
|
59
59
|
- `SubjectAccessRequestPanel`: controlled QR, numeric-code or `did:web`
|
|
60
60
|
resolver plus section selector. It deliberately has no scanner role: the
|
|
61
61
|
same component is reusable by an individual member or a professional.
|
|
62
|
+
- `SoschainWorkspace`: subject-card picker and four-area workspace for Places,
|
|
63
|
+
devices/vehicles and read-only emergency communications. The host supplies
|
|
64
|
+
already-authorized cards and capabilities.
|
|
62
65
|
|
|
63
66
|
Clinical label semantics stay in `gdc-common-utils-ts` / the SDK reader. Hosts
|
|
64
67
|
pass human titles to `ClinicalSectionSummary`: local `CodeableConcept.text`
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export type SoschainWorkspaceArea = 'overview' | 'places' | 'products' | 'communications';
|
|
2
|
+
export type SoschainCardSummary = Readonly<{
|
|
3
|
+
identifier: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
kindLabel: string;
|
|
6
|
+
selected?: boolean;
|
|
7
|
+
openHref: string;
|
|
8
|
+
}>;
|
|
9
|
+
export type SoschainAssociationSummary = Readonly<{
|
|
10
|
+
identifier: string;
|
|
11
|
+
name: string;
|
|
12
|
+
kindLabel: string;
|
|
13
|
+
detail: string;
|
|
14
|
+
statusLabel: string;
|
|
15
|
+
}>;
|
|
16
|
+
export type SoschainCommunicationSummary = Readonly<{
|
|
17
|
+
identifier: string;
|
|
18
|
+
sender: string;
|
|
19
|
+
categoryLabel: string;
|
|
20
|
+
subject: string;
|
|
21
|
+
body: string;
|
|
22
|
+
occurredAt: string;
|
|
23
|
+
placeLabel?: string;
|
|
24
|
+
}>;
|
|
25
|
+
export type SoschainWorkspaceCopy = Readonly<{
|
|
26
|
+
cardsTitle: string;
|
|
27
|
+
cardsDescription: string;
|
|
28
|
+
openCard: string;
|
|
29
|
+
selectedCard: string;
|
|
30
|
+
workspaceEyebrow: string;
|
|
31
|
+
noCardTitle: string;
|
|
32
|
+
noCardBody: string;
|
|
33
|
+
areas: Record<SoschainWorkspaceArea, string>;
|
|
34
|
+
overviewTitle: string;
|
|
35
|
+
overviewBody: string;
|
|
36
|
+
placesTitle: string;
|
|
37
|
+
placesBody: string;
|
|
38
|
+
productsTitle: string;
|
|
39
|
+
productsBody: string;
|
|
40
|
+
communicationsTitle: string;
|
|
41
|
+
communicationsBody: string;
|
|
42
|
+
addPlace: string;
|
|
43
|
+
addProduct: string;
|
|
44
|
+
emptyPlaces: string;
|
|
45
|
+
emptyProducts: string;
|
|
46
|
+
emptyCommunications: string;
|
|
47
|
+
readOnly: string;
|
|
48
|
+
}>;
|
|
49
|
+
export type SoschainWorkspaceProps = Readonly<{
|
|
50
|
+
copy: SoschainWorkspaceCopy;
|
|
51
|
+
cards: readonly SoschainCardSummary[];
|
|
52
|
+
selectedCard?: SoschainCardSummary;
|
|
53
|
+
activeArea: SoschainWorkspaceArea;
|
|
54
|
+
areaHrefs: Record<SoschainWorkspaceArea, string>;
|
|
55
|
+
places: readonly SoschainAssociationSummary[];
|
|
56
|
+
products: readonly SoschainAssociationSummary[];
|
|
57
|
+
communications: readonly SoschainCommunicationSummary[];
|
|
58
|
+
canManageAssociations: boolean;
|
|
59
|
+
addPlaceHref?: string;
|
|
60
|
+
addProductHref?: string;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Shared subject-first SOSChain workspace for personal and professional apps.
|
|
64
|
+
*
|
|
65
|
+
* The host supplies already-authorized cards, associations, capabilities and
|
|
66
|
+
* communications. This presentational component never derives authority from
|
|
67
|
+
* a selected role, card, tab or browser-controlled value.
|
|
68
|
+
*/
|
|
69
|
+
export declare function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, canManageAssociations, addPlaceHref, addProductHref, }: SoschainWorkspaceProps): import("react").JSX.Element;
|
|
70
|
+
//# sourceMappingURL=SoschainWorkspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SoschainWorkspace.d.ts","sourceRoot":"","sources":["../src/SoschainWorkspace.tsx"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,gBAAgB,CAAA;AAEzF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAC,CAAA;AAEF,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC,CAAA;AAEF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;IAC5C,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,IAAI,EAAE,qBAAqB,CAAA;IAC3B,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAA;IACrC,YAAY,CAAC,EAAE,mBAAmB,CAAA;IAClC,UAAU,EAAE,qBAAqB,CAAA;IACjC,SAAS,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;IAChD,MAAM,EAAE,SAAS,0BAA0B,EAAE,CAAA;IAC7C,QAAQ,EAAE,SAAS,0BAA0B,EAAE,CAAA;IAC/C,cAAc,EAAE,SAAS,4BAA4B,EAAE,CAAA;IACvD,qBAAqB,EAAE,OAAO,CAAA;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAC,CAAA;AAqBF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,KAAK,EACL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,MAAM,EACN,QAAQ,EACR,cAAc,EACd,qBAAqB,EACrB,YAAY,EACZ,cAAc,GACf,EAAE,sBAAsB,+BAmGxB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
function AssociationList({ items, empty }) {
|
|
3
|
+
if (items.length === 0)
|
|
4
|
+
return _jsx("p", { className: "uhcp-sos-empty", children: empty });
|
|
5
|
+
return (_jsx("ul", { className: "uhcp-sos-entity-list", children: items.map((item) => (_jsxs("li", { children: [_jsx("span", { className: "uhcp-sos-kind", children: item.kindLabel }), _jsx("strong", { children: item.name }), _jsx("span", { children: item.detail }), _jsx("small", { children: item.statusLabel })] }, item.identifier))) }));
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Shared subject-first SOSChain workspace for personal and professional apps.
|
|
9
|
+
*
|
|
10
|
+
* The host supplies already-authorized cards, associations, capabilities and
|
|
11
|
+
* communications. This presentational component never derives authority from
|
|
12
|
+
* a selected role, card, tab or browser-controlled value.
|
|
13
|
+
*/
|
|
14
|
+
export function SoschainWorkspace({ copy, cards, selectedCard, activeArea, areaHrefs, places, products, communications, canManageAssociations, addPlaceHref, addProductHref, }) {
|
|
15
|
+
if (!selectedCard) {
|
|
16
|
+
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 })] }), 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))) }))] }));
|
|
17
|
+
}
|
|
18
|
+
const title = activeArea === 'places'
|
|
19
|
+
? copy.placesTitle
|
|
20
|
+
: activeArea === 'products'
|
|
21
|
+
? copy.productsTitle
|
|
22
|
+
: activeArea === 'communications'
|
|
23
|
+
? copy.communicationsTitle
|
|
24
|
+
: copy.overviewTitle;
|
|
25
|
+
const body = activeArea === 'places'
|
|
26
|
+
? copy.placesBody
|
|
27
|
+
: activeArea === 'products'
|
|
28
|
+
? copy.productsBody
|
|
29
|
+
: activeArea === 'communications'
|
|
30
|
+
? copy.communicationsBody
|
|
31
|
+
: copy.overviewBody;
|
|
32
|
+
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: Object.keys(areaHrefs).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 })] }), !canManageAssociations && activeArea !== 'communications' && (_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 })] })] })), 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))) })))] })] }));
|
|
33
|
+
}
|
package/dist/index.d.ts
CHANGED
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,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,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,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,uBAAuB,CAAA;AACrC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wBAAwB,CAAA"}
|
package/dist/index.js
CHANGED
package/dist/styles.css
CHANGED
|
@@ -264,3 +264,36 @@ html[data-theme='dark'] .uhcp-brand-artwork-dark { display: block !important; }
|
|
|
264
264
|
@media (prefers-reduced-motion: reduce) {
|
|
265
265
|
.uhcp-access-card { transition: none; }
|
|
266
266
|
}
|
|
267
|
+
.uhcp-sos-wrap { margin: 0 auto; max-width: 1160px; padding: clamp(1.25rem, 4vw, 3rem); }
|
|
268
|
+
.uhcp-sos-heading > span, .uhcp-sos-kind { color: var(--uhcp-emerald); font-size: .75rem; font-weight: 900; letter-spacing: .12em; text-transform: uppercase; }
|
|
269
|
+
.uhcp-sos-heading h1 { font-size: clamp(2rem, 5vw, 3.75rem); letter-spacing: -.04em; margin: .45rem 0; }
|
|
270
|
+
.uhcp-sos-heading p, .uhcp-sos-panel header p { color: var(--uhcp-muted); line-height: 1.6; margin: 0; }
|
|
271
|
+
.uhcp-sos-card-grid, .uhcp-sos-entity-list { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); list-style: none; margin: 2rem 0 0; padding: 0; }
|
|
272
|
+
.uhcp-sos-card-grid a, .uhcp-sos-entity-list li { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: 1.5rem; color: var(--uhcp-text); display: grid; gap: .65rem; padding: 1.4rem; text-decoration: none; }
|
|
273
|
+
.uhcp-sos-card-grid a:hover { border-color: var(--uhcp-turquoise); transform: translateY(-2px); }
|
|
274
|
+
.uhcp-sos-card-grid a:focus-visible, .uhcp-sos-tabs a:focus-visible, .uhcp-sos-panel a:focus-visible { outline: 3px solid var(--uhcp-turquoise); outline-offset: 3px; }
|
|
275
|
+
.uhcp-sos-card-grid span, .uhcp-sos-card-grid small, .uhcp-sos-entity-list span, .uhcp-sos-entity-list small { color: var(--uhcp-muted); }
|
|
276
|
+
.uhcp-sos-card-grid b { color: var(--uhcp-turquoise); }
|
|
277
|
+
.uhcp-sos-tabs { display: flex; gap: .5rem; margin: 2rem 0 1rem; overflow-x: auto; padding: .25rem; }
|
|
278
|
+
.uhcp-sos-tabs a { border-radius: 999px; color: var(--uhcp-muted); font-weight: 800; padding: .75rem 1rem; text-decoration: none; white-space: nowrap; }
|
|
279
|
+
.uhcp-sos-tabs a[aria-current='page'] { background: linear-gradient(135deg, var(--uhcp-action-start), var(--uhcp-action-end)); color: #fff; }
|
|
280
|
+
.uhcp-sos-panel, .uhcp-sos-empty-panel { background: var(--uhcp-panel); border: 1px solid var(--uhcp-border); border-radius: 2rem; padding: clamp(1.25rem, 4vw, 2.25rem); }
|
|
281
|
+
.uhcp-sos-panel > header { align-items: flex-start; display: flex; gap: 1rem; justify-content: space-between; }
|
|
282
|
+
.uhcp-sos-panel h2 { margin: 0 0 .35rem; }
|
|
283
|
+
.uhcp-sos-panel > header > a { background: linear-gradient(135deg, var(--uhcp-action-start), var(--uhcp-action-end)); border-radius: 999px; color: #fff; font-weight: 800; padding: .75rem 1rem; text-decoration: none; white-space: nowrap; }
|
|
284
|
+
.uhcp-sos-readonly { background: var(--uhcp-panel-muted); border-radius: 999px; color: var(--uhcp-muted); font-size: .75rem; font-weight: 800; padding: .55rem .75rem; white-space: nowrap; }
|
|
285
|
+
.uhcp-sos-overview-grid { display: grid; gap: 1rem; grid-template-columns: repeat(3, 1fr); margin-top: 2rem; }
|
|
286
|
+
.uhcp-sos-overview-grid article { background: var(--uhcp-panel-muted); border-radius: 1.25rem; display: grid; gap: .3rem; padding: 1.25rem; }
|
|
287
|
+
.uhcp-sos-overview-grid strong { color: var(--uhcp-turquoise); font-size: 2.25rem; }
|
|
288
|
+
.uhcp-sos-overview-grid span, .uhcp-sos-empty { color: var(--uhcp-muted); }
|
|
289
|
+
.uhcp-sos-timeline { display: grid; gap: 0; list-style: none; margin: 2rem 0 0; padding: 0; }
|
|
290
|
+
.uhcp-sos-timeline li { border-left: 2px solid var(--uhcp-border); padding: 0 0 1.75rem 1.5rem; position: relative; }
|
|
291
|
+
.uhcp-sos-timeline li::before { background: var(--uhcp-turquoise); border-radius: 50%; content: ''; height: .75rem; left: -.44rem; position: absolute; top: .2rem; width: .75rem; }
|
|
292
|
+
.uhcp-sos-timeline div { display: flex; gap: 1rem; justify-content: space-between; }
|
|
293
|
+
.uhcp-sos-timeline div span { color: var(--uhcp-emerald); font-size: .75rem; font-weight: 900; text-transform: uppercase; }
|
|
294
|
+
.uhcp-sos-timeline time, .uhcp-sos-timeline small { color: var(--uhcp-muted); font-size: .8rem; }
|
|
295
|
+
.uhcp-sos-timeline p { line-height: 1.55; }
|
|
296
|
+
@media (max-width: 620px) {
|
|
297
|
+
.uhcp-sos-overview-grid { grid-template-columns: 1fr; }
|
|
298
|
+
.uhcp-sos-panel > header { display: grid; }
|
|
299
|
+
}
|
package/package.json
CHANGED