@hanzo/app 0.2.4 → 0.2.5
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/App.js +1 -1
- package/dist/Column.js +5 -2
- package/dist/Me.js +8 -5
- package/dist/Settings.js +10 -0
- package/dist/Shell.js +4 -1
- package/dist/help.js +2 -0
- package/dist/look.js +3 -3
- package/package.json +1 -1
package/dist/App.js
CHANGED
|
@@ -262,5 +262,5 @@ function Window({ bar }) {
|
|
|
262
262
|
};
|
|
263
263
|
return (_jsx(AiProvider, { client: client ?? undefined, children: _jsx(HostProvider, { host: host, children: _jsx(PrefsProvider, { children: _jsxs(YStack, { ref: windowRef, "data-slot": "window", ...(bar ? floor : null), flex: 1, minW: 0, height: "100dvh", overflow: "hidden", "$max-md": { position: 'fixed', t: TOP, l: 0, r: 0, height: HEIGHT, ...{ overflow: 'clip' } }, children: [bar ? (_jsxs(XStack, { "data-slot": "title-bar", height: BAR, shrink: 0, items: "center", gap: 2, pl: (bar.inset ?? 0) + 6, pr: "$2", ...bar.drag, children: [_jsx(XStack, { "$max-md": { display: 'none' }, children: _jsx(Toggle, { open: !closed, onPress: flip }) }), _jsx(XStack, { $md: { display: 'none' }, children: _jsx(Toggle, { open: drawer.state === 'open', onPress: drawer.open, label: t('Open sidebar') }) }), _jsx(Mark, { label: t('Back'), "data-slot": "back", onPress: () => router.back(), children: _jsx(ArrowLeft, { size: 18, "aria-hidden": true, "data-i18n-mirror": true }) }), _jsx(Mark, { label: t('Forward'), "data-slot": "forward", onPress: () => router.forward(), children: _jsx(ArrowRight, { size: 18, "aria-hidden": true, "data-i18n-mirror": true }) }), _jsx(XStack, { flex: 1, self: "stretch", ...bar.drag })] })) : null, _jsxs(XStack, { ref: drawer.pane, "data-room": "", "data-app": mode, "data-slot": "frame", ...(bar ? null : floor), ...(drawer.slide ? RAISED : null),
|
|
264
264
|
// inline-style: the slide, a transform with no logical form whose sign and distance the drawer writes on the element itself, a drag every frame (Drawer.tsx).
|
|
265
|
-
style: drawer.slide ?? undefined, flex: 1, minW: 0, minH: 0, paddingInlineEnd: "var(--pane-gap)", pb: "var(--pane-gap)", pt:
|
|
265
|
+
style: drawer.slide ?? undefined, flex: 1, minW: 0, minH: 0, paddingInlineEnd: "var(--pane-gap)", pb: "var(--pane-gap)", pt: 0, "$max-md": { p: 0 }, children: [drawer.slide ? _jsx(Lift, {}) : null, _jsx(YStack, { height: "100%", "$max-md": { display: 'none' }, children: _jsx(Rail, { host: host, mode: mode, at: where, open: !closed, toggle: bar ? undefined : flip, onChat: toChat, onDev: toDev, onStudio: toStudio, onTabs: toTabs, go: move, onOrg: org }) }), closed || mode === 'tabs' ? null : (_jsx(YStack, { "$max-md": { display: 'none' }, children: _jsx(Column, { host: host, mode: mode, thread: thread, go: move, onShut: () => setClosed(true), onSeek: seek, onBack: back, places: sidebar }) })), _jsxs(YStack, { "data-slot": "stage", flex: 1, minW: 0, minH: 0, marginInlineStart: closed || mode === 'tabs' ? 0 : 'var(--pane-gap)', "$max-md": { marginInlineStart: 0, pb: FOOT }, children: [bar ? null : _jsx(Top, { host: host, mode: mode, places: sidebar, go: move, onMenu: drawer.open, onChat: toChat, onDev: toDev }), _jsx(XStack, { "data-slot": "panes", flex: 1, minW: 0, minH: 0, children: mode === 'chat' ? (_jsx(Paned, { framed: true, children: _jsx(Chat, {}) })) : mode === 'tabs' ? (_jsx(YStack, { render: "main", "data-slot": "pane", ...pane(), overflow: "hidden", flex: 1, minW: 0, minH: 0, children: _jsx(Suspense, { fallback: null, children: _jsx(Terminals, {}) }) })) : mode === 'studio' ? (_jsx(YStack, { render: "main", "data-slot": "pane", ...pane(), overflow: "hidden", flex: 1, minW: 0, minH: 0, children: _jsx(YStack, { flex: 1, minH: 0, height: "100%", children: _jsx(Suspense, { fallback: null, children: _jsx(Studio, { host: maker, rail: false }) }) }) })) : (_jsx(YStack, { render: "main", "data-slot": "pane", ...(run ? null : { ...pane(), overflow: 'hidden' }), flex: 1, minW: 0, minH: 0, children: plans ? null : _jsx(Builder, { host: host, rail: false }) })) })] })] }), drawer.state === 'shut' ? null : (_jsx(Layer, { drawer: drawer, top: bar ? BAR : 0, children: _jsx(Column, { host: host, mode: mode, thread: thread, go: move, onShut: shut, onSeek: seek, onBack: back, drawer: true, places: sidebar, rail: _jsx(Rail, { host: host, mode: mode, at: where, open: true, rows: true, onChat: toChat, onDev: toDev, onStudio: toStudio, onTabs: toTabs, go: move, onOrg: org }), foot: _jsx(Foot, { host: host, onChat: fresh, onOrg: org }) }) })), finding ? _jsx(Palette, { go: move, onClose: found, mode: mode, host: host }) : null] }) }) }) }));
|
|
266
266
|
}
|
package/dist/Column.js
CHANGED
|
@@ -29,7 +29,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
29
29
|
import { phrase } from '@hanzo/i18n';
|
|
30
30
|
import { useI18n } from '@hanzo/i18n/react';
|
|
31
31
|
import { Text, XStack, YStack } from '@hanzo/gui';
|
|
32
|
-
import { ArrowLeft, Bell, Search, SquarePen } from 'lucide-react';
|
|
32
|
+
import { ArrowLeft, Bell, Search, Sparkles, SquarePen } from 'lucide-react';
|
|
33
33
|
import { DOTS, Gutter, library, NEW, own, tabs, useScheduled, useSessions } from '@hanzo/build';
|
|
34
34
|
import { tidy } from './lib/title.js';
|
|
35
35
|
import { DropdownMenu } from '@hanzo/ui';
|
|
@@ -42,7 +42,9 @@ import { Setup } from './Setup.js';
|
|
|
42
42
|
import { ago, UNTITLED_RUN } from './recent.js';
|
|
43
43
|
import { empty } from './open.js';
|
|
44
44
|
import { useSpan } from './span.js';
|
|
45
|
+
import { useFree } from './Upgrade.js';
|
|
45
46
|
import { talk } from './lib/host.js';
|
|
47
|
+
import { payUrl } from './lib/pay.js';
|
|
46
48
|
import { brand, wordmark } from './where.js';
|
|
47
49
|
/** The sidebar fills the column. Its `width` is typed in px alone, though its frame takes any gui size — the type is
|
|
48
50
|
* @hanzo/ui's to widen. */
|
|
@@ -91,6 +93,7 @@ function Activity({ host }) {
|
|
|
91
93
|
}
|
|
92
94
|
export function Column({ host, mode, thread, go, onShut, onSeek, onBack, drawer = false, rail, foot, places, }) {
|
|
93
95
|
const { t, dir } = useI18n();
|
|
96
|
+
const free = useFree(Boolean(host.token?.()));
|
|
94
97
|
// The desktop sidebar and a phone's drawer can both be in the page: each names its own group labels.
|
|
95
98
|
const uid = useId();
|
|
96
99
|
const span = useSpan(SPAN, WIDTH, FLOOR, CEIL);
|
|
@@ -114,5 +117,5 @@ export function Column({ host, mode, thread, go, onShut, onSeek, onBack, drawer
|
|
|
114
117
|
};
|
|
115
118
|
return (_jsxs(YStack, { "data-slot": "app-column", ref: drawer ? undefined : span.ref,
|
|
116
119
|
// inline-style: `--span`, the width a drag rewrites on the element itself (span.ts); no prop sets a variable.
|
|
117
|
-
style: drawer ? undefined : span.style, position: "relative", flex: drawer ? 1 : undefined, shrink: drawer ? 1 : 0, minW: 0, height: "100%", width: drawer ? undefined : 'var(--span)', children: [_jsxs(Sidebar, { "data-slot": "app-rail", role: "navigation", "aria-label": brand(), bg: "transparent", borderWidth: 0, ...FILL, px: "$2", pt: drawer ? '$2' : 0, pb: "$2", gap: "$0", children: [at ? (_jsxs(XStack, { "data-slot": "app-head", items: "center", gap: "$1", paddingInlineStart: 2, paddingInlineEnd: 2, height: 52, shrink: 0, minW: 0, children: [_jsx(SidebarIconButton, { label: t('Back'), "data-slot": "place-back", onPress: onBack, ...HEAD, children: _jsx(ArrowLeft, { size: 16, "aria-hidden": true, "data-i18n-mirror": true }) }), _jsx(Text, { flex: 1, minW: 0, fontSize: 18, lineHeight: 24, fontWeight: "600", color: "$ink", numberOfLines: 1, "data-slot": "place-name", children: t(TITLE[at]) })] })) : (_jsxs(XStack, { "data-slot": "app-head", items: "center", gap: "$1", paddingInlineStart: "$2", paddingInlineEnd: 2, height: 52, shrink: 0, minW: 0, children: [_jsx(Text, { flex: 1, minW: 0, fontSize: 18, lineHeight: 24, fontWeight: "600", color: "$ink", numberOfLines: 1, children: wordmark(mode) }), _jsx(Activity, { host: host }), _jsx(SidebarIconButton, { label: t('Search'), onPress: onSeek, "aria-haspopup": "dialog", ...HEAD, children: _jsx(Search, { size: 16, "aria-hidden": true }) })] })), mode === 'chat' ? (_jsx(YStack, { role: "list", gap: 2, shrink: 0, children: _jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { "data-slot": "app-new", ...ROW, active: !thread, bg: "transparent", hoverStyle: { bg: '$hover' }, icon: _jsx(SquarePen, { size: 16, "aria-hidden": true }), onPress: create, ...keys(create), children: _jsx(Text, { fontSize: "$3", color: "$ink", children: t('New chat') }) }) }) })) : (_jsx(YStack, { "data-slot": "app-places", shrink: 0, children: groups.map((g, i) => (_jsxs(YStack, { pt: i ? '$2' : 0, children: [i && g.label ? (_jsx(Text, { id: `${uid}-${g.id}`, paddingInlineStart: "$2", pb: 2, fontSize: "$3", color: "$soft", children: g.label })) : null, _jsx(YStack, { role: "list", "aria-labelledby": i && g.label ? `${uid}-${g.id}` : undefined, "aria-label": i && g.label ? undefined : g.label || (at ? t(TITLE[at]) : g.id), gap: 1, children: g.links.map((link) => (_jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { ...ROW, ...(link.id === NEW ? { 'data-slot': 'app-new' } : {}), active: link.active, icon: link.id === NEW ? _jsx(SquarePen, { size: 16, "aria-hidden": true }) : link.icon, onPress: link.onPress, ...keys(() => link.onPress?.()), children: _jsx(Text, { fontSize: "$3", color: link.active ? '$ink' : '$quiet', children: link.label }) }) }, link.id))) })] }, g.id))) })), rail, mode === 'studio' || mode === 'tabs' || at ? null : _jsx(Recents, { host: host, mode: mode, thread: thread, onOpen: open, onNew: create }), at ? null : (_jsxs(YStack, { gap: "$2", pt: "$2", shrink: 0, children: [_jsx(Made, {}), _jsx(Setup, {})] })), foot] }), drawer ? null : (_jsx(Gutter, { side: dir === 'rtl' ? 'right' : 'left', span: span.span, floor: FLOOR, ceil: CEIL, reset: WIDTH, onSpan: span.move, onKeep: span.keep, onShut: onShut, label: t('Resize sidebar') }))] }));
|
|
120
|
+
style: drawer ? undefined : span.style, position: "relative", flex: drawer ? 1 : undefined, shrink: drawer ? 1 : 0, minW: 0, height: "100%", width: drawer ? undefined : 'var(--span)', children: [_jsxs(Sidebar, { "data-slot": "app-rail", role: "navigation", "aria-label": brand(), bg: "transparent", borderWidth: 0, ...FILL, px: "$2", pt: drawer ? '$2' : 0, pb: "$2", gap: "$0", children: [at ? (_jsxs(XStack, { "data-slot": "app-head", items: "center", gap: "$1", paddingInlineStart: 2, paddingInlineEnd: 2, height: 52, shrink: 0, minW: 0, children: [_jsx(SidebarIconButton, { label: t('Back'), "data-slot": "place-back", onPress: onBack, ...HEAD, children: _jsx(ArrowLeft, { size: 16, "aria-hidden": true, "data-i18n-mirror": true }) }), _jsx(Text, { flex: 1, minW: 0, fontSize: 18, lineHeight: 24, fontWeight: "600", color: "$ink", numberOfLines: 1, "data-slot": "place-name", children: t(TITLE[at]) })] })) : (_jsxs(XStack, { "data-slot": "app-head", items: "center", gap: "$1", paddingInlineStart: "$2", paddingInlineEnd: 2, height: 52, shrink: 0, minW: 0, children: [_jsx(Text, { flex: 1, minW: 0, fontSize: 18, lineHeight: 24, fontWeight: "600", color: "$ink", numberOfLines: 1, children: wordmark(mode) }), _jsx(Activity, { host: host }), _jsx(SidebarIconButton, { label: t('Search'), onPress: onSeek, "aria-haspopup": "dialog", ...HEAD, children: _jsx(Search, { size: 16, "aria-hidden": true }) })] })), mode === 'chat' ? (_jsx(YStack, { role: "list", gap: 2, shrink: 0, children: _jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { "data-slot": "app-new", ...ROW, active: !thread, bg: "transparent", hoverStyle: { bg: '$hover' }, icon: _jsx(SquarePen, { size: 16, "aria-hidden": true }), onPress: create, ...keys(create), children: _jsx(Text, { fontSize: "$3", color: "$ink", children: t('New chat') }) }) }) })) : (_jsx(YStack, { "data-slot": "app-places", shrink: 0, children: groups.map((g, i) => (_jsxs(YStack, { pt: i ? '$2' : 0, children: [i && g.label ? (_jsx(Text, { id: `${uid}-${g.id}`, paddingInlineStart: "$2", pb: 2, fontSize: "$3", color: "$soft", children: g.label })) : null, _jsx(YStack, { role: "list", "aria-labelledby": i && g.label ? `${uid}-${g.id}` : undefined, "aria-label": i && g.label ? undefined : g.label || (at ? t(TITLE[at]) : g.id), gap: 1, children: g.links.map((link) => (_jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { ...ROW, ...(link.id === NEW ? { 'data-slot': 'app-new' } : {}), active: link.active, icon: link.id === NEW ? _jsx(SquarePen, { size: 16, "aria-hidden": true }) : link.icon, onPress: link.onPress, ...keys(() => link.onPress?.()), children: _jsx(Text, { fontSize: "$3", color: link.active ? '$ink' : '$quiet', children: link.label }) }) }, link.id))) })] }, g.id))) })), rail, mode === 'studio' || mode === 'tabs' || at ? null : _jsx(Recents, { host: host, mode: mode, thread: thread, onOpen: open, onNew: create }), at ? null : (_jsxs(YStack, { gap: "$2", pt: "$2", shrink: 0, children: [_jsx(Made, {}), _jsx(Setup, {})] })), free ? (_jsx(YStack, { role: "list", gap: 2, shrink: 0, pt: "$2", children: _jsx(YStack, { role: "listitem", children: _jsx(SidebarItem, { ...ROW, "data-slot": "column-upgrade", icon: _jsx(Sparkles, { size: 16, "aria-hidden": true, color: "var(--primary)" }), onPress: () => window.location.assign(payUrl('/cart', { plan: 'pro', returnUrl: window.location.href })), ...keys(() => window.location.assign(payUrl('/cart', { plan: 'pro', returnUrl: window.location.href }))), children: _jsx(Text, { fontSize: "$3", color: "$ink", children: t('Upgrade to Pro') }) }) }) })) : null, foot] }), drawer ? null : (_jsx(Gutter, { side: dir === 'rtl' ? 'right' : 'left', span: span.span, floor: FLOOR, ceil: CEIL, reset: WIDTH, onSpan: span.move, onKeep: span.keep, onShut: onShut, label: t('Resize sidebar') }))] }));
|
|
118
121
|
}
|
package/dist/Me.js
CHANGED
|
@@ -36,7 +36,7 @@ import { phrase } from '@hanzo/i18n';
|
|
|
36
36
|
import { useI18n } from '@hanzo/i18n/react';
|
|
37
37
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
38
38
|
import { SizableText, XStack, YStack } from '@hanzo/gui';
|
|
39
|
-
import { ArrowUpRight, Building2, Check, ChevronsUpDown, CircleHelp, CircleUserRound, Download, FileText, FlaskConical, Info, Keyboard, LifeBuoy, LogOut, Palette, Plus, ScrollText, Settings, ShieldCheck, Sparkles, Users, X, } from 'lucide-react';
|
|
39
|
+
import { ArrowUpRight, BookOpen, Building2, Check, ChevronsUpDown, CircleHelp, CircleUserRound, Download, FileText, FlaskConical, Info, Keyboard, LifeBuoy, LogOut, MessagesSquare, Palette, Plus, ScrollText, Settings, ShieldCheck, Sparkles, Users, X, } from 'lucide-react';
|
|
40
40
|
import { label, Meter, said as spoken, useStanding } from '@hanzo/build';
|
|
41
41
|
import { useOrganizations } from '@hanzo/iam/react';
|
|
42
42
|
import { Button, Dialog, DialogContent, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Input, Kbd, } from '@hanzo/ui';
|
|
@@ -56,6 +56,8 @@ const MADE = 'hanzo:org:made';
|
|
|
56
56
|
/** Each Help page's icon, by its key in help.ts. */
|
|
57
57
|
const ICONS = {
|
|
58
58
|
help: _jsx(CircleHelp, { size: 16, "aria-hidden": true }),
|
|
59
|
+
docs: _jsx(BookOpen, { size: 16, "aria-hidden": true }),
|
|
60
|
+
contact: _jsx(MessagesSquare, { size: 16, "aria-hidden": true }),
|
|
59
61
|
center: _jsx(ShieldCheck, { size: 16, "aria-hidden": true }),
|
|
60
62
|
releases: _jsx(ScrollText, { size: 16, "aria-hidden": true }),
|
|
61
63
|
download: _jsx(Download, { size: 16, "aria-hidden": true }),
|
|
@@ -166,12 +168,13 @@ export function Me({ host, narrow = false, above = false, onOrg, }) {
|
|
|
166
168
|
const plan = spoken(read.value?.label ?? null);
|
|
167
169
|
const teamPlan = team ? (team.name === current ? plan : teamOther) : '';
|
|
168
170
|
const ownPlan = personal ? (personal.name === current ? plan : other) : '';
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
+
const isFree = !read.value?.label?.name || read.value?.label?.name?.toLowerCase() === 'free';
|
|
172
|
+
const planName = plan || (isFree ? t('Free') : '');
|
|
173
|
+
// Where the reader works, and on what: "hanzo - Enterprise", "Personal - Pro", "Personal - Free".
|
|
174
|
+
const working = [here ? (here.personal ? t('Personal') : here.display) : current, planName].filter(Boolean).join(' - ');
|
|
171
175
|
// A personal plan is bought for the personal organization, beside any business one.
|
|
172
176
|
// The plans row's name (a phrase of `upgrade`'s).
|
|
173
177
|
const plans = upgrade(read.value?.label?.name);
|
|
174
|
-
const isFree = !read.value?.label?.name || read.value?.label?.name?.toLowerCase() === 'free';
|
|
175
178
|
const getPro = () => (personal ? window.location.assign(payUrl('/cart', { plan: 'pro', org: personal.name, returnUrl: window.location.href })) : window.location.assign(payUrl('/cart', { plan: 'pro', returnUrl: window.location.href })));
|
|
176
179
|
const apple = mac();
|
|
177
180
|
useEffect(() => {
|
|
@@ -215,7 +218,7 @@ export function Me({ host, narrow = false, above = false, onOrg, }) {
|
|
|
215
218
|
$touchable: narrow ? { width: 44, minH: 44 } : undefined, px: narrow ? 0 : '$2', gap: "$2.5", rounded: narrow ? 999 : '$5', items: "center", justify: narrow ? 'center' : 'flex-start', hoverStyle: { bg: '$hover' }, focusVisibleStyle: { outlineWidth: 2, outlineStyle: 'solid', outlineColor: '$outlineColor' }, cursor: "pointer", children: [_jsx(Face, { host: host, size: narrow ? 26 : 32 }), narrow ? null : (_jsxs(_Fragment, { children: [_jsxs(YStack, { flex: 1, minW: 0, children: [_jsx(SizableText, { size: "$3", fontWeight: "600", color: "$ink", numberOfLines: 1, text: "start", children: who }), working ? (_jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: 1, text: "start", children: working })) : null] }), isFree ? (_jsx(Button, { size: "xs", variant: "outline", "data-slot": "me-upgrade", px: "$2", py: "$0.5", rounded: "$3", onPress: (e) => {
|
|
216
219
|
e?.stopPropagation?.();
|
|
217
220
|
getPro();
|
|
218
|
-
}, cursor: "pointer", children: t('Upgrade') })) : null, _jsx(ChevronsUpDown, { size: 14, "aria-hidden": true, opacity: 0.6 })] }))] }) }), _jsxs(DropdownMenuContent, { minW: 260, maxW: "calc(100vw - 16px)", "aria-labelledby": undefined, "aria-label": t('Account'), onCloseAutoFocus: back, children: [_jsxs(DropdownMenuSub, { open: account, onOpenChange: setAccount, children: [_jsxs(DropdownMenuSubTrigger, { minH: 48, gap: "$2.5", children: [_jsx(Face, { host: host, size: 28 }), _jsxs(YStack, { flex: 1, minW: 0, children: [_jsx(SizableText, { size: "$2", fontWeight: "600", color: "$ink", numberOfLines: 1, children: who }), _jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: 1, children: host.person.email || working })] })] }), account ? (_jsxs(DropdownMenuSubContent, { minW: 260, maxW: "calc(100vw - 16px)", pointerEvents: "auto", children: [_jsx(Meter, { read: read, onPlans: () => leave('here'), onBilling: () => (setOpen(false), showSettings('billing')) }), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuLabel, { children: t('Organizations') }), all.map((o) => (_jsx(DropdownMenuItem, { onSelect: () => o.name !== current && onOrg(o.name), children: _jsx(Line, { icon: _jsx(Mark, { org: o }), sub: [o.personal ? t('Personal') : said(o.role, t), planFor(o)].filter(Boolean).join('
|
|
221
|
+
}, cursor: "pointer", children: t('Upgrade') })) : null, _jsx(ChevronsUpDown, { size: 14, "aria-hidden": true, opacity: 0.6 })] }))] }) }), _jsxs(DropdownMenuContent, { minW: 260, maxW: "calc(100vw - 16px)", "aria-labelledby": undefined, "aria-label": t('Account'), onCloseAutoFocus: back, children: [_jsxs(DropdownMenuSub, { open: account, onOpenChange: setAccount, children: [_jsxs(DropdownMenuSubTrigger, { minH: 48, gap: "$2.5", children: [_jsx(Face, { host: host, size: 28 }), _jsxs(YStack, { flex: 1, minW: 0, children: [_jsx(SizableText, { size: "$2", fontWeight: "600", color: "$ink", numberOfLines: 1, children: who }), _jsx(SizableText, { size: "$1", color: "$soft", numberOfLines: 1, children: host.person.email || working })] })] }), account ? (_jsxs(DropdownMenuSubContent, { minW: 260, maxW: "calc(100vw - 16px)", pointerEvents: "auto", children: [_jsx(Meter, { read: read, onPlans: () => leave('here'), onBilling: () => (setOpen(false), showSettings('billing')) }), _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuLabel, { children: t('Organizations') }), all.map((o) => (_jsx(DropdownMenuItem, { onSelect: () => o.name !== current && onOrg(o.name), children: _jsx(Line, { icon: _jsx(Mark, { org: o }), sub: [o.personal ? t('Personal') : said(o.role, t), planFor(o) || (isFree && o.personal ? t('Free') : '')].filter(Boolean).join(' - '), trail: o.name === current ? _jsx(Check, { size: 16, "aria-label": t('Current') }) : null, children: o.display }) }, o.name))), _jsx(DropdownMenuItem, { onSelect: () => setCreating(true), children: _jsx(Line, { icon: _jsx(Plus, { size: 16, "aria-hidden": true }), children: t('Create organization') }) }), _jsx(DropdownMenuItem, { onSelect: () => out(site(settings('organization'))), children: _jsx(Line, { icon: _jsx(Settings, { size: 16, "aria-hidden": true }), children: t('Organization settings') }) }), where().team ? null : here && !here.personal ? (_jsx(DropdownMenuItem, { onSelect: () => out(`${ENTRY}&org=${encodeURIComponent(here.name)}`), children: _jsx(Line, { icon: _jsx(Users, { size: 16, "aria-hidden": true }), trail: _jsx(ArrowUpRight, { size: 14, "aria-hidden": true, opacity: 0.6 }), children: t('Open in Hanzo Team') }) })) : (_jsx(DropdownMenuItem, { onSelect: () => setCreating(true), children: _jsx(Line, { icon: _jsx(Users, { size: 16, "aria-hidden": true }), children: t('Create a team') }) })), superAdmin() ? (_jsx(DropdownMenuItem, { onSelect: choose, children: _jsx(Line, { icon: _jsx(Building2, { size: 16, "aria-hidden": true }), children: t('All organizations') }) })) : null] })) : null] }), team ? (_jsx(DropdownMenuItem, { "data-slot": "me-team", onSelect: () => team.name !== current && onOrg(team.name), children: _jsx(Line, { icon: _jsx(Mark, { org: team }), trail: team.name === current ? _jsx(Check, { size: 16, "aria-label": t('Current') }) : null, children: t('{org} · {plan}', { org: team.display, plan: teamPlan || t('No plan') }) }) })) : null, personal ? (_jsx(DropdownMenuItem, { "data-slot": "me-personal", onSelect: () => personal.name !== current && onOrg(personal.name), actionsVisibility: "always", actions: ownPlan ? undefined : (_jsx(Button, { size: "xs", variant: "outline", onPress: getPro, children: t('Get Pro') })), children: _jsx(Line, { icon: _jsx(CircleUserRound, { size: 16, "aria-hidden": true }), trail: personal.name === current ? _jsx(Check, { size: 16, "aria-label": t('Current') }) : null, children: t('Personal · {plan}', { plan: ownPlan || t('No plan') }) }) })) : null, _jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuItem, { onSelect: () => leave('here'), children: _jsx(Line, { icon: _jsx(Sparkles, { size: 16, "aria-hidden": true }), children: t(plans) }) }), _jsx(DropdownMenuItem, { onSelect: () => showSettings('general'), children: _jsx(Line, { icon: _jsx(Palette, { size: 16, "aria-hidden": true }), children: t('Personalization') }) }), _jsx(DropdownMenuItem, { onSelect: () => showSettings('account'), children: _jsx(Line, { icon: _jsx(CircleUserRound, { size: 16, "aria-hidden": true }), children: t('Profile') }) }), _jsx(DropdownMenuItem, { "aria-keyshortcuts": "Control+, Meta+,", onSelect: () => showSettings('general'), children: _jsx(Line, { icon: _jsx(Settings, { size: 16, "aria-hidden": true }), trail: _jsx(DropdownMenuShortcut, { "aria-hidden": true, children: _jsx("bdi", { dir: "ltr", children: apple ? '⌘,' : 'Ctrl+,' }) }), children: t('Settings') }) }), _jsx(DropdownMenuItem, { onSelect: () => window.location.assign(site('/beta/status')), children: _jsx(Line, { icon: _jsx(FlaskConical, { size: 16, "aria-hidden": true }), children: t('Beta') }) }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuSub, { open: help, onOpenChange: setHelp, children: [_jsx(DropdownMenuSubTrigger, { children: _jsx(Line, { icon: _jsx(LifeBuoy, { size: 16, "aria-hidden": true }), children: t('Help') }) }), help ? (_jsxs(DropdownMenuSubContent, { minW: 240, maxW: "calc(100vw - 16px)", pointerEvents: "auto", children: [pages().map((p) => (_jsx(DropdownMenuItem, { onSelect: () => out(p.href), children: _jsx(Line, { icon: ICONS[p.key], trail: p.key === 'help' ? _jsx(ArrowUpRight, { size: 14, "aria-hidden": true, opacity: 0.6 }) : null, children: t(p.label) }) }, p.key))), _jsx(DropdownMenuItem, { "aria-keyshortcuts": "Control+/ Meta+/", onSelect: () => setKeys(true), children: _jsx(Line, { icon: _jsx(Keyboard, { size: 16, "aria-hidden": true }), trail: _jsx(DropdownMenuShortcut, { "aria-hidden": true, children: _jsx("bdi", { dir: "ltr", children: apple ? '⌘/' : 'Ctrl+/' }) }), children: t('Keyboard shortcuts') }) }), _jsx(DropdownMenuSeparator, {}), legal().map((p) => (_jsx(DropdownMenuItem, { onSelect: () => out(p.href), children: _jsx(Line, { icon: ICONS[p.key], children: t(p.label) }) }, p.key)))] })) : null] }), host.signOut ? (_jsx(DropdownMenuItem, { onSelect: () => host.signOut?.(), children: _jsx(Line, { icon: _jsx(LogOut, { size: 16, "aria-hidden": true, "data-i18n-mirror": true }), children: t('Log out') }) })) : null] })] }), _jsx(Create, { open: creating, onOpenChange: setCreating }), _jsx(Shortcuts, { open: keys, onOpenChange: setKeys, apple: apple })] }));
|
|
219
222
|
}
|
|
220
223
|
/** The app's keys (help.ts `KEYS`), one row each, spelled for this platform. */
|
|
221
224
|
function Shortcuts({ open, onOpenChange, apple }) {
|
package/dist/Settings.js
CHANGED
|
@@ -92,6 +92,16 @@ const GROUPS = [
|
|
|
92
92
|
{ id: 'keys', label: phrase('API keys'), href: 'https://platform.hanzo.ai/api-keys' },
|
|
93
93
|
],
|
|
94
94
|
},
|
|
95
|
+
{
|
|
96
|
+
label: phrase('Help & Support'),
|
|
97
|
+
rows: [
|
|
98
|
+
{ id: 'docs', label: phrase('Documentation'), href: 'https://docs.hanzo.ai' },
|
|
99
|
+
{ id: 'support', label: phrase('Help center'), href: site('/support') },
|
|
100
|
+
{ id: 'contact', label: phrase('Contact us'), href: site('/contact') },
|
|
101
|
+
{ id: 'status', label: phrase('Status'), href: 'https://status.hanzo.ai' },
|
|
102
|
+
{ id: 'releases', label: phrase('Release notes'), href: 'https://github.com/hanzoai/cli/releases' },
|
|
103
|
+
],
|
|
104
|
+
},
|
|
95
105
|
];
|
|
96
106
|
/** Every row, flat — what the pane looks a chosen id up in. */
|
|
97
107
|
export const ROWS = GROUPS.flatMap((g) => g.rows);
|
package/dist/Shell.js
CHANGED
|
@@ -1257,7 +1257,10 @@ function Frame({ mode, children, navigate, back, forward, }) {
|
|
|
1257
1257
|
// FILTER, not Search. Two controls that both said Search did two
|
|
1258
1258
|
// different things: this one narrows the list beside you, and the
|
|
1259
1259
|
// bar above opens the palette that finds anything anywhere.
|
|
1260
|
-
placeholder: t("Filter"), "aria-label": t("Filter sidebar") }), flex: 1, minW: 0, bg: "transparent", borderWidth: 0, outlineStyle: "none", color: "inherit", fontSize: "$2" })] }) }), settingsPane ? (_jsx(SidebarScroll, { children: _jsx(SettingsList, { active: settingsPane, filter: filter, onPick: pick, onBack: () => showSettings(null) }) })) : (_jsx(_Fragment, { children: _jsx(SidebarScroll, { children: _jsxs(_Fragment, { children: [settled ? (_jsx(Index, { mode: mode, owner: owner, filter: filter, onPick: onPick, navigate: navigate })) : null, products.length ? (_jsx(SidebarFolder, { name: t("Cloud & Platform"), open: filter ? true : undefined, children: products.map((prod) => (_jsx(SidebarItem, { icon: _jsx(prod.icon, { size: 13, "aria-hidden": true }), onPress: () => window.open(prod.href, "_blank", "noopener"), children: t(prod.label) }, prod.id))) })) : null] }) }) })), settled && onApex ? _jsx(Leave, { href: signedIn ? ENTRY : WORKSPACE, children: t("Workspace") }) : null, settled ? (signedIn ? (_jsxs(_Fragment, { children: [_jsx(SidebarItem, { icon: _jsx(
|
|
1260
|
+
placeholder: t("Filter"), "aria-label": t("Filter sidebar") }), flex: 1, minW: 0, bg: "transparent", borderWidth: 0, outlineStyle: "none", color: "inherit", fontSize: "$2" })] }) }), settingsPane ? (_jsx(SidebarScroll, { children: _jsx(SettingsList, { active: settingsPane, filter: filter, onPick: pick, onBack: () => showSettings(null) }) })) : (_jsx(_Fragment, { children: _jsx(SidebarScroll, { children: _jsxs(_Fragment, { children: [settled ? (_jsx(Index, { mode: mode, owner: owner, filter: filter, onPick: onPick, navigate: navigate })) : null, products.length ? (_jsx(SidebarFolder, { name: t("Cloud & Platform"), open: filter ? true : undefined, children: products.map((prod) => (_jsx(SidebarItem, { icon: _jsx(prod.icon, { size: 13, "aria-hidden": true }), onPress: () => window.open(prod.href, "_blank", "noopener"), children: t(prod.label) }, prod.id))) })) : null] }) }) })), settled && onApex ? _jsx(Leave, { href: signedIn ? ENTRY : WORKSPACE, children: t("Workspace") }) : null, settled ? (signedIn ? (_jsxs(_Fragment, { children: [free ? (_jsx(SidebarItem, { icon: _jsx(Sparkles, { size: 15, "aria-hidden": true, color: "var(--primary)" }), onPress: () => {
|
|
1261
|
+
window.location.assign(payUrl("/cart", { plan: "pro", returnUrl: window.location.href }));
|
|
1262
|
+
dismiss();
|
|
1263
|
+
}, children: t("Upgrade to Pro") })) : null, _jsx(SidebarItem, { icon: _jsx(UserPlus, { size: 15, "aria-hidden": true }), onPress: () => window.open(invite(), "_blank", "noopener"), children: t("Invite Teammates") }), _jsx(SidebarItem, { icon: _jsx(Share2, { size: 15, "aria-hidden": true }), onPress: () => {
|
|
1261
1264
|
navigate?.(site("/referral"));
|
|
1262
1265
|
dismiss();
|
|
1263
1266
|
}, children: t("Share Hanzo") }), _jsxs(XStack, { items: "center", gap: "$1", px: "$1.5", py: "$1", borderTopWidth: 1, borderColor: "$borderColor", children: [_jsx(YStack, { flex: 1, minW: 0, children: _jsx(Me, { host: who, onOrg: (o) => (choose(o), window.location.reload()) }) }), _jsx(Box, { render: "button", onClick: toggle, "aria-label": t("Collapse sidebar"), p: "$2", rounded: "$2", hoverStyle: { bg: "$hover" }, cursor: "pointer", children: _jsx(PanelLeftClose, { size: 16, "aria-hidden": true, "data-i18n-mirror": "" }) })] })] })) : null) : null] }));
|
package/dist/help.js
CHANGED
|
@@ -13,6 +13,8 @@ const RELEASES = 'https://github.com/hanzoai/cli/releases';
|
|
|
13
13
|
*/
|
|
14
14
|
export const pages = () => [
|
|
15
15
|
{ key: 'help', label: phrase('Help center'), href: site('/support') },
|
|
16
|
+
{ key: 'docs', label: phrase('Documentation'), href: 'https://docs.hanzo.ai' },
|
|
17
|
+
{ key: 'contact', label: phrase('Contact us'), href: site('/contact') },
|
|
16
18
|
{ key: 'center', label: phrase('Privacy center'), href: site('/legal') },
|
|
17
19
|
{ key: 'releases', label: phrase('Release notes'), href: RELEASES },
|
|
18
20
|
{ key: 'download', label: phrase('Download apps'), href: site('/download') },
|
package/dist/look.js
CHANGED
|
@@ -9,8 +9,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
9
9
|
* row of its own here, written to next-themes and to IAM's per-subject key —
|
|
10
10
|
* two more places a theme lived, neither of which crossed an origin.
|
|
11
11
|
*/
|
|
12
|
-
import { useI18n } from "@hanzo/i18n/react";
|
|
13
|
-
import { Text, YStack } from "@hanzo/ui";
|
|
12
|
+
import { LanguagePicker, useI18n } from "@hanzo/i18n/react";
|
|
13
|
+
import { Text, XStack, YStack } from "@hanzo/ui";
|
|
14
14
|
import { Appearance } from "@hanzo/appearance";
|
|
15
15
|
import { useIam } from "@hanzo/iam/react";
|
|
16
16
|
import { api } from "./lib/api.js";
|
|
@@ -20,5 +20,5 @@ export function Look() {
|
|
|
20
20
|
const { t } = useI18n();
|
|
21
21
|
const { accessToken } = useIam();
|
|
22
22
|
const org = useOrg();
|
|
23
|
-
return (_jsxs(YStack, { gap: "$
|
|
23
|
+
return (_jsxs(YStack, { gap: "$4", maxW: 420, children: [_jsx(Text, { fontSize: "$3", color: "$soft", children: t("Kept with your account, so it follows you to every Hanzo surface.") }), _jsx(Appearance, { org: org.id, orgName: org.name || brand(), account: { base: api(), token: accessToken ?? undefined } }), _jsxs(YStack, { gap: "$2", pt: "$3", borderTopWidth: 1, borderColor: "$borderColor", children: [_jsx(Text, { fontSize: "$3", fontWeight: "600", color: "$ink", children: t("Language") }), _jsx(Text, { fontSize: "$2", color: "$soft", children: t("The language Hanzo is shown in, on every Hanzo surface you sign in to.") }), _jsx(XStack, { pt: "$1", children: _jsx(LanguagePicker, {}) })] })] }));
|
|
24
24
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanzo/app",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Hanzo's app: the shell and its apps (Home, Chat, Inbox, Contacts, Meet, Calendar, Drive, Board, Work, Bots), once, for every Hanzo surface.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|