@xeonr/console-shell 0.1.0
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/dist/AccountMenu.d.ts +5 -0
- package/dist/AccountMenu.d.ts.map +1 -0
- package/dist/AccountMenu.js +71 -0
- package/dist/AccountMenu.js.map +1 -0
- package/dist/CommandPalette.d.ts +8 -0
- package/dist/CommandPalette.d.ts.map +1 -0
- package/dist/CommandPalette.js +160 -0
- package/dist/CommandPalette.js.map +1 -0
- package/dist/ConsoleProvider.d.ts +36 -0
- package/dist/ConsoleProvider.d.ts.map +1 -0
- package/dist/ConsoleProvider.js +110 -0
- package/dist/ConsoleProvider.js.map +1 -0
- package/dist/ConsoleShell.d.ts +20 -0
- package/dist/ConsoleShell.d.ts.map +1 -0
- package/dist/ConsoleShell.js +81 -0
- package/dist/ConsoleShell.js.map +1 -0
- package/dist/Launcher.d.ts +7 -0
- package/dist/Launcher.d.ts.map +1 -0
- package/dist/Launcher.js +119 -0
- package/dist/Launcher.js.map +1 -0
- package/dist/ScopeRail.d.ts +11 -0
- package/dist/ScopeRail.d.ts.map +1 -0
- package/dist/ScopeRail.js +74 -0
- package/dist/ScopeRail.js.map +1 -0
- package/dist/SectionSidebar.d.ts +11 -0
- package/dist/SectionSidebar.d.ts.map +1 -0
- package/dist/SectionSidebar.js +67 -0
- package/dist/SectionSidebar.js.map +1 -0
- package/dist/TeamCard.d.ts +5 -0
- package/dist/TeamCard.d.ts.map +1 -0
- package/dist/TeamCard.js +109 -0
- package/dist/TeamCard.js.map +1 -0
- package/dist/TopBar.d.ts +13 -0
- package/dist/TopBar.d.ts.map +1 -0
- package/dist/TopBar.js +50 -0
- package/dist/TopBar.js.map +1 -0
- package/dist/client.d.ts +11 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +71 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/nav.d.ts +18 -0
- package/dist/nav.d.ts.map +1 -0
- package/dist/nav.js +8 -0
- package/dist/nav.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountMenu.d.ts","sourceRoot":"","sources":["../src/AccountMenu.tsx"],"names":[],"mappings":"AA2DA,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,+BAiD/F"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import styled from "styled-components";
|
|
4
|
+
import { Icon, v } from "@xeonr/platform-ui";
|
|
5
|
+
import { useConsole } from "./ConsoleProvider.js";
|
|
6
|
+
// Account menu off the rail avatar: identity, pending invitations (invitee-side
|
|
7
|
+
// surface via auth's ListMyInvitations), account/security links into the auth
|
|
8
|
+
// portal, sign out everywhere (RP-initiated logout + back-channel fan-out).
|
|
9
|
+
const Pop = styled.div `
|
|
10
|
+
position: fixed;
|
|
11
|
+
left: 62px; bottom: 12px;
|
|
12
|
+
width: 300px;
|
|
13
|
+
z-index: ${v.zPop};
|
|
14
|
+
background: ${v.surface};
|
|
15
|
+
border: 1px solid ${v.line2};
|
|
16
|
+
border-radius: ${v.rCard};
|
|
17
|
+
box-shadow: ${v.elev};
|
|
18
|
+
padding: 6px;
|
|
19
|
+
display: flex; flex-direction: column; gap: 2px;
|
|
20
|
+
`;
|
|
21
|
+
const Who = styled.div `
|
|
22
|
+
display: flex; flex-direction: column;
|
|
23
|
+
padding: 10px 10px 8px;
|
|
24
|
+
b { font-size: 13px; font-weight: 600; }
|
|
25
|
+
span { font-size: 12px; color: ${v.faint}; }
|
|
26
|
+
`;
|
|
27
|
+
const Hair = styled.div `height: 1px; background: ${v.line}; margin: 4px 0;`;
|
|
28
|
+
const Label = styled.div `
|
|
29
|
+
font-size: 10.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
|
|
30
|
+
color: ${v.faint}; padding: 6px 10px 2px;
|
|
31
|
+
`;
|
|
32
|
+
const Item = styled.a `
|
|
33
|
+
display: flex; align-items: center; gap: 10px;
|
|
34
|
+
padding: 7px 10px;
|
|
35
|
+
border-radius: ${v.rCtl};
|
|
36
|
+
font-size: 13px;
|
|
37
|
+
color: ${v.text};
|
|
38
|
+
text-decoration: none;
|
|
39
|
+
cursor: pointer;
|
|
40
|
+
&:hover { background: ${v.hover}; }
|
|
41
|
+
small { margin-left: auto; color: ${v.faint}; font-size: 11px; }
|
|
42
|
+
.ext { margin-left: auto; color: ${v.faint}; font-size: 11px; }
|
|
43
|
+
`;
|
|
44
|
+
const Invite = styled.div `
|
|
45
|
+
display: flex; align-items: center; gap: 10px;
|
|
46
|
+
padding: 8px 10px;
|
|
47
|
+
border-radius: ${v.rCtl};
|
|
48
|
+
background: ${v.infoBg};
|
|
49
|
+
b { font-size: 12.5px; font-weight: 600; }
|
|
50
|
+
span { font-size: 11.5px; color: ${v.muted}; display: block; }
|
|
51
|
+
a { margin-left: auto; font-size: 12px; font-weight: 600; color: ${v.info}; text-decoration: none; white-space: nowrap; }
|
|
52
|
+
`;
|
|
53
|
+
export function AccountMenu({ onClose, authOrigin }) {
|
|
54
|
+
const c = useConsole();
|
|
55
|
+
const ref = useRef(null);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
const onDoc = (e) => {
|
|
58
|
+
if (ref.current && !ref.current.contains(e.target))
|
|
59
|
+
onClose();
|
|
60
|
+
};
|
|
61
|
+
const onKey = (e) => e.key === "Escape" && onClose();
|
|
62
|
+
document.addEventListener("mousedown", onDoc);
|
|
63
|
+
document.addEventListener("keydown", onKey);
|
|
64
|
+
return () => {
|
|
65
|
+
document.removeEventListener("mousedown", onDoc);
|
|
66
|
+
document.removeEventListener("keydown", onKey);
|
|
67
|
+
};
|
|
68
|
+
}, [onClose]);
|
|
69
|
+
return (_jsxs(Pop, { ref: ref, role: "menu", "aria-label": "Account", children: [_jsxs(Who, { children: [_jsx("b", { children: c.me.displayName }), _jsx("span", { children: c.me.email })] }), c.invitations.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(Hair, {}), _jsx(Label, { children: "Waiting for you" }), c.invitations.map((i) => (_jsxs(Invite, { children: [_jsx(Icon, { name: "invite", style: { color: v.info } }), _jsxs("div", { children: [_jsx("b", { children: i.team.name || i.team.slug }), _jsxs("span", { children: ["from ", i.invitedBy, " \u00B7 ", i.role] })] }), _jsx("a", { href: `${authOrigin}/teams/invitations/${encodeURIComponent(i.id)}`, children: "Review" })] }, i.id)))] })) : null, _jsx(Hair, {}), _jsxs(Item, { href: `${authOrigin}/account`, children: [_jsx(Icon, { name: "user" }), " Account ", _jsx(Icon, { className: "ext", name: "external" })] }), _jsxs(Item, { href: `${authOrigin}/account/security`, children: [_jsx(Icon, { name: "lock" }), " Security & passkeys ", _jsx(Icon, { className: "ext", name: "external" })] }), _jsxs(Item, { href: `${authOrigin}/teams`, children: [_jsx(Icon, { name: "team" }), " Teams ", _jsx(Icon, { className: "ext", name: "external" })] }), c.me.isOrgAdmin ? (_jsxs(Item, { href: `${authOrigin}/organisation`, children: [_jsx(Icon, { name: "organisation" }), " Organisation ", _jsx(Icon, { className: "ext", name: "external" })] })) : null, _jsx(Hair, {}), _jsxs(Item, { href: "/auth/logout", children: [_jsx(Icon, { name: "sign-out" }), " Sign out everywhere"] })] }));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=AccountMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccountMenu.js","sourceRoot":"","sources":["../src/AccountMenu.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NavGroup } from "./nav.ts";
|
|
2
|
+
export declare function CommandPalette({ onClose, base, groups, productLabel, }: {
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
base: string;
|
|
5
|
+
groups: NavGroup[];
|
|
6
|
+
productLabel: string;
|
|
7
|
+
}): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=CommandPalette.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPalette.d.ts","sourceRoot":"","sources":["../src/CommandPalette.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAuEzC,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,MAAM,EACN,YAAY,GACb,EAAE;IACD,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB,+BAuHA"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import styled from "styled-components";
|
|
4
|
+
import { useNavigate } from "react-router-dom";
|
|
5
|
+
import { Icon, v } from "@xeonr/platform-ui";
|
|
6
|
+
import { useConsole } from "./ConsoleProvider.js";
|
|
7
|
+
// ⌘K in two tiers. Tier 1 (always): navigation across products, teams and the
|
|
8
|
+
// current product's sections, from the registry. Tier 2 (when the client has
|
|
9
|
+
// `search`): federated results from every product the team is entitled to.
|
|
10
|
+
const Scrim = styled.div `
|
|
11
|
+
position: fixed; inset: 0;
|
|
12
|
+
z-index: ${v.zPalette};
|
|
13
|
+
background: ${v.scrim};
|
|
14
|
+
display: flex; justify-content: center; align-items: flex-start;
|
|
15
|
+
padding: 120px 16px 16px;
|
|
16
|
+
`;
|
|
17
|
+
const Dialog = styled.div `
|
|
18
|
+
width: min(640px, 100%);
|
|
19
|
+
background: ${v.surface};
|
|
20
|
+
border: 1px solid ${v.line2};
|
|
21
|
+
border-radius: ${v.rModal};
|
|
22
|
+
box-shadow: ${v.elev};
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
`;
|
|
25
|
+
const Stripe = styled.div `height: 2px; background: ${v.grad90};`;
|
|
26
|
+
const InputRow = styled.div `
|
|
27
|
+
display: flex; align-items: center; gap: 12px;
|
|
28
|
+
padding: 14px 18px;
|
|
29
|
+
border-bottom: 1px solid ${v.line};
|
|
30
|
+
color: ${v.faint};
|
|
31
|
+
input { flex: 1 1 auto; font: inherit; font-size: 15px; background: transparent; border: 0; outline: 0; color: ${v.text}; }
|
|
32
|
+
input::placeholder { color: ${v.faint}; }
|
|
33
|
+
.scope { font-size: 11.5px; border: 1px solid ${v.line2}; border-radius: 6px; padding: 2px 7px; }
|
|
34
|
+
`;
|
|
35
|
+
const List = styled.div `display: flex; flex-direction: column; padding: 8px; max-height: 420px; overflow-y: auto;`;
|
|
36
|
+
const GroupLabel = styled.div `
|
|
37
|
+
font-size: 10.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
|
|
38
|
+
color: ${v.faint}; padding: 8px 10px 4px;
|
|
39
|
+
`;
|
|
40
|
+
const Row = styled.a `
|
|
41
|
+
display: flex; align-items: center; gap: 12px;
|
|
42
|
+
padding: 10px;
|
|
43
|
+
border-radius: 10px;
|
|
44
|
+
background: ${(p) => (p.$on ? v.brand12 : "transparent")};
|
|
45
|
+
color: ${v.text};
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
.ic { color: ${(p) => p.$c ?? v.muted}; width: 18px; display: grid; place-items: center; }
|
|
49
|
+
b { flex: 1 1 auto; font-size: 13.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
50
|
+
small { font-size: 12px; color: ${v.faint}; white-space: nowrap; }
|
|
51
|
+
`;
|
|
52
|
+
const Foot = styled.div `
|
|
53
|
+
display: flex; gap: 16px;
|
|
54
|
+
padding: 10px 18px;
|
|
55
|
+
border-top: 1px solid ${v.line};
|
|
56
|
+
font-size: 11.5px; color: ${v.faint};
|
|
57
|
+
kbd { font: inherit; border: 1px solid ${v.line2}; border-radius: 4px; padding: 0 5px; }
|
|
58
|
+
span:last-child { margin-left: auto; }
|
|
59
|
+
`;
|
|
60
|
+
export function CommandPalette({ onClose, base, groups, productLabel, }) {
|
|
61
|
+
const c = useConsole();
|
|
62
|
+
const navigate = useNavigate();
|
|
63
|
+
const [q, setQ] = useState("");
|
|
64
|
+
const [remote, setRemote] = useState([]);
|
|
65
|
+
const [sel, setSel] = useState(0);
|
|
66
|
+
const inputRef = useRef(null);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
inputRef.current?.focus();
|
|
69
|
+
}, []);
|
|
70
|
+
// Tier 2: federated search, debounced; stale responses are dropped.
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!q.trim()) {
|
|
73
|
+
setRemote([]);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
let live = true;
|
|
77
|
+
const h = setTimeout(() => {
|
|
78
|
+
void c.search(q).then((r) => live && setRemote(r)).catch(() => live && setRemote([]));
|
|
79
|
+
}, 150);
|
|
80
|
+
return () => {
|
|
81
|
+
live = false;
|
|
82
|
+
clearTimeout(h);
|
|
83
|
+
};
|
|
84
|
+
}, [q, c]);
|
|
85
|
+
const entries = useMemo(() => {
|
|
86
|
+
const needle = q.trim().toLowerCase();
|
|
87
|
+
const hit = (s) => !needle || s.toLowerCase().includes(needle);
|
|
88
|
+
const out = [];
|
|
89
|
+
// current product's sections
|
|
90
|
+
for (const g of groups) {
|
|
91
|
+
for (const i of g.items) {
|
|
92
|
+
if (i.hidden || !hit(i.label))
|
|
93
|
+
continue;
|
|
94
|
+
out.push({
|
|
95
|
+
group: productLabel,
|
|
96
|
+
product: c.product,
|
|
97
|
+
kind: "navigation",
|
|
98
|
+
title: i.label,
|
|
99
|
+
subtitle: g.label,
|
|
100
|
+
href: i.href ?? (i.path ? `${base}/${i.path}` : base),
|
|
101
|
+
icon: i.icon,
|
|
102
|
+
internal: !i.href,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// other products
|
|
107
|
+
for (const p of c.products) {
|
|
108
|
+
if (p.key === c.product || p.key === "home" || p.status !== "live" || !p.enabled || !hit(p.name))
|
|
109
|
+
continue;
|
|
110
|
+
out.push({ group: "Products", product: p.key, kind: "navigation", title: `Open ${p.name}`, subtitle: new URL(p.origin).host, href: c.productHref(p), icon: p.icon, colour: p.colour });
|
|
111
|
+
}
|
|
112
|
+
// teams
|
|
113
|
+
for (const t of c.teams) {
|
|
114
|
+
if (t.id === c.activeTeam?.id || !hit(`${t.name} ${t.slug}`))
|
|
115
|
+
continue;
|
|
116
|
+
out.push({ group: "Teams", product: "teams", kind: "team", title: `Switch to ${t.name || t.slug}`, subtitle: t.role, href: `#team:${t.id}`, icon: "team" });
|
|
117
|
+
}
|
|
118
|
+
for (const r of remote) {
|
|
119
|
+
const p = c.products.find((x) => x.key === r.product);
|
|
120
|
+
out.push({ ...r, group: p?.name ?? r.product, colour: p?.colour });
|
|
121
|
+
}
|
|
122
|
+
return out;
|
|
123
|
+
}, [q, groups, c, base, productLabel, remote]);
|
|
124
|
+
useEffect(() => setSel(0), [q]);
|
|
125
|
+
const go = (e) => {
|
|
126
|
+
onClose();
|
|
127
|
+
if (e.href.startsWith("#team:")) {
|
|
128
|
+
c.setTeam(e.href.slice(6));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (e.internal)
|
|
132
|
+
navigate(e.href);
|
|
133
|
+
else
|
|
134
|
+
window.location.assign(e.href);
|
|
135
|
+
};
|
|
136
|
+
const onKey = (ev) => {
|
|
137
|
+
if (ev.key === "ArrowDown") {
|
|
138
|
+
ev.preventDefault();
|
|
139
|
+
setSel((s) => Math.min(s + 1, entries.length - 1));
|
|
140
|
+
}
|
|
141
|
+
else if (ev.key === "ArrowUp") {
|
|
142
|
+
ev.preventDefault();
|
|
143
|
+
setSel((s) => Math.max(s - 1, 0));
|
|
144
|
+
}
|
|
145
|
+
else if (ev.key === "Enter") {
|
|
146
|
+
const e = entries[sel];
|
|
147
|
+
if (e)
|
|
148
|
+
go(e);
|
|
149
|
+
}
|
|
150
|
+
else if (ev.key === "Escape")
|
|
151
|
+
onClose();
|
|
152
|
+
};
|
|
153
|
+
let lastGroup = "";
|
|
154
|
+
return (_jsx(Scrim, { onMouseDown: (e) => e.target === e.currentTarget && onClose(), children: _jsxs(Dialog, { role: "dialog", "aria-modal": "true", "aria-label": "Search and commands", onKeyDown: onKey, children: [_jsx(Stripe, {}), _jsxs(InputRow, { children: [_jsx(Icon, { name: "search" }), _jsx("input", { ref: inputRef, value: q, onChange: (e) => setQ(e.target.value), placeholder: `Search ${productLabel.toLowerCase()}, products, teams…`, "aria-label": "Search" }), c.activeTeam ? _jsx("span", { className: "scope", children: c.activeTeam.slug }) : null] }), _jsxs(List, { role: "listbox", children: [entries.map((e, i) => {
|
|
155
|
+
const label = e.group !== lastGroup ? _jsx(GroupLabel, { children: e.group }, `g-${e.group}`) : null;
|
|
156
|
+
lastGroup = e.group;
|
|
157
|
+
return (_jsxs("span", { style: { display: "contents" }, children: [label, _jsxs(Row, { role: "option", "aria-selected": i === sel, "$on": i === sel, "$c": e.colour, href: e.href, onMouseEnter: () => setSel(i), onClick: (ev) => { ev.preventDefault(); go(e); }, children: [_jsx("span", { className: "ic", children: _jsx(Icon, { name: e.icon ?? "arrow-right" }) }), _jsx("b", { children: e.title }), e.subtitle ? _jsx("small", { children: e.subtitle }) : null] })] }, `${e.group}-${e.title}-${i}`));
|
|
158
|
+
}), entries.length === 0 ? _jsx(GroupLabel, { children: "No matches" }) : null] }), _jsxs(Foot, { children: [_jsxs("span", { children: [_jsx("kbd", { children: "\u2191\u2193" }), " navigate"] }), _jsxs("span", { children: [_jsx("kbd", { children: "\u21B5" }), " open"] }), _jsx("span", { children: "Results from every product this team is entitled to" })] })] }) }));
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=CommandPalette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandPalette.js","sourceRoot":"","sources":["../src/CommandPalette.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { ConsoleClient, Invitation, Me, Product, SearchResult, Team } from "./types.ts";
|
|
3
|
+
export declare const MAX_PINNED = 6;
|
|
4
|
+
export interface ConsoleState {
|
|
5
|
+
/** registry key of the console mounting the shell; "home" for console.xeonr.io */
|
|
6
|
+
product: string;
|
|
7
|
+
me: Me;
|
|
8
|
+
teams: Team[];
|
|
9
|
+
activeTeam: Team | null;
|
|
10
|
+
products: Product[];
|
|
11
|
+
pinned: string[];
|
|
12
|
+
invitations: Invitation[];
|
|
13
|
+
loading: boolean;
|
|
14
|
+
setTeam(id: string): void;
|
|
15
|
+
togglePin(key: string): void;
|
|
16
|
+
/** absolute link into another product for the active team */
|
|
17
|
+
productHref(p: Product, path?: string): string;
|
|
18
|
+
/** federated ⌘K (tier 2); resolves to [] when the client has no search */
|
|
19
|
+
search(query: string): Promise<SearchResult[]>;
|
|
20
|
+
refresh(): void;
|
|
21
|
+
}
|
|
22
|
+
export interface ConsoleProviderProps {
|
|
23
|
+
client: ConsoleClient;
|
|
24
|
+
product: string;
|
|
25
|
+
/** team slug from the product's own URL, when it has one */
|
|
26
|
+
teamSlug?: string | undefined;
|
|
27
|
+
onTeamChange?: ((team: Team) => void) | undefined;
|
|
28
|
+
/** the console home origin, for the rail's Home tile */
|
|
29
|
+
homeOrigin?: string | undefined;
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
}
|
|
32
|
+
export declare function ConsoleProvider({ client, product, teamSlug, onTeamChange, homeOrigin, children }: ConsoleProviderProps): import("react").JSX.Element;
|
|
33
|
+
/** Null while the provider is still loading — the shell renders its skeleton then. */
|
|
34
|
+
export declare function useConsoleMaybe(): ConsoleState | null;
|
|
35
|
+
export declare function useConsole(): ConsoleState;
|
|
36
|
+
//# sourceMappingURL=ConsoleProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsoleProvider.d.ts","sourceRoot":"","sources":["../src/ConsoleProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7G,OAAO,KAAK,EAAE,aAAa,EAAkB,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAW7G,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,EAAE,CAAC;IACP,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,6DAA6D;IAC7D,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/C,0EAA0E;IAC1E,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC/C,OAAO,IAAI,IAAI,CAAC;CACjB;AAID,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAClD,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,oBAAoB,+BAoGtH;AAED,sFAAsF;AACtF,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAErD;AAED,wBAAgB,UAAU,IAAI,YAAY,CAIzC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { useTheme } from "@xeonr/platform-ui";
|
|
4
|
+
// ConsoleProvider loads everything the chrome needs — who I am, my teams, the
|
|
5
|
+
// product registry filtered to the active team, my pins, my invitations — and
|
|
6
|
+
// exposes the two mutations the shell performs: switch team, pin/unpin.
|
|
7
|
+
//
|
|
8
|
+
// Team context is resolved in this order (DESIGN.md §6, rule 3): the team
|
|
9
|
+
// slug in the URL (the product tells us via `teamSlug`), then the server-held
|
|
10
|
+
// context, then the caller's first team. The product is told about switches
|
|
11
|
+
// via `onTeamChange` and navigates itself; the shell never routes for it.
|
|
12
|
+
export const MAX_PINNED = 6;
|
|
13
|
+
const Ctx = createContext(null);
|
|
14
|
+
export function ConsoleProvider({ client, product, teamSlug, onTeamChange, homeOrigin, children }) {
|
|
15
|
+
const [me, setMe] = useState(null);
|
|
16
|
+
const [ctx, setCtx] = useState(null);
|
|
17
|
+
const [products, setProducts] = useState([]);
|
|
18
|
+
const [invitations, setInvitations] = useState([]);
|
|
19
|
+
const [tick, setTick] = useState(0);
|
|
20
|
+
const theme = useTheme();
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
let live = true;
|
|
23
|
+
void Promise.all([client.me(), client.getContext(), client.listMyInvitations()]).then(([m, c, inv]) => {
|
|
24
|
+
if (!live)
|
|
25
|
+
return;
|
|
26
|
+
setMe(m);
|
|
27
|
+
setCtx(c);
|
|
28
|
+
setInvitations(inv);
|
|
29
|
+
// The server-held theme follows you across hosts; local preference wins
|
|
30
|
+
// only if it was set explicitly on this host.
|
|
31
|
+
if (theme.pref === "system" && c.theme !== "system")
|
|
32
|
+
theme.setPref(c.theme);
|
|
33
|
+
});
|
|
34
|
+
return () => {
|
|
35
|
+
live = false;
|
|
36
|
+
};
|
|
37
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
38
|
+
}, [client, tick]);
|
|
39
|
+
const activeTeam = useMemo(() => {
|
|
40
|
+
if (!me)
|
|
41
|
+
return null;
|
|
42
|
+
if (teamSlug)
|
|
43
|
+
return me.teams.find((t) => t.slug === teamSlug) ?? null;
|
|
44
|
+
if (ctx?.activeTeam)
|
|
45
|
+
return me.teams.find((t) => t.id === ctx.activeTeam) ?? null;
|
|
46
|
+
return me.teams[0] ?? null;
|
|
47
|
+
}, [me, ctx, teamSlug]);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
let live = true;
|
|
50
|
+
void client.listProducts(activeTeam?.id ?? null).then((ps) => live && setProducts(ps));
|
|
51
|
+
return () => {
|
|
52
|
+
live = false;
|
|
53
|
+
};
|
|
54
|
+
}, [client, activeTeam?.id]);
|
|
55
|
+
const pinned = useMemo(() => {
|
|
56
|
+
const fromCtx = ctx?.pinnedProducts ?? [];
|
|
57
|
+
const known = new Set(products.map((p) => p.key));
|
|
58
|
+
const list = fromCtx.filter((k) => known.has(k));
|
|
59
|
+
return list.length > 0 ? list : products.filter((p) => p.pinnedByDefault).map((p) => p.key);
|
|
60
|
+
}, [ctx, products]);
|
|
61
|
+
const setTeam = useCallback((id) => {
|
|
62
|
+
const t = me?.teams.find((x) => x.id === id);
|
|
63
|
+
if (!t)
|
|
64
|
+
return;
|
|
65
|
+
setCtx((c) => (c ? { ...c, activeTeam: id } : c));
|
|
66
|
+
void client.setContext({ activeTeam: id });
|
|
67
|
+
onTeamChange?.(t);
|
|
68
|
+
}, [client, me, onTeamChange]);
|
|
69
|
+
const togglePin = useCallback((key) => {
|
|
70
|
+
const next = pinned.includes(key) ? pinned.filter((k) => k !== key) : [...pinned, key].slice(-MAX_PINNED);
|
|
71
|
+
setCtx((c) => (c ? { ...c, pinnedProducts: next } : c));
|
|
72
|
+
void client.setContext({ pinnedProducts: next });
|
|
73
|
+
}, [client, pinned]);
|
|
74
|
+
const productHref = useCallback((p, path = "") => {
|
|
75
|
+
const team = activeTeam?.slug;
|
|
76
|
+
const base = p.key === "home" ? (homeOrigin ?? p.origin) : p.origin;
|
|
77
|
+
return team && p.scopes.includes("team") ? `${base}/${team}${path}` : `${base}${path}`;
|
|
78
|
+
}, [activeTeam, homeOrigin]);
|
|
79
|
+
const value = useMemo(() => me
|
|
80
|
+
? {
|
|
81
|
+
product,
|
|
82
|
+
me,
|
|
83
|
+
teams: me.teams,
|
|
84
|
+
activeTeam,
|
|
85
|
+
products,
|
|
86
|
+
pinned,
|
|
87
|
+
invitations,
|
|
88
|
+
loading: false,
|
|
89
|
+
setTeam,
|
|
90
|
+
togglePin,
|
|
91
|
+
productHref,
|
|
92
|
+
search: (q) => (client.search ? client.search(q, activeTeam?.id ?? null) : Promise.resolve([])),
|
|
93
|
+
refresh: () => setTick((n) => n + 1),
|
|
94
|
+
}
|
|
95
|
+
: null, [me, product, activeTeam, products, pinned, invitations, setTeam, togglePin, productHref, client]);
|
|
96
|
+
if (!value)
|
|
97
|
+
return _jsx(Ctx.Provider, { value: null, children: children });
|
|
98
|
+
return _jsx(Ctx.Provider, { value: value, children: children });
|
|
99
|
+
}
|
|
100
|
+
/** Null while the provider is still loading — the shell renders its skeleton then. */
|
|
101
|
+
export function useConsoleMaybe() {
|
|
102
|
+
return useContext(Ctx);
|
|
103
|
+
}
|
|
104
|
+
export function useConsole() {
|
|
105
|
+
const c = useContext(Ctx);
|
|
106
|
+
if (!c)
|
|
107
|
+
throw new Error("useConsole before the console has loaded — use useConsoleMaybe or render inside ConsoleShell");
|
|
108
|
+
return c;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=ConsoleProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsoleProvider.js","sourceRoot":"","sources":["../src/ConsoleProvider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { NavGroup } from "./nav.ts";
|
|
3
|
+
import { type Crumb } from "./TopBar.tsx";
|
|
4
|
+
import type { Product } from "./types.ts";
|
|
5
|
+
export interface ConsoleShellProps {
|
|
6
|
+
productLabel: string;
|
|
7
|
+
/** the product's team root path, e.g. "/platform-core" — section links are relative to it */
|
|
8
|
+
base: string;
|
|
9
|
+
sections: NavGroup[];
|
|
10
|
+
crumbs?: Crumb[] | undefined;
|
|
11
|
+
searchPlaceholder?: string | undefined;
|
|
12
|
+
/** auth portal origin for members/teams/account deep links */
|
|
13
|
+
authOrigin?: string | undefined;
|
|
14
|
+
docsHref?: string | undefined;
|
|
15
|
+
wide?: boolean | undefined;
|
|
16
|
+
onEnableProduct?: ((p: Product) => void) | undefined;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare function ConsoleShell({ productLabel, base, sections, crumbs, searchPlaceholder, authOrigin, docsHref, wide, onEnableProduct, children, }: ConsoleShellProps): import("react").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=ConsoleShell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsoleShell.d.ts","sourceRoot":"","sources":["../src/ConsoleShell.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAU,KAAK,KAAK,EAAE,MAAM,cAAc,CAAC;AAIlD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAsD1C,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACrD,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,iBAAiB,EACjB,UAAoC,EACpC,QAAQ,EACR,IAAI,EACJ,eAAe,EACf,QAAQ,GACT,EAAE,iBAAiB,+BAmEnB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
import styled from "styled-components";
|
|
4
|
+
import { Skeleton, v } from "@xeonr/platform-ui";
|
|
5
|
+
import { useConsoleMaybe } from "./ConsoleProvider.js";
|
|
6
|
+
import { ScopeRail } from "./ScopeRail.js";
|
|
7
|
+
import { SectionSidebar } from "./SectionSidebar.js";
|
|
8
|
+
import { TopBar } from "./TopBar.js";
|
|
9
|
+
import { CommandPalette } from "./CommandPalette.js";
|
|
10
|
+
import { Launcher } from "./Launcher.js";
|
|
11
|
+
import { AccountMenu } from "./AccountMenu.js";
|
|
12
|
+
// The whole integration contract for a product console:
|
|
13
|
+
//
|
|
14
|
+
// <ConsoleProvider client={…} product="functions" teamSlug={slug} onTeamChange={…}>
|
|
15
|
+
// <ConsoleShell productLabel="Functions" base={`/${slug}`} sections={NAV} crumbs={[…]}>
|
|
16
|
+
// <Outlet />
|
|
17
|
+
// </ConsoleShell>
|
|
18
|
+
// </ConsoleProvider>
|
|
19
|
+
//
|
|
20
|
+
// Mount it once at the product's root layout so the chrome never remounts.
|
|
21
|
+
const Stripe = styled.div `
|
|
22
|
+
position: fixed; top: 0; left: 0; right: 0;
|
|
23
|
+
height: 2px;
|
|
24
|
+
z-index: calc(${v.zToast} + 1);
|
|
25
|
+
background: ${v.grad90};
|
|
26
|
+
`;
|
|
27
|
+
const Frame = styled.div `
|
|
28
|
+
display: flex;
|
|
29
|
+
height: 100%;
|
|
30
|
+
padding-top: 2px;
|
|
31
|
+
`;
|
|
32
|
+
const Main = styled.div `
|
|
33
|
+
flex: 1 1 auto;
|
|
34
|
+
min-width: 0;
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
overflow-y: auto;
|
|
38
|
+
`;
|
|
39
|
+
const Page = styled.main `
|
|
40
|
+
padding: 20px 24px 40px;
|
|
41
|
+
max-width: ${(p) => (p.$wide ? "none" : "1240px")};
|
|
42
|
+
width: 100%;
|
|
43
|
+
margin: 0 auto;
|
|
44
|
+
`;
|
|
45
|
+
const MobileScrim = styled.div `
|
|
46
|
+
position: fixed; inset: 0;
|
|
47
|
+
z-index: calc(${v.zNav} - 1);
|
|
48
|
+
background: ${v.scrim};
|
|
49
|
+
@media (min-width: 901px) { display: none; }
|
|
50
|
+
`;
|
|
51
|
+
const SkeletonFrame = styled.div `
|
|
52
|
+
display: flex; height: 100%;
|
|
53
|
+
> div:first-child { width: 56px; border-right: 1px solid ${v.line}; background: ${v.sidebar}; }
|
|
54
|
+
> div:nth-child(2) { width: 224px; border-right: 1px solid ${v.line}; background: ${v.sidebar}; padding: 12px 10px; display: flex; flex-direction: column; gap: 8px; }
|
|
55
|
+
> div:last-child { flex: 1; padding: 20px 24px; display: flex; flex-direction: column; gap: 12px; }
|
|
56
|
+
`;
|
|
57
|
+
export function ConsoleShell({ productLabel, base, sections, crumbs, searchPlaceholder, authOrigin = "https://auth.xeonr.io", docsHref, wide, onEnableProduct, children, }) {
|
|
58
|
+
const c = useConsoleMaybe();
|
|
59
|
+
const [side, setSide] = useState(false);
|
|
60
|
+
const [palette, setPalette] = useState(false);
|
|
61
|
+
const [launcher, setLauncher] = useState(false);
|
|
62
|
+
const [account, setAccount] = useState(false);
|
|
63
|
+
const closeAccount = useCallback(() => setAccount(false), []);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
const on = (e) => {
|
|
66
|
+
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
setPalette((p) => !p);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
window.addEventListener("keydown", on);
|
|
72
|
+
return () => window.removeEventListener("keydown", on);
|
|
73
|
+
}, []);
|
|
74
|
+
if (!c) {
|
|
75
|
+
return (_jsxs(_Fragment, { children: [_jsx(Stripe, {}), _jsxs(SkeletonFrame, { "aria-busy": "true", "aria-label": "Loading console", children: [_jsx("div", {}), _jsxs("div", { children: [_jsx(Skeleton, { "$h": "56px", "$r": "12px" }), Array.from({ length: 6 }).map((_, i) => _jsx(Skeleton, { "$h": "34px", "$r": "8px" }, i))] }), _jsxs("div", { children: [_jsx(Skeleton, { "$h": "28px", "$w": "260px" }), _jsx(Skeleton, { "$h": "160px", "$r": "14px" }), _jsx(Skeleton, { "$h": "320px", "$r": "14px" })] })] })] }));
|
|
76
|
+
}
|
|
77
|
+
const teamCrumb = c.activeTeam ? [{ label: c.activeTeam.name || c.activeTeam.slug }] : [];
|
|
78
|
+
const allCrumbs = [...teamCrumb, { label: productLabel, href: base }, ...(crumbs ?? [])];
|
|
79
|
+
return (_jsxs(_Fragment, { children: [_jsx(Stripe, {}), _jsxs(Frame, { children: [_jsx(ScopeRail, { onOpenLauncher: () => setLauncher(true), onOpenAccount: () => setAccount((a) => !a) }), _jsx(SectionSidebar, { open: side, base: base, groups: sections, productLabel: productLabel, authOrigin: authOrigin, docsHref: docsHref, onNavigate: () => setSide(false) }), side ? _jsx(MobileScrim, { onClick: () => setSide(false) }) : null, _jsxs(Main, { children: [_jsx(TopBar, { crumbs: allCrumbs, searchPlaceholder: searchPlaceholder ?? `Search ${productLabel.toLowerCase()}, teams, products…`, onBurger: () => setSide((s) => !s), onSearch: () => setPalette(true), notifications: c.invitations.length, onNotifications: () => setAccount(true) }), _jsx(Page, { "$wide": wide, children: children })] })] }), palette ? _jsx(CommandPalette, { onClose: () => setPalette(false), base: base, groups: sections, productLabel: productLabel }) : null, launcher ? _jsx(Launcher, { onClose: () => setLauncher(false), authOrigin: authOrigin, onEnable: onEnableProduct }) : null, account ? _jsx(AccountMenu, { onClose: closeAccount, authOrigin: authOrigin }) : null] }));
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=ConsoleShell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsoleShell.js","sourceRoot":"","sources":["../src/ConsoleShell.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Product } from "./types.ts";
|
|
2
|
+
export declare function Launcher({ onClose, authOrigin, onEnable }: {
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
authOrigin: string;
|
|
5
|
+
onEnable?: ((p: Product) => void) | undefined;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=Launcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Launcher.d.ts","sourceRoot":"","sources":["../src/Launcher.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAmB,MAAM,YAAY,CAAC;AA6G3D,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;CAAE,+BAiFrJ"}
|