@opengeni/react 7.4.0-canary.36855269964001 → 7.4.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/README.md +3 -48
- package/dist/artifacts-document.js +2 -3
- package/dist/artifacts-presentation.js +2 -3
- package/dist/artifacts-spreadsheet.js +2 -2
- package/dist/artifacts.d.ts +0 -1
- package/dist/artifacts.js +1402 -505
- package/dist/artifacts.js.map +1 -1
- package/dist/{browser-viewer-R6KK5VKR.js → browser-viewer-2E6R2Y4W.js} +4 -4
- package/dist/{chunk-WUISZ3WU.js → chunk-3E2AITTZ.js} +28 -32
- package/dist/{chunk-WUISZ3WU.js.map → chunk-3E2AITTZ.js.map} +1 -1
- package/dist/{chunk-PWUILT2U.js → chunk-5AZSK6MV.js} +2 -2
- package/dist/{chunk-Y2PRMYLC.js → chunk-DUEBTL3N.js} +3 -4
- package/dist/{chunk-Y2PRMYLC.js.map → chunk-DUEBTL3N.js.map} +1 -1
- package/dist/{chunk-7UAMYXJY.js → chunk-KNDIXZN6.js} +18 -25
- package/dist/{chunk-7UAMYXJY.js.map → chunk-KNDIXZN6.js.map} +1 -1
- package/dist/{chunk-P4G6K2E2.js → chunk-L4OSXQ6H.js} +884 -1119
- package/dist/chunk-L4OSXQ6H.js.map +1 -0
- package/dist/{chunk-LLIH7Q4B.js → chunk-S5JQ4R22.js} +19 -47
- package/dist/chunk-S5JQ4R22.js.map +1 -0
- package/dist/{chunk-A4UJB2MM.js → chunk-SEEVCT36.js} +2 -2
- package/dist/{chunk-UXJCQ5GH.js → chunk-UDD6DLLT.js} +1 -6
- package/dist/chunk-UDD6DLLT.js.map +1 -0
- package/dist/chunk-UGMKPUEM.js +299 -0
- package/dist/chunk-UGMKPUEM.js.map +1 -0
- package/dist/{chunk-ZCZHKJKZ.js → chunk-USXVQACU.js} +3 -3
- package/dist/{chunk-VABBF52G.js → chunk-V2ABIVYJ.js} +6 -70
- package/dist/chunk-V2ABIVYJ.js.map +1 -0
- package/dist/{chunk-TVO6GXR6.js → chunk-X4HIN6TV.js} +162 -71
- package/dist/chunk-X4HIN6TV.js.map +1 -0
- package/dist/{chunk-IIDEIBMC.js → chunk-XEJEOAOV.js} +38 -49
- package/dist/chunk-XEJEOAOV.js.map +1 -0
- package/dist/{chunk-ZKLCPBWN.js → chunk-Y3QTZN2F.js} +5 -5
- package/dist/{chunk-73BUNGLF.js → chunk-YZ3YYMOM.js} +1 -1
- package/dist/components/artifacts/editable-artifact-ui.d.ts +1 -2
- package/dist/components/artifacts/index.d.ts +0 -7
- package/dist/components/browser-select-control.d.ts +1 -3
- package/dist/components/message-timeline.d.ts +1 -18
- package/dist/components/open-geni-links.d.ts +0 -16
- package/dist/components/session-conversation.d.ts +1 -20
- package/dist/composer.js +3 -3
- package/dist/{computer-viewer-DJHPSP2J.js → computer-viewer-WMJE6OA3.js} +3 -3
- package/dist/connect.js +6 -7
- package/dist/connect.js.map +1 -1
- package/dist/hooks/latest-question.d.ts +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.js +28 -39
- package/dist/index.js.map +1 -1
- package/dist/interaction.js +4 -4
- package/dist/{latest-question-KGCDK3XX.js → latest-question-QB4EUCW5.js} +3 -3
- package/dist/lib/format.d.ts +0 -3
- package/dist/machines.js +2 -2
- package/dist/{markdown-table-layout-QXSLK4BY.js → markdown-table-layout-PFUEZ2U4.js} +5 -37
- package/dist/markdown-table-layout-PFUEZ2U4.js.map +1 -0
- package/dist/{sandbox-files-4PMXDSDV.js → sandbox-files-PXPIZAFG.js} +2 -2
- package/dist/session-ui.d.ts +2 -5
- package/dist/session-ui.js +13 -23
- package/dist/session-ui.js.map +1 -1
- package/dist/session.js +3 -3
- package/dist/sites.js +289 -4
- package/dist/sites.js.map +1 -1
- package/dist/timeline/types.d.ts +1 -7
- package/dist/{timeline-annotation-selection-DMLMM2TX.js → timeline-annotation-selection-ODLVF4OI.js} +1 -6
- package/dist/timeline-annotation-selection-ODLVF4OI.js.map +1 -0
- package/package.json +3 -7
- package/src/artifacts.ts +0 -37
- package/src/components/artifacts/editable-artifact-ui.tsx +1 -3
- package/src/components/artifacts/editable-artifact-workbench.tsx +2 -5
- package/src/components/artifacts/editable-document.tsx +36 -34
- package/src/components/artifacts/editable-presentation.tsx +16 -21
- package/src/components/artifacts/index.ts +0 -41
- package/src/components/browser-select-control.tsx +1 -4
- package/src/components/browser-viewer.tsx +22 -81
- package/src/components/computer-viewer.tsx +23 -51
- package/src/components/markdown-table-layout.ts +5 -49
- package/src/components/markdown.tsx +2 -5
- package/src/components/message-timeline.tsx +434 -515
- package/src/components/open-geni-links.tsx +0 -24
- package/src/components/session-conversation.tsx +20 -131
- package/src/components/timeline-annotation-selection.tsx +0 -7
- package/src/hooks/use-available-models.ts +1 -1
- package/src/index.ts +0 -9
- package/src/lib/format.ts +0 -13
- package/src/session-ui.ts +0 -9
- package/src/timeline/projection.ts +4 -78
- package/src/timeline/types.ts +0 -7
- package/styles/compiled.css +0 -325
- package/dist/chat-interactive-block-VAGABN7J.js +0 -11
- package/dist/chunk-5CVXZA3Y.js +0 -292
- package/dist/chunk-5CVXZA3Y.js.map +0 -1
- package/dist/chunk-B3V6TG77.js +0 -41
- package/dist/chunk-B3V6TG77.js.map +0 -1
- package/dist/chunk-IIDEIBMC.js.map +0 -1
- package/dist/chunk-LLIH7Q4B.js.map +0 -1
- package/dist/chunk-P4G6K2E2.js.map +0 -1
- package/dist/chunk-RAIQYITC.js +0 -1772
- package/dist/chunk-RAIQYITC.js.map +0 -1
- package/dist/chunk-SCOTPE2I.js +0 -589
- package/dist/chunk-SCOTPE2I.js.map +0 -1
- package/dist/chunk-TVO6GXR6.js.map +0 -1
- package/dist/chunk-UXJCQ5GH.js.map +0 -1
- package/dist/chunk-VABBF52G.js.map +0 -1
- package/dist/chunk-WEHMPOXK.js +0 -39
- package/dist/chunk-WEHMPOXK.js.map +0 -1
- package/dist/chunk-XCHWDJ22.js +0 -107
- package/dist/chunk-XCHWDJ22.js.map +0 -1
- package/dist/components/artifacts/artifact-chrome.d.ts +0 -120
- package/dist/components/artifacts/artifact-sandbox.d.ts +0 -27
- package/dist/components/artifacts/chat-interactive-block.d.ts +0 -29
- package/dist/components/artifacts/deferred-chat-media.d.ts +0 -15
- package/dist/components/artifacts/editable-artifact-view.d.ts +0 -46
- package/dist/components/artifacts/latest-task-runner.d.ts +0 -15
- package/dist/components/artifacts/session-artifact-viewer.d.ts +0 -39
- package/dist/components/artifacts/site-view.d.ts +0 -23
- package/dist/components/timeline-pill-geometry.d.ts +0 -6
- package/dist/components/timeline-pill-placement.d.ts +0 -18
- package/dist/components/usage-limit-notice.d.ts +0 -49
- package/dist/components/usage-member-list.d.ts +0 -91
- package/dist/components/usage-meter.d.ts +0 -73
- package/dist/hooks/use-usage.d.ts +0 -40
- package/dist/markdown-table-layout-QXSLK4BY.js.map +0 -1
- package/dist/sandbox-files-4PMXDSDV.js.map +0 -1
- package/dist/timeline/allowance-exhausted-row.d.ts +0 -24
- package/dist/timeline-annotation-selection-DMLMM2TX.js.map +0 -1
- package/dist/timeline-pill-geometry-2G6EK47V.js +0 -73
- package/dist/timeline-pill-geometry-2G6EK47V.js.map +0 -1
- package/dist/usage/allowance-copy.d.ts +0 -25
- package/dist/usage/summary.d.ts +0 -35
- package/dist/usage.d.ts +0 -13
- package/dist/usage.js +0 -1073
- package/dist/usage.js.map +0 -1
- package/src/components/artifacts/artifact-chrome.tsx +0 -413
- package/src/components/artifacts/artifact-sandbox.tsx +0 -185
- package/src/components/artifacts/chat-interactive-block.tsx +0 -260
- package/src/components/artifacts/deferred-chat-media.tsx +0 -67
- package/src/components/artifacts/editable-artifact-view.tsx +0 -187
- package/src/components/artifacts/latest-task-runner.ts +0 -49
- package/src/components/artifacts/session-artifact-viewer.tsx +0 -376
- package/src/components/artifacts/site-view.tsx +0 -116
- package/src/components/timeline-pill-geometry.ts +0 -112
- package/src/components/timeline-pill-placement.ts +0 -81
- package/src/components/usage-limit-notice.tsx +0 -179
- package/src/components/usage-member-list.tsx +0 -792
- package/src/components/usage-meter.tsx +0 -382
- package/src/hooks/use-usage.ts +0 -100
- package/src/timeline/allowance-exhausted-row.tsx +0 -86
- package/src/usage/allowance-copy.ts +0 -64
- package/src/usage/summary.ts +0 -93
- package/src/usage.ts +0 -50
- /package/dist/{browser-viewer-R6KK5VKR.js.map → browser-viewer-2E6R2Y4W.js.map} +0 -0
- /package/dist/{chunk-PWUILT2U.js.map → chunk-5AZSK6MV.js.map} +0 -0
- /package/dist/{chunk-A4UJB2MM.js.map → chunk-SEEVCT36.js.map} +0 -0
- /package/dist/{chunk-ZCZHKJKZ.js.map → chunk-USXVQACU.js.map} +0 -0
- /package/dist/{chunk-ZKLCPBWN.js.map → chunk-Y3QTZN2F.js.map} +0 -0
- /package/dist/{chunk-73BUNGLF.js.map → chunk-YZ3YYMOM.js.map} +0 -0
- /package/dist/{chat-interactive-block-VAGABN7J.js.map → computer-viewer-WMJE6OA3.js.map} +0 -0
- /package/dist/{latest-question-KGCDK3XX.js.map → latest-question-QB4EUCW5.js.map} +0 -0
- /package/dist/{computer-viewer-DJHPSP2J.js.map → sandbox-files-PXPIZAFG.js.map} +0 -0
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import type { UsageAllowancePeriod, WorkspaceUsageResponse } from "@opengeni/sdk/usage-allowances";
|
|
2
|
-
import { type UsageClientLike } from "../hooks/use-usage.js";
|
|
3
|
-
import { type AllowanceLabels } from "../usage/allowance-copy.js";
|
|
4
|
-
import { type UsageSummary } from "../usage/summary.js";
|
|
5
|
-
export type UsageMeterLabels = AllowanceLabels & {
|
|
6
|
-
/** Heading for the member's own ceiling. */
|
|
7
|
-
title: string;
|
|
8
|
-
/** Heading when only the shared workspace pool applies. */
|
|
9
|
-
workspaceTitle: string;
|
|
10
|
-
/** "38% left" — `percent` is preformatted ("38", "<1"). */
|
|
11
|
-
left: (percent: string) => string;
|
|
12
|
-
/** "62% used". */
|
|
13
|
-
used: (percent: string) => string;
|
|
14
|
-
limitReached: string;
|
|
15
|
-
/** Status chip beside a hero meter that is close to its limit. */
|
|
16
|
-
nearLimit: string;
|
|
17
|
-
/** "$13.00 left" for a hero meter with amounts. */
|
|
18
|
-
amountLeft: (amount: string) => string;
|
|
19
|
-
/** No ceiling applies to this member. */
|
|
20
|
-
unlimited: string;
|
|
21
|
-
loading: string;
|
|
22
|
-
error: string;
|
|
23
|
-
retry: string;
|
|
24
|
-
/** "$31.00 of $50.00 used" when the host passes `formatAmount`. */
|
|
25
|
-
amounts: (used: string, limit: string) => string;
|
|
26
|
-
/** The shared pool, under a member's own meter: "Workspace: 9% left". */
|
|
27
|
-
workspaceLine: (value: string) => string;
|
|
28
|
-
};
|
|
29
|
-
export declare const DEFAULT_USAGE_METER_LABELS: UsageMeterLabels;
|
|
30
|
-
export type UsageMeterBaseProps = {
|
|
31
|
-
/** "left" (default) reads like a battery; "used" reads like spend. */
|
|
32
|
-
measure?: "left" | "used" | undefined;
|
|
33
|
-
/**
|
|
34
|
-
* Opt in to amounts. Receives USD micros; return your own unit ("$31.00",
|
|
35
|
-
* "3.1 credits", "1.5× plan"). Without it the meter shows only shares.
|
|
36
|
-
*/
|
|
37
|
-
formatAmount?: ((micros: number) => string) | undefined;
|
|
38
|
-
labels?: Partial<UsageMeterLabels> | undefined;
|
|
39
|
-
/**
|
|
40
|
-
* `compact` is one line for menus and headers; `hero` leads a page with the
|
|
41
|
-
* amount (or share) left in large type. An empty `labels.title` hides the
|
|
42
|
-
* heading when the page already names it.
|
|
43
|
-
*/
|
|
44
|
-
density?: "default" | "compact" | "hero" | undefined;
|
|
45
|
-
/** Show the shared pool under the member's own meter when it is the tighter one. Default true. */
|
|
46
|
-
showWorkspace?: boolean | undefined;
|
|
47
|
-
className?: string | undefined;
|
|
48
|
-
};
|
|
49
|
-
export type UsageMeterProps = UsageMeterBaseProps & {
|
|
50
|
-
/**
|
|
51
|
-
* A usage response you already loaded (for example from `useUsage`).
|
|
52
|
-
* Omit it to let the meter read `/usage/me` itself.
|
|
53
|
-
*/
|
|
54
|
-
usage?: WorkspaceUsageResponse | null | undefined;
|
|
55
|
-
client?: UsageClientLike | undefined;
|
|
56
|
-
workspaceId?: string | undefined;
|
|
57
|
-
period?: UsageAllowancePeriod | undefined;
|
|
58
|
-
/** Re-read when this changes (see `useUsage`). */
|
|
59
|
-
refreshKey?: unknown;
|
|
60
|
-
};
|
|
61
|
-
/**
|
|
62
|
-
* The signed-in member's own usage: how much of their limit is left and when
|
|
63
|
-
* it resets. Shares only by default; hosts opt in to amounts.
|
|
64
|
-
*/
|
|
65
|
-
export declare function UsageMeter({ usage, client, workspaceId, period, refreshKey, ...view }: UsageMeterProps): import("react").JSX.Element;
|
|
66
|
-
export type UsageMeterViewProps = UsageMeterBaseProps & {
|
|
67
|
-
summary: UsageSummary | null;
|
|
68
|
-
loading?: boolean | undefined;
|
|
69
|
-
error?: Error | null | undefined;
|
|
70
|
-
onRetry?: (() => void) | undefined;
|
|
71
|
-
};
|
|
72
|
-
/** Presentational meter for a summary you computed (`summarizeUsage`). */
|
|
73
|
-
export declare function UsageMeterView({ summary, loading, error, onRetry, measure, formatAmount, labels: overrides, density, showWorkspace, className, }: UsageMeterViewProps): import("react").JSX.Element;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { OpenGeniClient } from "@opengeni/sdk";
|
|
2
|
-
import { type UsageAllowancePeriod, type WorkspaceUsageResponse } from "@opengeni/sdk/usage-allowances";
|
|
3
|
-
import { type UsageSummary } from "../usage/summary.js";
|
|
4
|
-
/**
|
|
5
|
-
* Anything that can read the signed-in member's own usage: the root SDK client
|
|
6
|
-
* pointed at your session proxy (`getMyUsage`), or any client exposing
|
|
7
|
-
* `requestJson` (for example the narrower browser client).
|
|
8
|
-
*/
|
|
9
|
-
export type UsageClientLike = Pick<OpenGeniClient, "getMyUsage"> | Pick<OpenGeniClient, "requestJson">;
|
|
10
|
-
export type UseUsageOptions = {
|
|
11
|
-
/** Defaults to the `<OpenGeniProvider>` client. */
|
|
12
|
-
client?: UsageClientLike | undefined;
|
|
13
|
-
/** Defaults to the `<OpenGeniProvider>` workspace. */
|
|
14
|
-
workspaceId?: string | undefined;
|
|
15
|
-
/** `"current"` (default) or a `YYYY-MM` allowance period. */
|
|
16
|
-
period?: UsageAllowancePeriod | undefined;
|
|
17
|
-
/** Re-read on an interval. Off by default; usage changes only when work settles. */
|
|
18
|
-
pollIntervalMs?: number | undefined;
|
|
19
|
-
enabled?: boolean | undefined;
|
|
20
|
-
/**
|
|
21
|
-
* Re-read whenever this value changes, keeping the current reading while it
|
|
22
|
-
* loads. Pass something that changes when work settles (a turn count, the
|
|
23
|
-
* session status) so the meter follows real usage without polling.
|
|
24
|
-
*/
|
|
25
|
-
refreshKey?: unknown;
|
|
26
|
-
};
|
|
27
|
-
export type UseUsageResult = {
|
|
28
|
-
/** The raw `/usage/me` response: the workspace pool and your own row. */
|
|
29
|
-
usage: WorkspaceUsageResponse | null;
|
|
30
|
-
/** What to tell this member; null until loaded. */
|
|
31
|
-
summary: UsageSummary | null;
|
|
32
|
-
loading: boolean;
|
|
33
|
-
error: Error | null;
|
|
34
|
-
refresh: () => Promise<void>;
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* The signed-in member's own usage in one workspace, read through `/usage/me`
|
|
38
|
-
* (the session proxy serves exactly this route). Never reads another member.
|
|
39
|
-
*/
|
|
40
|
-
export declare function useUsage(options?: UseUsageOptions): UseUsageResult;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/markdown-table-layout.ts"],"sourcesContent":["export function markdownTableWidth({\n columnLeft,\n columnWidth,\n contentLeft,\n contentRight,\n preferredWidth,\n}: {\n columnLeft: number;\n columnWidth: number;\n contentLeft: number;\n contentRight: number;\n preferredWidth: number;\n}): number {\n const center = columnLeft + columnWidth / 2;\n const available = 2 * Math.min(center - contentLeft, contentRight - center);\n return Math.max(columnWidth, Math.min(preferredWidth, available));\n}\n\nfunction measurementCopy(source: Node, document: Document): Node {\n if (source.nodeType === Node.ELEMENT_NODE) {\n const element = source as Element;\n // Inert prevents focus, not custom-element construction, media loading or\n // embedded browsing contexts. Do not clone those host-rendered surfaces.\n if (\n element.localName.includes(\"-\") ||\n [\"iframe\", \"object\", \"embed\", \"video\", \"audio\", \"canvas\", \"script\"].includes(\n element.localName,\n )\n ) {\n const bounds = element.getBoundingClientRect();\n const placeholder = document.createElement(\"span\");\n placeholder.style.display = \"inline-block\";\n placeholder.style.width = `${bounds.width}px`;\n placeholder.style.height = `${bounds.height}px`;\n return placeholder;\n }\n }\n const copy = document.importNode(source, false);\n if (copy.nodeType === Node.ELEMENT_NODE) {\n const element = copy as Element;\n element.removeAttribute(\"id\");\n for (const attribute of [...element.attributes]) {\n if (attribute.name.startsWith(\"on\")) element.removeAttribute(attribute.name);\n }\n }\n for (const child of source.childNodes) copy.appendChild(measurementCopy(child, document));\n return copy;\n}\n\n/** Loaded only for assistant tables. Keep prose and nested scroll owners intact. */\nexport function observeMarkdownTableLayout(wrapper: HTMLDivElement, table: HTMLTableElement) {\n const body = wrapper.parentElement;\n const scroller = body\n ?.closest(\"[data-og-wide-table-message]\")\n ?.closest<HTMLElement>(\"[data-og-timeline-scroller]\");\n if (!body?.classList.contains(\"og-markdown-body\") || !scroller) return;\n\n // Build the static copy without a browsing context before inserting its probe.\n const measurementDocument = table.ownerDocument.implementation.createHTMLDocument(\"\");\n let width: number | null = null;\n const reset = () => {\n width = null;\n wrapper.style.width = \"\";\n wrapper.style.maxWidth = \"\";\n wrapper.style.marginInline = \"\";\n };\n const measure = () => {\n // Intermediate clipped/scrollable surfaces own their own content bounds.\n for (\n let ancestor: HTMLElement | null = body;\n ancestor && ancestor !== scroller;\n ancestor = ancestor.parentElement\n ) {\n if (getComputedStyle(ancestor).overflowX !== \"visible\") {\n reset();\n return;\n }\n }\n const column = body.getBoundingClientRect();\n const panel = scroller.getBoundingClientRect();\n const panelStyle = getComputedStyle(scroller);\n const left = panel.left + scroller.clientLeft + parseFloat(panelStyle.paddingLeft);\n const right =\n panel.left + scroller.clientLeft + scroller.clientWidth - parseFloat(panelStyle.paddingRight);\n\n // Even a temporary max-content width on the live table changes its height\n // during forced layout. Browser scroll anchoring can retain that displacement\n // after the width is restored. Measure a copy without touching live geometry.\n const probe = table.ownerDocument.createElement(\"div\");\n probe.setAttribute(\"aria-hidden\", \"true\");\n probe.inert = true;\n // A zero-sized, contained box cannot extend the scroller's overflow area,\n // including inside transformed ancestors. Keep the same inherited styling.\n probe.style.cssText =\n \"position:absolute;width:0;height:0;overflow:hidden;contain:layout size paint;visibility:hidden;pointer-events:none\";\n const copy = measurementCopy(table, measurementDocument) as HTMLTableElement;\n copy.style.width = \"max-content\";\n probe.append(copy);\n let preferred: number;\n try {\n table.parentElement!.append(probe);\n preferred = copy.getBoundingClientRect().width;\n } finally {\n probe.remove();\n }\n const next = markdownTableWidth({\n columnLeft: column.left,\n columnWidth: column.width,\n contentLeft: left,\n contentRight: right,\n preferredWidth: preferred,\n });\n if (width !== null && Math.abs(width - next) < 0.5) return;\n width = next;\n wrapper.style.width = `${width}px`;\n wrapper.style.maxWidth = \"none\";\n wrapper.style.marginInline = `calc((100% - ${width}px) / 2)`;\n };\n\n measure();\n const observer = typeof ResizeObserver === \"undefined\" ? undefined : new ResizeObserver(measure);\n observer?.observe(scroller);\n observer?.observe(body);\n observer?.observe(table);\n return {\n measure,\n disconnect: () => {\n observer?.disconnect();\n reset();\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { AllowanceExhaustedRefusal } from "@opengeni/sdk";
|
|
2
|
-
import { type ReactNode } from "react";
|
|
3
|
-
import { type AllowanceLabels } from "../usage/allowance-copy.js";
|
|
4
|
-
/**
|
|
5
|
-
* Replace the built-in "usage limit reached" row. Return `undefined` to keep
|
|
6
|
-
* the default for this refusal (for example, only customize member limits).
|
|
7
|
-
*/
|
|
8
|
-
export type RenderAllowanceExhausted = (refusal: AllowanceExhaustedRefusal, context: {
|
|
9
|
-
labels: AllowanceLabels;
|
|
10
|
-
defaultRow: ReactNode;
|
|
11
|
-
}) => ReactNode | undefined;
|
|
12
|
-
export declare function AllowancePresentationProvider({ render, labels, children, }: {
|
|
13
|
-
render: RenderAllowanceExhausted | undefined;
|
|
14
|
-
labels: Partial<AllowanceLabels> | undefined;
|
|
15
|
-
children: ReactNode;
|
|
16
|
-
}): import("react").JSX.Element;
|
|
17
|
-
/**
|
|
18
|
-
* A usage ceiling stopped further work. Calm by design: nothing failed, the
|
|
19
|
-
* conversation is kept, and the row says who can raise the limit and when it
|
|
20
|
-
* resets. Never the server's prose or a member identifier.
|
|
21
|
-
*/
|
|
22
|
-
export declare function AllowanceExhaustedRow({ refusal }: {
|
|
23
|
-
refusal: AllowanceExhaustedRefusal;
|
|
24
|
-
}): import("react").JSX.Element;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/timeline-annotation-selection.tsx"],"sourcesContent":["import type { DraftTimelineAnnotation } from \"@opengeni/sdk\";\nimport { QuoteIcon } from \"lucide-react\";\nimport { useEffect, useRef, useState, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { usePortalTokenStyle } from \"../lib/use-portal-token-style\";\nimport type { TimelineAnnotationSourceDescriptor } from \"../timeline\";\nimport {\n clipRangeToSource,\n matchingQuoteInSource,\n occurrenceOffsets,\n quoteOccurrenceIndex,\n truncateAnnotationQuote,\n visibleClientRect,\n} from \"./timeline-annotation-shared\";\n\ntype SelectionCandidate = {\n annotation: DraftTimelineAnnotation;\n left: number;\n top: number;\n keyboard: boolean;\n};\n\nconst CONTROL_SELECTOR = \"button,input,textarea,select,summary,[contenteditable='true']\";\nconst SOURCE_CONTEXT_BYTES = 160;\nconst MAX_QUOTE_BYTES = 16 * 1024;\nconst POPOVER_WIDTH = 280;\nconst POPOVER_HEIGHT = 64;\n\nfunction utf8Prefix(value: string, maxBytes: number): string {\n let output = \"\";\n let bytes = 0;\n for (const character of value) {\n const next = new TextEncoder().encode(character).byteLength;\n if (bytes + next > maxBytes) break;\n output += character;\n bytes += next;\n }\n return output;\n}\n\nfunction utf8Suffix(value: string, maxBytes: number): string {\n let output = \"\";\n let bytes = 0;\n for (const character of [...value].reverse()) {\n const next = new TextEncoder().encode(character).byteLength;\n if (bytes + next > maxBytes) break;\n output = character + output;\n bytes += next;\n }\n return output;\n}\n\nfunction selectionElement(node: Node | null): Element | null {\n return node instanceof Element ? node : (node?.parentElement ?? null);\n}\n\nfunction containingSource(node: Node | null): HTMLElement | null {\n const element = selectionElement(node);\n const source = element?.closest(\"[data-og-annotation-source-key]\");\n return source instanceof HTMLElement ? source : null;\n}\n\nfunction resolveSourceBoundary(range: Range, root: HTMLElement): HTMLElement | null {\n const start = containingSource(range.startContainer);\n const end = containingSource(range.endContainer);\n if (start && end && start !== end) return null;\n const boundary = start ?? end;\n if (!boundary || !root.contains(boundary)) return null;\n return boundary;\n}\n\nfunction isWhollyInsideControl(range: Range, boundary: HTMLElement): boolean {\n const start = selectionElement(range.startContainer)?.closest(CONTROL_SELECTOR);\n const end = selectionElement(range.endContainer)?.closest(CONTROL_SELECTOR);\n return (\n start instanceof Element && start === end && boundary.contains(start) && start !== boundary\n );\n}\n\nfunction annotationId(): string {\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\n return globalThis.crypto.randomUUID();\n }\n return `annotation-${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction popoverPosition(rect: DOMRect): { left: number; top: number } {\n const half = POPOVER_WIDTH / 2;\n const left = clamp(rect.left + rect.width / 2, 12 + half, window.innerWidth - 12 - half);\n const preferBelow = rect.bottom + 8 + POPOVER_HEIGHT <= window.innerHeight - 12;\n const top = preferBelow ? rect.bottom + 8 : Math.max(12, rect.top - POPOVER_HEIGHT - 8);\n return { left, top };\n}\n\nfunction buildCandidate(\n root: HTMLElement,\n sources: ReadonlyMap<string, TimelineAnnotationSourceDescriptor>,\n keyboard: boolean,\n): SelectionCandidate | null {\n const selection = document.getSelection();\n if (!selection || selection.rangeCount !== 1 || selection.isCollapsed) return null;\n const range = selection.getRangeAt(0);\n const startBoundary = resolveSourceBoundary(range, root);\n if (!startBoundary) return null;\n if (isWhollyInsideControl(range, startBoundary)) return null;\n const clipped = clipRangeToSource(range, startBoundary);\n if (!clipped) return null;\n const sourceKey = startBoundary.dataset.ogAnnotationSourceKey;\n const source = sourceKey ? sources.get(sourceKey) : undefined;\n const rawQuote = clipped.toString();\n const quote = (source ? matchingQuoteInSource(source.text, rawQuote) : null) ?? rawQuote;\n if (\n !source ||\n quote.trim().length === 0 ||\n new TextEncoder().encode(quote).byteLength > MAX_QUOTE_BYTES\n ) {\n return null;\n }\n const sourceOffsets = occurrenceOffsets(source.text, quote);\n if (sourceOffsets.length === 0) return null;\n const occurrence = quoteOccurrenceIndex(startBoundary, clipped, quote);\n const startOffset = sourceOffsets[Math.min(occurrence, sourceOffsets.length - 1)]!;\n const endOffset = startOffset + quote.length;\n const rect = visibleClientRect(range) ?? visibleClientRect(clipped);\n if (!rect) return null;\n const position = popoverPosition(rect);\n return {\n annotation: {\n id: annotationId(),\n quote,\n note: \"\",\n source: {\n kind: source.kind,\n eventId: source.eventId,\n eventType: source.eventType,\n sequence: source.sequence,\n turnId: source.turnId,\n startOffset,\n endOffset,\n contextBefore: utf8Suffix(source.text.slice(0, startOffset), SOURCE_CONTEXT_BYTES),\n contextAfter: utf8Prefix(source.text.slice(endOffset), SOURCE_CONTEXT_BYTES),\n ...(source.label ? { label: source.label } : {}),\n },\n },\n left: position.left,\n top: position.top,\n keyboard,\n };\n}\n\nexport function TimelineAnnotationSelection({\n rootRef,\n sources,\n onAnnotate,\n}: {\n rootRef: RefObject<HTMLElement | null>;\n sources: ReadonlyMap<string, TimelineAnnotationSourceDescriptor>;\n onAnnotate?: ((annotation: DraftTimelineAnnotation) => void) | undefined;\n}) {\n const [candidate, setCandidate] = useState<SelectionCandidate | null>(null);\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n const initialSelectionObservedRef = useRef(false);\n const pointerOriginRef = useRef<\"unset\" | \"inside\" | \"outside\">(\"unset\");\n const portalStyle = usePortalTokenStyle(rootRef.current);\n\n useEffect(() => {\n const root = rootRef.current;\n if (!root || !onAnnotate) {\n setCandidate(null);\n return;\n }\n const update = (keyboard: boolean) => {\n setCandidate(buildCandidate(root, sources, keyboard));\n };\n // A user may finish selecting text before this lazy component arrives.\n // Reconcile once; later prop changes must not revive dismissed selections.\n if (!initialSelectionObservedRef.current) {\n initialSelectionObservedRef.current = true;\n update(false);\n }\n const onRootPointerUp = (event: PointerEvent) => {\n if (event.target instanceof Node && buttonRef.current?.contains(event.target)) return;\n // Tests may fire only pointerup on the source. A real click that started\n // outside the timeline must not resurrect leftover selection.\n if (pointerOriginRef.current === \"outside\") return;\n window.setTimeout(() => update(false), 0);\n };\n const onDocumentPointerUp = (event: PointerEvent) => {\n if (event.target instanceof Node && buttonRef.current?.contains(event.target)) return;\n const startedInRoot = pointerOriginRef.current === \"inside\";\n pointerOriginRef.current = \"unset\";\n if (!startedInRoot) return;\n window.setTimeout(() => update(false), 0);\n };\n const onKeyUp = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setCandidate(null);\n return;\n }\n window.setTimeout(() => update(true), 0);\n };\n const onPointerDown = (event: PointerEvent) => {\n if (event.target instanceof Node && buttonRef.current?.contains(event.target)) {\n event.preventDefault();\n return;\n }\n pointerOriginRef.current =\n event.target instanceof Node && root.contains(event.target) ? \"inside\" : \"outside\";\n setCandidate(null);\n };\n const onDocumentKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") setCandidate(null);\n };\n const onSelectionChange = () => {\n if (buttonRef.current && document.activeElement === buttonRef.current) return;\n const selection = document.getSelection();\n if (!selection || selection.isCollapsed) setCandidate(null);\n };\n root.addEventListener(\"pointerup\", onRootPointerUp);\n root.addEventListener(\"keyup\", onKeyUp);\n document.addEventListener(\"pointerup\", onDocumentPointerUp);\n document.addEventListener(\"pointerdown\", onPointerDown);\n document.addEventListener(\"keydown\", onDocumentKeyDown);\n document.addEventListener(\"selectionchange\", onSelectionChange);\n return () => {\n root.removeEventListener(\"pointerup\", onRootPointerUp);\n root.removeEventListener(\"keyup\", onKeyUp);\n document.removeEventListener(\"pointerup\", onDocumentPointerUp);\n document.removeEventListener(\"pointerdown\", onPointerDown);\n document.removeEventListener(\"keydown\", onDocumentKeyDown);\n document.removeEventListener(\"selectionchange\", onSelectionChange);\n };\n }, [onAnnotate, rootRef, sources]);\n\n useEffect(() => {\n if (candidate?.keyboard) buttonRef.current?.focus();\n }, [candidate]);\n\n if (!candidate || !onAnnotate || typeof document === \"undefined\") return null;\n const preview = truncateAnnotationQuote(candidate.annotation.quote, 72);\n return createPortal(\n <button\n ref={buttonRef}\n type=\"button\"\n data-og-annotation-popover=\"\"\n style={{ left: candidate.left, top: candidate.top, ...portalStyle }}\n className=\"og-root fixed z-[80] flex max-w-[min(18rem,calc(100vw-1.5rem))] -translate-x-1/2 items-start gap-2 rounded-2xl border border-og-border bg-og-surface-1 px-3 py-2 text-og-sm font-medium text-og-fg shadow-xl outline-hidden transition hover:border-og-accent/40 hover:bg-og-surface-2 focus-visible:ring-2 focus-visible:ring-og-accent pointer-coarse:min-h-[44px]\"\n aria-label={`Add a note about “${preview}”`}\n title={candidate.annotation.quote}\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => {\n onAnnotate(candidate.annotation);\n document.getSelection()?.removeAllRanges();\n setCandidate(null);\n }}\n >\n <QuoteIcon className=\"mt-0.5 size-3.5 shrink-0 text-og-accent\" aria-hidden=\"true\" />\n <span className=\"min-w-0 text-left\">\n <span className=\"block leading-5\">Add note</span>\n <span className=\"mt-0.5 block truncate text-og-xs font-normal text-og-fg-muted\">\n {preview}\n </span>\n </span>\n </button>,\n document.body,\n );\n}\n\nexport default TimelineAnnotationSelection;\n"],"mappings":"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","names":[]}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// src/components/timeline-pill-geometry.ts
|
|
2
|
-
var INTERACTIVE = 'a[href], button, input, select, textarea, summary, [role="button"], [role="link"], [role="menuitem"], [role="tab"], [role="switch"], [role="checkbox"], [contenteditable="true"]';
|
|
3
|
-
var ROW_WIDTH_RATIO = 0.8;
|
|
4
|
-
function choosePlacement(pill, frame, scroller, preference, current) {
|
|
5
|
-
const pillRect = pill.getBoundingClientRect();
|
|
6
|
-
const frameRect = frame.getBoundingClientRect();
|
|
7
|
-
const view = scroller.getBoundingClientRect();
|
|
8
|
-
if (pillRect.width === 0 || view.width === 0) return current;
|
|
9
|
-
const inset = Math.max(0, pillRect.left - frameRect.left, frameRect.right - pillRect.right);
|
|
10
|
-
const gutter = Math.min(inset, parseFloat(getComputedStyle(scroller).paddingLeft) || 16);
|
|
11
|
-
const left = (placement) => placement === "start" ? frameRect.left + gutter : placement === "end" ? frameRect.right - gutter - pillRect.width : frameRect.left + (frameRect.width - pillRect.width) / 2;
|
|
12
|
-
const collisions = (placement) => countCollisions(
|
|
13
|
-
pill,
|
|
14
|
-
scroller,
|
|
15
|
-
view,
|
|
16
|
-
left(placement),
|
|
17
|
-
pillRect.top,
|
|
18
|
-
pillRect.width,
|
|
19
|
-
pillRect.height
|
|
20
|
-
);
|
|
21
|
-
if (collisions(current) === 0) return current;
|
|
22
|
-
let best = current;
|
|
23
|
-
let fewest = Number.POSITIVE_INFINITY;
|
|
24
|
-
for (const candidate of preference) {
|
|
25
|
-
const count = candidate === current ? collisions(current) : collisions(candidate);
|
|
26
|
-
if (count === 0) return candidate;
|
|
27
|
-
if (count < fewest) {
|
|
28
|
-
fewest = count;
|
|
29
|
-
best = candidate;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return best;
|
|
33
|
-
}
|
|
34
|
-
function countCollisions(pill, scroller, view, left, top, width, height) {
|
|
35
|
-
const document = scroller.ownerDocument;
|
|
36
|
-
let count = 0;
|
|
37
|
-
for (const fx of [0.06, 0.3, 0.5, 0.7, 0.94]) {
|
|
38
|
-
for (const fy of [0.2, 0.5, 0.8]) {
|
|
39
|
-
const x = left + width * fx;
|
|
40
|
-
const y = top + height * fy;
|
|
41
|
-
if (x < view.left || x > view.right || y < view.top || y > view.bottom) continue;
|
|
42
|
-
if (coversControl(document.elementsFromPoint(x, y), pill, scroller, view, x, y)) count += 1;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return count;
|
|
46
|
-
}
|
|
47
|
-
function coversControl(stack, pill, scroller, view, x, y) {
|
|
48
|
-
for (const element of stack) {
|
|
49
|
-
if (pill.contains(element)) continue;
|
|
50
|
-
if (!scroller.contains(element) || element === scroller) return false;
|
|
51
|
-
const control = element.closest(INTERACTIVE);
|
|
52
|
-
if (!control || !scroller.contains(control)) return false;
|
|
53
|
-
if (control.getBoundingClientRect().width < view.width * ROW_WIDTH_RATIO) return true;
|
|
54
|
-
if (element.closest("svg, img, canvas, video")) return true;
|
|
55
|
-
return textUnderPoint(element, x, y);
|
|
56
|
-
}
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
function textUnderPoint(element, x, y) {
|
|
60
|
-
const range = element.ownerDocument.createRange();
|
|
61
|
-
for (const node of element.childNodes) {
|
|
62
|
-
if (node.nodeType !== Node.TEXT_NODE || !node.textContent?.trim()) continue;
|
|
63
|
-
range.selectNodeContents(node);
|
|
64
|
-
for (const rect of range.getClientRects()) {
|
|
65
|
-
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) return true;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
export {
|
|
71
|
-
choosePlacement
|
|
72
|
-
};
|
|
73
|
-
//# sourceMappingURL=timeline-pill-geometry-2G6EK47V.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/timeline-pill-geometry.ts"],"sourcesContent":["import type { TimelinePillPlacement } from \"./timeline-pill-placement\";\n\nconst INTERACTIVE =\n 'a[href], button, input, select, textarea, summary, [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"tab\"], [role=\"switch\"], [role=\"checkbox\"], [contenteditable=\"true\"]';\n\n/** A control this wide is a row (a disclosure header); only what it draws counts. */\nconst ROW_WIDTH_RATIO = 0.8;\n\n/**\n * Hit-testing for useTimelinePillPlacement, loaded only once a pill shows so it\n * stays out of a session's first load.\n */\nexport function choosePlacement(\n pill: HTMLElement,\n frame: HTMLElement,\n scroller: HTMLElement,\n preference: readonly TimelinePillPlacement[],\n current: TimelinePillPlacement,\n): TimelinePillPlacement {\n const pillRect = pill.getBoundingClientRect();\n const frameRect = frame.getBoundingClientRect();\n const view = scroller.getBoundingClientRect();\n if (pillRect.width === 0 || view.width === 0) return current;\n const inset = Math.max(0, pillRect.left - frameRect.left, frameRect.right - pillRect.right);\n const gutter = Math.min(inset, parseFloat(getComputedStyle(scroller).paddingLeft) || 16);\n const left = (placement: TimelinePillPlacement) =>\n placement === \"start\"\n ? frameRect.left + gutter\n : placement === \"end\"\n ? frameRect.right - gutter - pillRect.width\n : frameRect.left + (frameRect.width - pillRect.width) / 2;\n const collisions = (placement: TimelinePillPlacement) =>\n countCollisions(\n pill,\n scroller,\n view,\n left(placement),\n pillRect.top,\n pillRect.width,\n pillRect.height,\n );\n // Stay put while the current spot is clear, so the pill does not wander.\n if (collisions(current) === 0) return current;\n let best = current;\n let fewest = Number.POSITIVE_INFINITY;\n for (const candidate of preference) {\n const count = candidate === current ? collisions(current) : collisions(candidate);\n if (count === 0) return candidate;\n if (count < fewest) {\n fewest = count;\n best = candidate;\n }\n }\n return best;\n}\n\nfunction countCollisions(\n pill: HTMLElement,\n scroller: HTMLElement,\n view: DOMRect,\n left: number,\n top: number,\n width: number,\n height: number,\n): number {\n const document = scroller.ownerDocument;\n let count = 0;\n for (const fx of [0.06, 0.3, 0.5, 0.7, 0.94]) {\n for (const fy of [0.2, 0.5, 0.8]) {\n const x = left + width * fx;\n const y = top + height * fy;\n if (x < view.left || x > view.right || y < view.top || y > view.bottom) continue;\n if (coversControl(document.elementsFromPoint(x, y), pill, scroller, view, x, y)) count += 1;\n }\n }\n return count;\n}\n\nfunction coversControl(\n stack: Element[],\n pill: HTMLElement,\n scroller: HTMLElement,\n view: DOMRect,\n x: number,\n y: number,\n): boolean {\n for (const element of stack) {\n if (pill.contains(element)) continue;\n if (!scroller.contains(element) || element === scroller) return false;\n const control = element.closest(INTERACTIVE);\n if (!control || !scroller.contains(control)) return false;\n // A compact control (a link, an icon button) is covered anywhere on its box.\n if (control.getBoundingClientRect().width < view.width * ROW_WIDTH_RATIO) return true;\n // A full-width row (a disclosure header) only where it draws something: an\n // icon or the glyphs of its label, never its empty background.\n if (element.closest(\"svg, img, canvas, video\")) return true;\n return textUnderPoint(element, x, y);\n }\n return false;\n}\n\nfunction textUnderPoint(element: Element, x: number, y: number): boolean {\n const range = element.ownerDocument.createRange();\n for (const node of element.childNodes) {\n if (node.nodeType !== Node.TEXT_NODE || !node.textContent?.trim()) continue;\n range.selectNodeContents(node);\n for (const rect of range.getClientRects()) {\n if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) return true;\n }\n }\n return false;\n}\n"],"mappings":";AAEA,IAAM,cACJ;AAGF,IAAM,kBAAkB;AAMjB,SAAS,gBACd,MACA,OACA,UACA,YACA,SACuB;AACvB,QAAM,WAAW,KAAK,sBAAsB;AAC5C,QAAM,YAAY,MAAM,sBAAsB;AAC9C,QAAM,OAAO,SAAS,sBAAsB;AAC5C,MAAI,SAAS,UAAU,KAAK,KAAK,UAAU,EAAG,QAAO;AACrD,QAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,OAAO,UAAU,MAAM,UAAU,QAAQ,SAAS,KAAK;AAC1F,QAAM,SAAS,KAAK,IAAI,OAAO,WAAW,iBAAiB,QAAQ,EAAE,WAAW,KAAK,EAAE;AACvF,QAAM,OAAO,CAAC,cACZ,cAAc,UACV,UAAU,OAAO,SACjB,cAAc,QACZ,UAAU,QAAQ,SAAS,SAAS,QACpC,UAAU,QAAQ,UAAU,QAAQ,SAAS,SAAS;AAC9D,QAAM,aAAa,CAAC,cAClB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,SAAS;AAAA,IACd,SAAS;AAAA,IACT,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAEF,MAAI,WAAW,OAAO,MAAM,EAAG,QAAO;AACtC,MAAI,OAAO;AACX,MAAI,SAAS,OAAO;AACpB,aAAW,aAAa,YAAY;AAClC,UAAM,QAAQ,cAAc,UAAU,WAAW,OAAO,IAAI,WAAW,SAAS;AAChF,QAAI,UAAU,EAAG,QAAO;AACxB,QAAI,QAAQ,QAAQ;AAClB,eAAS;AACT,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBACP,MACA,UACA,MACA,MACA,KACA,OACA,QACQ;AACR,QAAM,WAAW,SAAS;AAC1B,MAAI,QAAQ;AACZ,aAAW,MAAM,CAAC,MAAM,KAAK,KAAK,KAAK,IAAI,GAAG;AAC5C,eAAW,MAAM,CAAC,KAAK,KAAK,GAAG,GAAG;AAChC,YAAM,IAAI,OAAO,QAAQ;AACzB,YAAM,IAAI,MAAM,SAAS;AACzB,UAAI,IAAI,KAAK,QAAQ,IAAI,KAAK,SAAS,IAAI,KAAK,OAAO,IAAI,KAAK,OAAQ;AACxE,UAAI,cAAc,SAAS,kBAAkB,GAAG,CAAC,GAAG,MAAM,UAAU,MAAM,GAAG,CAAC,EAAG,UAAS;AAAA,IAC5F;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,cACP,OACA,MACA,UACA,MACA,GACA,GACS;AACT,aAAW,WAAW,OAAO;AAC3B,QAAI,KAAK,SAAS,OAAO,EAAG;AAC5B,QAAI,CAAC,SAAS,SAAS,OAAO,KAAK,YAAY,SAAU,QAAO;AAChE,UAAM,UAAU,QAAQ,QAAQ,WAAW;AAC3C,QAAI,CAAC,WAAW,CAAC,SAAS,SAAS,OAAO,EAAG,QAAO;AAEpD,QAAI,QAAQ,sBAAsB,EAAE,QAAQ,KAAK,QAAQ,gBAAiB,QAAO;AAGjF,QAAI,QAAQ,QAAQ,yBAAyB,EAAG,QAAO;AACvD,WAAO,eAAe,SAAS,GAAG,CAAC;AAAA,EACrC;AACA,SAAO;AACT;AAEA,SAAS,eAAe,SAAkB,GAAW,GAAoB;AACvE,QAAM,QAAQ,QAAQ,cAAc,YAAY;AAChD,aAAW,QAAQ,QAAQ,YAAY;AACrC,QAAI,KAAK,aAAa,KAAK,aAAa,CAAC,KAAK,aAAa,KAAK,EAAG;AACnE,UAAM,mBAAmB,IAAI;AAC7B,eAAW,QAAQ,MAAM,eAAe,GAAG;AACzC,UAAI,KAAK,KAAK,QAAQ,KAAK,KAAK,SAAS,KAAK,KAAK,OAAO,KAAK,KAAK,OAAQ,QAAO;AAAA,IACrF;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/** Which ceiling ran out: the shared workspace pool, or one member's share of it. */
|
|
2
|
-
export type AllowanceScope = "workspace" | "member";
|
|
3
|
-
export type AllowanceLabels = {
|
|
4
|
-
/** "Usage limit reached" for a member ceiling. */
|
|
5
|
-
memberLimitReachedTitle: string;
|
|
6
|
-
/** "Workspace usage limit reached" for the shared pool. */
|
|
7
|
-
workspaceLimitReachedTitle: string;
|
|
8
|
-
/** Who can fix a member ceiling. */
|
|
9
|
-
memberRemedy: string;
|
|
10
|
-
/** Who can fix the workspace pool. */
|
|
11
|
-
workspaceRemedy: string;
|
|
12
|
-
/** "Resets Nov 1". `date` is already formatted by `formatDate`. */
|
|
13
|
-
resets: (date: string) => string;
|
|
14
|
-
/** Shown when a ceiling has no automatic reset. */
|
|
15
|
-
noReset: string;
|
|
16
|
-
/** Formats a reset instant for `resets`. Defaults to a short local date. */
|
|
17
|
-
formatDate: (iso: string) => string;
|
|
18
|
-
};
|
|
19
|
-
export declare function formatAllowanceDate(iso: string, now?: Date): string;
|
|
20
|
-
/** Full local date and time, for a title/tooltip next to the short date. */
|
|
21
|
-
export declare function formatAllowanceInstant(iso: string): string;
|
|
22
|
-
export declare const DEFAULT_ALLOWANCE_LABELS: AllowanceLabels;
|
|
23
|
-
export declare function allowanceLabels(overrides?: Partial<AllowanceLabels>): AllowanceLabels;
|
|
24
|
-
/** "Resets Nov 1." or the no-reset sentence. */
|
|
25
|
-
export declare function allowanceResetSentence(labels: AllowanceLabels, resetsAt: string | null): string;
|
package/dist/usage/summary.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { UsageAllowanceStatus, WorkspaceUsageResponse } from "@opengeni/sdk/usage-allowances";
|
|
2
|
-
import type { AllowanceScope } from "./allowance-copy.js";
|
|
3
|
-
/** One ceiling as a person reads it: how much of it is used, and when it resets. */
|
|
4
|
-
export type UsageReading = {
|
|
5
|
-
scope: AllowanceScope;
|
|
6
|
-
/** Used share of the ceiling. Can exceed 1 after post-call overshoot. */
|
|
7
|
-
fraction: number;
|
|
8
|
-
status: UsageAllowanceStatus;
|
|
9
|
-
resetsAt: string | null;
|
|
10
|
-
/** USD micros. Only shown when a host opts in with `formatAmount`. */
|
|
11
|
-
used: number;
|
|
12
|
-
limit: number;
|
|
13
|
-
remaining: number;
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* What a member can still do: `unlimited` when no ceiling applies, otherwise
|
|
17
|
-
* the state of whichever ceiling stops them first (`binding`).
|
|
18
|
-
*/
|
|
19
|
-
export type UsageSummary = {
|
|
20
|
-
state: "unlimited" | "ok" | "warning" | "exhausted";
|
|
21
|
-
/** The ceiling a person would ask to raise; null when unlimited. */
|
|
22
|
-
binding: UsageReading | null;
|
|
23
|
-
/** Their own ceiling, when one applies. */
|
|
24
|
-
member: UsageReading | null;
|
|
25
|
-
/** The shared workspace pool, when one is set. */
|
|
26
|
-
workspace: UsageReading | null;
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Fold a usage response (normally `/usage/me`) into what to tell one member.
|
|
30
|
-
* The server's `status` decides warning/exhausted (it applies the configured
|
|
31
|
-
* thresholds); when both ceilings apply, the one with less room left binds.
|
|
32
|
-
*/
|
|
33
|
-
export declare function summarizeUsage(usage: WorkspaceUsageResponse, subjectId?: string | undefined): UsageSummary;
|
|
34
|
-
/** A whole-number percentage for display: "<1" for a sliver, never "0" for some use. */
|
|
35
|
-
export declare function usagePercentLabel(fraction: number): string;
|
package/dist/usage.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export { useUsage } from "./hooks/use-usage.js";
|
|
2
|
-
export type { UsageClientLike, UseUsageOptions, UseUsageResult } from "./hooks/use-usage.js";
|
|
3
|
-
export { summarizeUsage, usagePercentLabel } from "./usage/summary.js";
|
|
4
|
-
export type { UsageReading, UsageSummary } from "./usage/summary.js";
|
|
5
|
-
export { DEFAULT_ALLOWANCE_LABELS, allowanceLabels, allowanceResetSentence, formatAllowanceDate, } from "./usage/allowance-copy.js";
|
|
6
|
-
export type { AllowanceLabels, AllowanceScope } from "./usage/allowance-copy.js";
|
|
7
|
-
export { DEFAULT_USAGE_METER_LABELS, UsageMeter, UsageMeterView } from "./components/usage-meter.js";
|
|
8
|
-
export type { UsageMeterBaseProps, UsageMeterLabels, UsageMeterProps, UsageMeterViewProps, } from "./components/usage-meter.js";
|
|
9
|
-
export { DEFAULT_USAGE_LIMIT_NOTICE_LABELS, UsageLimitNotice, UsageLimitNoticeView, } from "./components/usage-limit-notice.js";
|
|
10
|
-
export type { UsageLimitNoticeLabels, UsageLimitNoticeProps, } from "./components/usage-limit-notice.js";
|
|
11
|
-
export { DEFAULT_USAGE_MEMBER_LIST_LABELS, UsageMemberList, describeMemberLimit, } from "./components/usage-member-list.js";
|
|
12
|
-
export type { UsageAmountFormat, UsageMemberIdentity, UsageMemberListLabels, UsageMemberListProps, } from "./components/usage-member-list.js";
|
|
13
|
-
export type { RenderAllowanceExhausted } from "./timeline/allowance-exhausted-row.js";
|