@altertable/data-app 0.59.1 → 0.62.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/AGENTS.md +5 -3
- package/CONTRIBUTING.md +16 -4
- package/README.md +20 -14
- package/dist/chunks/{contract-jksbmt5q.js → contract-3bnrf5pf.js} +27 -5
- package/dist/chunks/contract-3bnrf5pf.js.map +10 -0
- package/dist/chunks/{contract-tkkc28tg.js → contract-4vrw9zk9.js} +43 -13
- package/dist/chunks/contract-4vrw9zk9.js.map +12 -0
- package/dist/chunks/{contract-14vxdcrs.js → contract-farfe948.js} +17 -21
- package/dist/chunks/contract-farfe948.js.map +10 -0
- package/dist/chunks/contract-nt819swq.js.map +1 -1
- package/dist/chunks/{contract-tqrf3ykr.js → contract-rrm7s5zp.js} +61 -32
- package/dist/chunks/contract-rrm7s5zp.js.map +12 -0
- package/dist/chunks/{contract-mb5nfzwg.js → contract-xjv197ck.js} +178 -31
- package/dist/chunks/contract-xjv197ck.js.map +13 -0
- package/dist/client/index.js +6 -4
- package/dist/client/index.js.map +1 -1
- package/dist/core/appearance.js +1 -1
- package/dist/core/contract.js +5 -3
- package/dist/core/contract.js.map +1 -1
- package/dist/embed/index.js +42 -8
- package/dist/embed/index.js.map +5 -4
- package/dist/local.js +191 -79
- package/dist/local.js.map +8 -7
- package/dist/react/embed/index.js +84 -99
- package/dist/react/embed/index.js.map +4 -5
- package/dist/react/index.css +156 -6
- package/dist/react/index.js +313 -152
- package/dist/react/index.js.map +17 -13
- package/dist/server.js +172 -76
- package/dist/server.js.map +7 -6
- package/dist/types/client/iframe.d.ts +14 -0
- package/dist/types/client/index.d.ts +19 -13
- package/dist/types/core/appearance.d.ts +7 -6
- package/dist/types/core/contract.d.ts +3 -3
- package/dist/types/core/messages.d.ts +9 -3
- package/dist/types/core/operation.d.ts +27 -0
- package/dist/types/core/presentation.d.ts +7 -0
- package/dist/types/embed/bridge.d.ts +12 -0
- package/dist/types/embed/host.d.ts +10 -3
- package/dist/types/embed/index.d.ts +7 -4
- package/dist/types/embed/{shell.d.ts → source.d.ts} +5 -4
- package/dist/types/embed/sql.d.ts +4 -0
- package/dist/types/react/embed/bridge.d.ts +19 -10
- package/dist/types/react/embed/index.d.ts +0 -2
- package/dist/types/react/ui/DataAppSkeleton.d.ts +8 -0
- package/dist/types/react/ui/SearchInput.d.ts +1 -1
- package/dist/types/react/ui/index.d.ts +2 -0
- package/dist/types/react/ui/useAppAppearance.d.ts +3 -0
- package/dist/types/react/ui/useDataAppPresentation.d.ts +3 -0
- package/dist/types/react/view-controls.d.ts +1 -1
- package/dist/{bootstrap.js → worker.js} +161 -29
- package/docs/app-authoring.md +24 -4
- package/docs/appearance.md +21 -8
- package/docs/client.md +40 -3
- package/docs/contract.md +9 -7
- package/docs/embed.md +114 -19
- package/docs/react-embed.md +84 -24
- package/docs/react.md +51 -0
- package/docs/releasing.md +5 -0
- package/docs/server-bun.md +5 -0
- package/docs/starter-agent-instructions.md +4 -2
- package/docs/worker.md +57 -0
- package/package.json +9 -5
- package/dist/chunks/contract-14vxdcrs.js.map +0 -10
- package/dist/chunks/contract-jksbmt5q.js.map +0 -10
- package/dist/chunks/contract-mb5nfzwg.js.map +0 -12
- package/dist/chunks/contract-tkkc28tg.js.map +0 -12
- package/dist/chunks/contract-tqrf3ykr.js.map +0 -11
- package/dist/types/embed/standalone.d.ts +0 -1
- package/dist/types/react/embed/shell.d.ts +0 -10
- package/docs/bootstrap.md +0 -76
package/dist/react/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import"../chunks/contract-
|
|
1
|
+
import"../chunks/contract-3bnrf5pf.js";
|
|
2
2
|
import {
|
|
3
|
-
DataAppError2
|
|
4
|
-
|
|
3
|
+
DataAppError2,
|
|
4
|
+
localFrameBridge,
|
|
5
|
+
getDataAppTransport2
|
|
6
|
+
} from "../chunks/contract-xjv197ck.js";
|
|
5
7
|
import {
|
|
6
8
|
getDataAppNavigation2,
|
|
7
9
|
createDataClient2
|
|
8
|
-
} from "../chunks/contract-
|
|
10
|
+
} from "../chunks/contract-4vrw9zk9.js";
|
|
9
11
|
import {
|
|
10
12
|
dataAppTitle2
|
|
11
13
|
} from "../chunks/contract-wz59z8pq.js";
|
|
@@ -17,8 +19,10 @@ import {
|
|
|
17
19
|
formatPercent2
|
|
18
20
|
} from "../chunks/contract-mev09s5v.js";
|
|
19
21
|
import {
|
|
22
|
+
parseAppearance2,
|
|
23
|
+
applyAppearance2,
|
|
20
24
|
createThemeController2
|
|
21
|
-
} from "../chunks/contract-
|
|
25
|
+
} from "../chunks/contract-farfe948.js";
|
|
22
26
|
import {
|
|
23
27
|
dimensionMemberKey,
|
|
24
28
|
dimensionFilter2,
|
|
@@ -756,6 +760,7 @@ function SearchInput({
|
|
|
756
760
|
endAction,
|
|
757
761
|
loading = false,
|
|
758
762
|
className,
|
|
763
|
+
onKeyDown,
|
|
759
764
|
...props
|
|
760
765
|
}) {
|
|
761
766
|
return /* @__PURE__ */ jsxs2("div", {
|
|
@@ -769,6 +774,15 @@ function SearchInput({
|
|
|
769
774
|
}),
|
|
770
775
|
/* @__PURE__ */ jsx3("input", {
|
|
771
776
|
...props,
|
|
777
|
+
onKeyDown: (event) => {
|
|
778
|
+
onKeyDown?.(event);
|
|
779
|
+
if (!event.defaultPrevented && event.key === "Escape" && !event.currentTarget.value) {
|
|
780
|
+
event.preventDefault();
|
|
781
|
+
event.stopPropagation();
|
|
782
|
+
event.currentTarget.blur();
|
|
783
|
+
event.currentTarget.closest('[role="dialog"]')?.focus();
|
|
784
|
+
}
|
|
785
|
+
},
|
|
772
786
|
type: "search",
|
|
773
787
|
className: classNames("altertable-search-input", className)
|
|
774
788
|
}),
|
|
@@ -1190,15 +1204,20 @@ function RequestHint({
|
|
|
1190
1204
|
"aria-atomic": "true",
|
|
1191
1205
|
children: active && /* @__PURE__ */ jsxs5(Fragment3, {
|
|
1192
1206
|
children: [
|
|
1193
|
-
/* @__PURE__ */
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1207
|
+
/* @__PURE__ */ jsxs5("span", {
|
|
1208
|
+
className: "altertable-request-hint-copy",
|
|
1209
|
+
children: [
|
|
1210
|
+
/* @__PURE__ */ jsx8(AppIcon, {
|
|
1211
|
+
name: status.kind === "error" ? "error" : "loading",
|
|
1212
|
+
size: 14,
|
|
1213
|
+
className: status.kind === "updating" ? "altertable-request-hint-spinner" : undefined
|
|
1214
|
+
}),
|
|
1215
|
+
/* @__PURE__ */ jsx8("span", {
|
|
1216
|
+
className: "altertable-request-hint-message",
|
|
1217
|
+
title: message,
|
|
1218
|
+
children: message
|
|
1219
|
+
})
|
|
1220
|
+
]
|
|
1202
1221
|
}),
|
|
1203
1222
|
status.kind === "error" && status.onRetry && /* @__PURE__ */ jsx8(Button, {
|
|
1204
1223
|
variant: "ghost",
|
|
@@ -2100,7 +2119,7 @@ function DimensionPicker({
|
|
|
2100
2119
|
|
|
2101
2120
|
// src/react/view-controls.tsx
|
|
2102
2121
|
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
2103
|
-
function useViewVariables(definitions, loadFacet) {
|
|
2122
|
+
function useViewVariables(definitions, clientScope, loadFacet) {
|
|
2104
2123
|
const variables = useAppVariables(definitions);
|
|
2105
2124
|
const resolved = {};
|
|
2106
2125
|
for (const name of Object.keys(definitions)) {
|
|
@@ -2114,7 +2133,13 @@ function useViewVariables(definitions, loadFacet) {
|
|
|
2114
2133
|
const facet = filter.facet;
|
|
2115
2134
|
const input = facet.input({ ...resolved, [name]: { kind: "all" } });
|
|
2116
2135
|
return {
|
|
2117
|
-
queryKey: [
|
|
2136
|
+
queryKey: [
|
|
2137
|
+
"dimension-facet",
|
|
2138
|
+
clientScope,
|
|
2139
|
+
name,
|
|
2140
|
+
facet.operation,
|
|
2141
|
+
input
|
|
2142
|
+
],
|
|
2118
2143
|
queryFn({ signal }) {
|
|
2119
2144
|
return loadFacet(facet.operation, input, signal).then((result) => parseFacetOptions2(result, filter));
|
|
2120
2145
|
},
|
|
@@ -2173,17 +2198,27 @@ function useViewVariables(definitions, loadFacet) {
|
|
|
2173
2198
|
}
|
|
2174
2199
|
|
|
2175
2200
|
// src/react/hooks.ts
|
|
2201
|
+
var clientScopes = new WeakMap;
|
|
2202
|
+
function getClientScope(client) {
|
|
2203
|
+
let scope = clientScopes.get(client);
|
|
2204
|
+
if (!scope) {
|
|
2205
|
+
scope = crypto.randomUUID();
|
|
2206
|
+
clientScopes.set(client, scope);
|
|
2207
|
+
}
|
|
2208
|
+
return scope;
|
|
2209
|
+
}
|
|
2176
2210
|
function createDataHooks(client) {
|
|
2211
|
+
const clientScope = getClientScope(client);
|
|
2177
2212
|
function useDataQuery(name, input, options) {
|
|
2178
2213
|
const queryClient = useQueryClient();
|
|
2179
|
-
const queryKey = ["data-operation", name, input];
|
|
2214
|
+
const queryKey = ["data-operation", clientScope, name, input];
|
|
2180
2215
|
const query = useQuery({
|
|
2181
2216
|
queryKey,
|
|
2182
2217
|
queryFn({ signal }) {
|
|
2183
2218
|
return client.query(name, input, { signal });
|
|
2184
2219
|
},
|
|
2185
2220
|
placeholderData(previousData, previousQuery) {
|
|
2186
|
-
return previousQuery?.queryKey[1] === name ? previousData : undefined;
|
|
2221
|
+
return previousQuery?.queryKey[1] === clientScope && previousQuery.queryKey[2] === name ? previousData : undefined;
|
|
2187
2222
|
},
|
|
2188
2223
|
enabled: options?.enabled,
|
|
2189
2224
|
...options?.staleTime !== undefined && { staleTime: options.staleTime },
|
|
@@ -2202,11 +2237,11 @@ function createDataHooks(client) {
|
|
|
2202
2237
|
function useDataView(name, input, options) {
|
|
2203
2238
|
const query = useDataQuery(name, input, options);
|
|
2204
2239
|
const [last, setLast] = useState6();
|
|
2205
|
-
if (query.isSuccess && !query.isPlaceholderData && query.data && (last?.name !== name || last.response !== query.data)) {
|
|
2206
|
-
setLast({ name, response: query.data });
|
|
2240
|
+
if (query.isSuccess && !query.isPlaceholderData && query.data && (last?.clientScope !== clientScope || last.name !== name || last.response !== query.data)) {
|
|
2241
|
+
setLast({ clientScope, name, response: query.data });
|
|
2207
2242
|
}
|
|
2208
2243
|
const sameInput = options.sameInput ?? ((left, right) => hashKey([left]) === hashKey([right]));
|
|
2209
|
-
const response = query.data ?? (last?.name === name ? last.response : undefined);
|
|
2244
|
+
const response = query.data ?? (last?.clientScope === clientScope && last.name === name ? last.response : undefined);
|
|
2210
2245
|
const snapshot = response && { data: response.data, input: response.input };
|
|
2211
2246
|
const view = resolveDataView({
|
|
2212
2247
|
requestedInput: input,
|
|
@@ -2272,7 +2307,7 @@ function createDataHooks(client) {
|
|
|
2272
2307
|
return dimensionFilter2(config);
|
|
2273
2308
|
}
|
|
2274
2309
|
function useView(definition) {
|
|
2275
|
-
const variables = useViewVariables(definition.variables, (operation, input, signal) => client.query(operation, input, {
|
|
2310
|
+
const variables = useViewVariables(definition.variables, clientScope, (operation, input, signal) => client.query(operation, input, {
|
|
2276
2311
|
signal
|
|
2277
2312
|
}).then((response) => response.data));
|
|
2278
2313
|
const request = useDataView(definition.operation, resolveViewInput(definition, variables.resolved), {
|
|
@@ -2300,18 +2335,66 @@ function createDataHooks(client) {
|
|
|
2300
2335
|
useView
|
|
2301
2336
|
};
|
|
2302
2337
|
}
|
|
2338
|
+
// src/react/ui/useDataAppPresentation.ts
|
|
2339
|
+
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
2340
|
+
|
|
2341
|
+
// src/core/presentation.ts
|
|
2342
|
+
function isDataAppPresentation(value) {
|
|
2343
|
+
if (!value || typeof value !== "object")
|
|
2344
|
+
return false;
|
|
2345
|
+
const presentation = value;
|
|
2346
|
+
return (presentation.surface === "embedded" || presentation.surface === "standalone") && (presentation.theme === "light" || presentation.theme === "dark");
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
// src/react/ui/useDataAppPresentation.ts
|
|
2350
|
+
function presentationFromBridgeState(state) {
|
|
2351
|
+
const presentation = state && typeof state === "object" ? state.presentation : undefined;
|
|
2352
|
+
return isDataAppPresentation(presentation) ? presentation : undefined;
|
|
2353
|
+
}
|
|
2354
|
+
function useDataAppPresentation() {
|
|
2355
|
+
const [presentation, setPresentation] = useState7(() => presentationFromBridgeState(getDataAppTransport2()?.snapshot()));
|
|
2356
|
+
useEffect5(() => {
|
|
2357
|
+
let disposed = false;
|
|
2358
|
+
let unsubscribe;
|
|
2359
|
+
function attach(bridge) {
|
|
2360
|
+
if (disposed)
|
|
2361
|
+
return;
|
|
2362
|
+
unsubscribe = bridge.subscribe((state) => setPresentation(presentationFromBridgeState(state)));
|
|
2363
|
+
setPresentation(presentationFromBridgeState(bridge.snapshot()));
|
|
2364
|
+
}
|
|
2365
|
+
const bridge = getDataAppTransport2();
|
|
2366
|
+
if (bridge)
|
|
2367
|
+
attach(bridge);
|
|
2368
|
+
else
|
|
2369
|
+
localFrameBridge()?.connect?.().then(attach).catch(() => {});
|
|
2370
|
+
return () => {
|
|
2371
|
+
disposed = true;
|
|
2372
|
+
unsubscribe?.();
|
|
2373
|
+
};
|
|
2374
|
+
}, []);
|
|
2375
|
+
return presentation;
|
|
2376
|
+
}
|
|
2377
|
+
|
|
2303
2378
|
// src/react/ui/DataApp.tsx
|
|
2304
|
-
import {
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2379
|
+
import { useEffect as useEffect14, useRef as useRef6 } from "react";
|
|
2380
|
+
|
|
2381
|
+
// src/react/ui/useAppAppearance.ts
|
|
2382
|
+
import { useLayoutEffect, useState as useState8, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
2383
|
+
function useAppAppearance(appearance, hostTheme) {
|
|
2384
|
+
const [controller] = useState8(() => createThemeController2(parseAppearance2(appearance).theme));
|
|
2385
|
+
const viewerPreference = useSyncExternalStore2(controller.subscribe, controller.getTheme, controller.getTheme);
|
|
2386
|
+
useLayoutEffect(() => applyAppearance2({
|
|
2387
|
+
...parseAppearance2(appearance),
|
|
2388
|
+
theme: hostTheme ?? viewerPreference
|
|
2389
|
+
}), [appearance, hostTheme, viewerPreference]);
|
|
2390
|
+
return hostTheme ? undefined : controller;
|
|
2391
|
+
}
|
|
2309
2392
|
|
|
2310
2393
|
// src/react/ui/AboutData.tsx
|
|
2311
2394
|
import {
|
|
2312
|
-
useEffect as
|
|
2395
|
+
useEffect as useEffect10,
|
|
2313
2396
|
useRef as useRef4,
|
|
2314
|
-
useState as
|
|
2397
|
+
useState as useState11
|
|
2315
2398
|
} from "react";
|
|
2316
2399
|
import { useMergeRefs as useMergeRefs4 } from "@floating-ui/react";
|
|
2317
2400
|
|
|
@@ -2344,7 +2427,7 @@ function EmptyState({
|
|
|
2344
2427
|
}
|
|
2345
2428
|
|
|
2346
2429
|
// src/react/ui/shortcuts.ts
|
|
2347
|
-
import { useEffect as
|
|
2430
|
+
import { useEffect as useEffect6 } from "react";
|
|
2348
2431
|
var shortcuts = {
|
|
2349
2432
|
refresh: { modifier: "alt", code: "KeyR", key: "R" },
|
|
2350
2433
|
aboutData: { modifier: "alt", code: "KeyI", key: "I" },
|
|
@@ -2372,7 +2455,7 @@ function isEditingTarget(target) {
|
|
|
2372
2455
|
}
|
|
2373
2456
|
function useShortcut(shortcut, action, enabled = true) {
|
|
2374
2457
|
const { modifier, shift = false, code } = shortcut;
|
|
2375
|
-
|
|
2458
|
+
useEffect6(() => {
|
|
2376
2459
|
if (!enabled)
|
|
2377
2460
|
return;
|
|
2378
2461
|
function onKeyDown(event) {
|
|
@@ -2406,8 +2489,8 @@ function Kbd({ shortcut, children, className, ...props }) {
|
|
|
2406
2489
|
|
|
2407
2490
|
// src/react/ui/QueryList.tsx
|
|
2408
2491
|
import {
|
|
2409
|
-
useEffect as
|
|
2410
|
-
useState as
|
|
2492
|
+
useEffect as useEffect7,
|
|
2493
|
+
useState as useState9
|
|
2411
2494
|
} from "react";
|
|
2412
2495
|
import { jsx as jsx19, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2413
2496
|
var KEYWORD = /\b(WITH|SELECT|FROM|WHERE|AND|OR|NOT|IN|AS|ON|JOIN|LEFT|RIGHT|INNER|FULL|OUTER|CROSS|GROUP BY|ORDER BY|HAVING|LIMIT|UNION|ALL|DISTINCT|CASE|WHEN|THEN|ELSE|END|NULL|TRUE|FALSE|BETWEEN|LIKE|ILIKE|EXISTS|VALUES|CAST|COUNT|SUM|AVG|MIN|MAX|QUALIFY|WINDOW|OVER|PARTITION|BY)\b/gi;
|
|
@@ -2425,8 +2508,8 @@ function SqlCode({ statement }) {
|
|
|
2425
2508
|
});
|
|
2426
2509
|
}
|
|
2427
2510
|
function QueryFigure({ name, statement }) {
|
|
2428
|
-
const [copyState, setCopyState] =
|
|
2429
|
-
|
|
2511
|
+
const [copyState, setCopyState] = useState9("idle");
|
|
2512
|
+
useEffect7(() => {
|
|
2430
2513
|
if (copyState === "idle")
|
|
2431
2514
|
return;
|
|
2432
2515
|
const timer = window.setTimeout(() => setCopyState("idle"), 1500);
|
|
@@ -2482,8 +2565,8 @@ function QueryNotebook({
|
|
|
2482
2565
|
queries,
|
|
2483
2566
|
className
|
|
2484
2567
|
}) {
|
|
2485
|
-
const [copyState, setCopyState] =
|
|
2486
|
-
|
|
2568
|
+
const [copyState, setCopyState] = useState9("idle");
|
|
2569
|
+
useEffect7(() => {
|
|
2487
2570
|
if (copyState === "idle")
|
|
2488
2571
|
return;
|
|
2489
2572
|
const timer = window.setTimeout(() => setCopyState("idle"), 1500);
|
|
@@ -2585,7 +2668,7 @@ function QueryList({
|
|
|
2585
2668
|
|
|
2586
2669
|
// src/react/ui/Sheet.tsx
|
|
2587
2670
|
import {
|
|
2588
|
-
useEffect as
|
|
2671
|
+
useEffect as useEffect8,
|
|
2589
2672
|
useId as useId5,
|
|
2590
2673
|
useRef as useRef3
|
|
2591
2674
|
} from "react";
|
|
@@ -2614,7 +2697,7 @@ function Sheet({
|
|
|
2614
2697
|
const titleId = useId5();
|
|
2615
2698
|
const descriptionId = useId5();
|
|
2616
2699
|
const dialogRef = useMergeRefs3([dialog, ref]);
|
|
2617
|
-
|
|
2700
|
+
useEffect8(() => {
|
|
2618
2701
|
const element = dialog.current;
|
|
2619
2702
|
if (!element)
|
|
2620
2703
|
return;
|
|
@@ -2728,7 +2811,7 @@ function Sheet({
|
|
|
2728
2811
|
}
|
|
2729
2812
|
|
|
2730
2813
|
// src/react/ui/Tabs.tsx
|
|
2731
|
-
import { useCallback as useCallback2, useEffect as
|
|
2814
|
+
import { useCallback as useCallback2, useEffect as useEffect9, useState as useState10 } from "react";
|
|
2732
2815
|
import {
|
|
2733
2816
|
Tabs,
|
|
2734
2817
|
TabList,
|
|
@@ -2741,8 +2824,8 @@ function useViewTab(views, fallback) {
|
|
|
2741
2824
|
const requested = searchParams().get("view");
|
|
2742
2825
|
return views.includes(requested) ? requested : fallback;
|
|
2743
2826
|
}, [views, fallback]);
|
|
2744
|
-
const [selected, setSelected] =
|
|
2745
|
-
|
|
2827
|
+
const [selected, setSelected] = useState10(currentView);
|
|
2828
|
+
useEffect9(() => {
|
|
2746
2829
|
function sync() {
|
|
2747
2830
|
const view = currentView();
|
|
2748
2831
|
setSelected(view);
|
|
@@ -2871,8 +2954,8 @@ function AboutData({
|
|
|
2871
2954
|
const hasQueries = (resolvedQueries ?? []).some((query) => !names || names.includes(query.name));
|
|
2872
2955
|
const sheetId = subjectId(subject);
|
|
2873
2956
|
const initialTab = resolveTab(tab ?? searchParams().get("tab"));
|
|
2874
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
2875
|
-
const [selectedTab, setSelectedTab] =
|
|
2957
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState11(() => searchParams().get("about") === sheetId);
|
|
2958
|
+
const [selectedTab, setSelectedTab] = useState11(initialTab);
|
|
2876
2959
|
const open = openProp ?? uncontrolledOpen;
|
|
2877
2960
|
const triggerRef = useRef4(null);
|
|
2878
2961
|
const mergedTrigger = useMergeRefs4([triggerRef, ref]);
|
|
@@ -2902,7 +2985,7 @@ function AboutData({
|
|
|
2902
2985
|
if (open)
|
|
2903
2986
|
writeSearch({ about: sheetId, tab: id });
|
|
2904
2987
|
}
|
|
2905
|
-
|
|
2988
|
+
useEffect10(() => {
|
|
2906
2989
|
function sync() {
|
|
2907
2990
|
const about = searchParams().get("about");
|
|
2908
2991
|
const urlTab = searchParams().get("tab");
|
|
@@ -3331,11 +3414,11 @@ function LiveControl({
|
|
|
3331
3414
|
|
|
3332
3415
|
// src/react/ui/PresentStory.tsx
|
|
3333
3416
|
import {
|
|
3334
|
-
useEffect as
|
|
3417
|
+
useEffect as useEffect11,
|
|
3335
3418
|
useEffectEvent as useEffectEvent2,
|
|
3336
3419
|
useId as useId7,
|
|
3337
3420
|
useRef as useRef5,
|
|
3338
|
-
useState as
|
|
3421
|
+
useState as useState12
|
|
3339
3422
|
} from "react";
|
|
3340
3423
|
import { useMergeRefs as useMergeRefs5 } from "@floating-ui/react";
|
|
3341
3424
|
|
|
@@ -3343,10 +3426,10 @@ import { useMergeRefs as useMergeRefs5 } from "@floating-ui/react";
|
|
|
3343
3426
|
import {
|
|
3344
3427
|
useCallback as useCallback3,
|
|
3345
3428
|
useId as useId6,
|
|
3346
|
-
useSyncExternalStore as
|
|
3429
|
+
useSyncExternalStore as useSyncExternalStore3
|
|
3347
3430
|
} from "react";
|
|
3348
3431
|
import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3349
|
-
var
|
|
3432
|
+
var themes = [
|
|
3350
3433
|
{ value: "light", label: "Light", icon: "lightTheme" },
|
|
3351
3434
|
{ value: "dark", label: "Dark", icon: "darkTheme" }
|
|
3352
3435
|
];
|
|
@@ -3361,10 +3444,10 @@ function useResolvedTheme(theme) {
|
|
|
3361
3444
|
};
|
|
3362
3445
|
}, [theme]);
|
|
3363
3446
|
const snapshot = useCallback3(() => {
|
|
3364
|
-
const
|
|
3365
|
-
return
|
|
3447
|
+
const preference = theme.getTheme();
|
|
3448
|
+
return preference === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : preference;
|
|
3366
3449
|
}, [theme]);
|
|
3367
|
-
return
|
|
3450
|
+
return useSyncExternalStore3(subscribe, snapshot, () => "light");
|
|
3368
3451
|
}
|
|
3369
3452
|
function ThemeSelector({
|
|
3370
3453
|
theme,
|
|
@@ -3382,7 +3465,7 @@ function ThemeSelector({
|
|
|
3382
3465
|
className: "altertable-theme-legend",
|
|
3383
3466
|
children: "Color theme"
|
|
3384
3467
|
}),
|
|
3385
|
-
|
|
3468
|
+
themes.map(({ value, label, icon }) => /* @__PURE__ */ jsx29(Tooltip, {
|
|
3386
3469
|
content: `${label} theme`,
|
|
3387
3470
|
children: /* @__PURE__ */ jsxs20("label", {
|
|
3388
3471
|
children: [
|
|
@@ -3392,7 +3475,7 @@ function ThemeSelector({
|
|
|
3392
3475
|
value,
|
|
3393
3476
|
checked: selected === value,
|
|
3394
3477
|
"aria-label": `${label} theme`,
|
|
3395
|
-
onChange: () => theme.
|
|
3478
|
+
onChange: () => theme.setTheme(value)
|
|
3396
3479
|
}),
|
|
3397
3480
|
/* @__PURE__ */ jsx29(AppIcon, {
|
|
3398
3481
|
name: icon,
|
|
@@ -3417,7 +3500,7 @@ function ThemeToggle({
|
|
|
3417
3500
|
variant: "ghost",
|
|
3418
3501
|
label: `Switch to ${next} theme`,
|
|
3419
3502
|
portalRoot,
|
|
3420
|
-
onClick: () => theme.
|
|
3503
|
+
onClick: () => theme.setTheme(next)
|
|
3421
3504
|
});
|
|
3422
3505
|
}
|
|
3423
3506
|
|
|
@@ -3494,7 +3577,7 @@ function PresentStory({
|
|
|
3494
3577
|
const headline = useRef5(null);
|
|
3495
3578
|
const headlineId = useId7();
|
|
3496
3579
|
const contextId = useId7();
|
|
3497
|
-
const [stepId, setStepId] =
|
|
3580
|
+
const [stepId, setStepId] = useState12(steps[0]?.id);
|
|
3498
3581
|
const triggerRef = useMergeRefs5([trigger, ref]);
|
|
3499
3582
|
const dialogRef = useMergeRefs5([dialog, dialogProps?.ref]);
|
|
3500
3583
|
const index = Math.max(0, steps.findIndex((step) => step.id === stepId));
|
|
@@ -3502,7 +3585,7 @@ function PresentStory({
|
|
|
3502
3585
|
const stepIds = steps.map((item) => item.id).join("\x00");
|
|
3503
3586
|
const unavailable = !steps.length || !!disabled;
|
|
3504
3587
|
const currentSteps = useEffectEvent2(() => steps);
|
|
3505
|
-
|
|
3588
|
+
useEffect11(() => {
|
|
3506
3589
|
function syncFromUrl() {
|
|
3507
3590
|
const params = searchParams();
|
|
3508
3591
|
const availableSteps = currentSteps();
|
|
@@ -3518,7 +3601,7 @@ function PresentStory({
|
|
|
3518
3601
|
syncFromUrl();
|
|
3519
3602
|
return subscribeSearch(syncFromUrl);
|
|
3520
3603
|
}, [stepIds]);
|
|
3521
|
-
|
|
3604
|
+
useEffect11(() => {
|
|
3522
3605
|
if (dialog.current?.open)
|
|
3523
3606
|
headline.current?.focus({ preventScroll: true });
|
|
3524
3607
|
}, [stepId]);
|
|
@@ -3754,8 +3837,8 @@ function PresentStory({
|
|
|
3754
3837
|
|
|
3755
3838
|
// src/react/ui/RefreshControl.tsx
|
|
3756
3839
|
import {
|
|
3757
|
-
useEffect as
|
|
3758
|
-
useState as
|
|
3840
|
+
useEffect as useEffect12,
|
|
3841
|
+
useState as useState13
|
|
3759
3842
|
} from "react";
|
|
3760
3843
|
import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3761
3844
|
function RefreshControl({
|
|
@@ -3767,13 +3850,13 @@ function RefreshControl({
|
|
|
3767
3850
|
className,
|
|
3768
3851
|
...props
|
|
3769
3852
|
}) {
|
|
3770
|
-
const [refreshDelay, setRefreshDelay] =
|
|
3853
|
+
const [refreshDelay, setRefreshDelay] = useState13({
|
|
3771
3854
|
refreshing,
|
|
3772
3855
|
elapsed: false
|
|
3773
3856
|
});
|
|
3774
3857
|
if (refreshDelay.refreshing !== refreshing)
|
|
3775
3858
|
setRefreshDelay({ refreshing, elapsed: false });
|
|
3776
|
-
|
|
3859
|
+
useEffect12(() => {
|
|
3777
3860
|
if (!refreshing)
|
|
3778
3861
|
return;
|
|
3779
3862
|
const timer = window.setTimeout(() => setRefreshDelay({ refreshing: true, elapsed: true }), 300);
|
|
@@ -3910,7 +3993,7 @@ function VariableBar({
|
|
|
3910
3993
|
}
|
|
3911
3994
|
|
|
3912
3995
|
// src/react/ui/DataViewToast.tsx
|
|
3913
|
-
import { useEffect as
|
|
3996
|
+
import { useEffect as useEffect13, useState as useState14 } from "react";
|
|
3914
3997
|
import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
3915
3998
|
function DataViewToast({
|
|
3916
3999
|
view,
|
|
@@ -3918,10 +4001,10 @@ function DataViewToast({
|
|
|
3918
4001
|
notice,
|
|
3919
4002
|
onRetry
|
|
3920
4003
|
}) {
|
|
3921
|
-
const [delay, setDelay] =
|
|
4004
|
+
const [delay, setDelay] = useState14({ kind: view.kind, elapsed: false });
|
|
3922
4005
|
if (delay.kind !== view.kind)
|
|
3923
4006
|
setDelay({ kind: view.kind, elapsed: false });
|
|
3924
|
-
|
|
4007
|
+
useEffect13(() => {
|
|
3925
4008
|
if (view.kind !== "updating" && view.kind !== "stale-error")
|
|
3926
4009
|
return;
|
|
3927
4010
|
const kind = view.kind;
|
|
@@ -4216,9 +4299,11 @@ function DataApp(props) {
|
|
|
4216
4299
|
footerActions,
|
|
4217
4300
|
layoutProps
|
|
4218
4301
|
} = props;
|
|
4219
|
-
const
|
|
4302
|
+
const presentation = useDataAppPresentation();
|
|
4303
|
+
const isEmbedded = presentation?.surface === "embedded";
|
|
4304
|
+
const themeController = useAppAppearance(config.appearance, presentation?.theme);
|
|
4220
4305
|
const bodyRef = useRef6(null);
|
|
4221
|
-
|
|
4306
|
+
useEffect14(() => {
|
|
4222
4307
|
if (import.meta.env?.DEV && bodyRef.current?.querySelector("h1"))
|
|
4223
4308
|
console.warn("DataApp owns the page title. Use section headings (h2) in its body.");
|
|
4224
4309
|
});
|
|
@@ -4228,6 +4313,28 @@ function DataApp(props) {
|
|
|
4228
4313
|
organization: scopeLabels?.organization ?? config.scope.organization,
|
|
4229
4314
|
environment: scopeLabels?.environment ?? config.scope.environment
|
|
4230
4315
|
});
|
|
4316
|
+
const toolbar = /* @__PURE__ */ jsx39(AppToolbar, {
|
|
4317
|
+
requestState: request?.view.kind,
|
|
4318
|
+
refresh: refresh ?? request?.refresh,
|
|
4319
|
+
story: story && {
|
|
4320
|
+
...story,
|
|
4321
|
+
title: config.title,
|
|
4322
|
+
scope,
|
|
4323
|
+
dataContext,
|
|
4324
|
+
empty: aboutEmpty,
|
|
4325
|
+
theme: themeController
|
|
4326
|
+
},
|
|
4327
|
+
aboutData: /* @__PURE__ */ jsx39(AboutData, {
|
|
4328
|
+
id: "data",
|
|
4329
|
+
shortcut: true,
|
|
4330
|
+
dataContext,
|
|
4331
|
+
empty: aboutEmpty,
|
|
4332
|
+
queries: queries ?? request?.queries,
|
|
4333
|
+
iconOnly: true,
|
|
4334
|
+
variant: "elevated"
|
|
4335
|
+
}),
|
|
4336
|
+
children: toolbarActions
|
|
4337
|
+
});
|
|
4231
4338
|
return /* @__PURE__ */ jsx39(InspectionContext, {
|
|
4232
4339
|
value: {
|
|
4233
4340
|
dataContext,
|
|
@@ -4236,36 +4343,16 @@ function DataApp(props) {
|
|
|
4236
4343
|
},
|
|
4237
4344
|
children: /* @__PURE__ */ jsxs28(AppLayout, {
|
|
4238
4345
|
...layoutProps,
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4346
|
+
footer: isEmbedded ? null : layoutProps?.footer,
|
|
4347
|
+
footerActions: footerActions ?? (themeController && /* @__PURE__ */ jsx39(ThemeToggle, {
|
|
4348
|
+
theme: themeController
|
|
4349
|
+
})),
|
|
4242
4350
|
children: [
|
|
4243
|
-
/* @__PURE__ */ jsx39(AppHeader, {
|
|
4351
|
+
isEmbedded ? toolbar : /* @__PURE__ */ jsx39(AppHeader, {
|
|
4244
4352
|
scope,
|
|
4245
4353
|
title: config.title,
|
|
4246
4354
|
description,
|
|
4247
|
-
toolbar
|
|
4248
|
-
requestState: request?.view.kind,
|
|
4249
|
-
refresh: refresh ?? request?.refresh,
|
|
4250
|
-
story: story && {
|
|
4251
|
-
...story,
|
|
4252
|
-
title: config.title,
|
|
4253
|
-
scope,
|
|
4254
|
-
dataContext,
|
|
4255
|
-
empty: aboutEmpty,
|
|
4256
|
-
theme
|
|
4257
|
-
},
|
|
4258
|
-
aboutData: /* @__PURE__ */ jsx39(AboutData, {
|
|
4259
|
-
id: "data",
|
|
4260
|
-
shortcut: true,
|
|
4261
|
-
dataContext,
|
|
4262
|
-
empty: aboutEmpty,
|
|
4263
|
-
queries: queries ?? request?.queries,
|
|
4264
|
-
iconOnly: true,
|
|
4265
|
-
variant: "elevated"
|
|
4266
|
-
}),
|
|
4267
|
-
children: toolbarActions
|
|
4268
|
-
})
|
|
4355
|
+
toolbar
|
|
4269
4356
|
}),
|
|
4270
4357
|
(request?.controls ?? props.variables) && /* @__PURE__ */ jsx39(VariableBar, {
|
|
4271
4358
|
children: request?.controls ?? props.variables
|
|
@@ -4514,21 +4601,20 @@ function DataWidgetContent({
|
|
|
4514
4601
|
}) : children;
|
|
4515
4602
|
const visual = /* @__PURE__ */ jsx44(WidgetContent, {
|
|
4516
4603
|
bodyPadding: empty ? "flush" : bodyPadding,
|
|
4517
|
-
footer,
|
|
4604
|
+
footer: empty ? undefined : footer,
|
|
4518
4605
|
status,
|
|
4519
4606
|
children: content
|
|
4520
4607
|
});
|
|
4521
|
-
const help = evidence && /* @__PURE__ */
|
|
4522
|
-
...evidence,
|
|
4608
|
+
const help = evidence && /* @__PURE__ */ jsxs30(AboutData, {
|
|
4523
4609
|
id: evidence.id,
|
|
4524
4610
|
references: {
|
|
4525
4611
|
kind: "ids",
|
|
4526
4612
|
glossaryIds: evidence.glossaryIds,
|
|
4527
4613
|
queryNames: evidence.queryNames
|
|
4528
4614
|
},
|
|
4529
|
-
|
|
4615
|
+
"aria-label": typeof title === "string" ? `Explore ${title}` : "Explore this widget",
|
|
4530
4616
|
variant: "ghost",
|
|
4531
|
-
className: "altertable-
|
|
4617
|
+
className: "altertable-widget-heading-trigger",
|
|
4532
4618
|
tooltip: "Explore this widget",
|
|
4533
4619
|
shortcut: false,
|
|
4534
4620
|
title,
|
|
@@ -4538,9 +4624,12 @@ function DataWidgetContent({
|
|
|
4538
4624
|
description,
|
|
4539
4625
|
visual,
|
|
4540
4626
|
visualKind: "widget",
|
|
4541
|
-
children:
|
|
4542
|
-
|
|
4543
|
-
|
|
4627
|
+
children: [
|
|
4628
|
+
title,
|
|
4629
|
+
/* @__PURE__ */ jsx44(AppIcon, {
|
|
4630
|
+
name: "openDetails"
|
|
4631
|
+
})
|
|
4632
|
+
]
|
|
4544
4633
|
});
|
|
4545
4634
|
return /* @__PURE__ */ jsxs30("section", {
|
|
4546
4635
|
...props,
|
|
@@ -4554,8 +4643,9 @@ function DataWidgetContent({
|
|
|
4554
4643
|
children: [
|
|
4555
4644
|
/* @__PURE__ */ jsxs30("h2", {
|
|
4556
4645
|
id: titleId,
|
|
4646
|
+
"aria-label": typeof title === "string" ? title : undefined,
|
|
4557
4647
|
children: [
|
|
4558
|
-
title,
|
|
4648
|
+
help ?? title,
|
|
4559
4649
|
count !== undefined && /* @__PURE__ */ jsx44("span", {
|
|
4560
4650
|
className: "altertable-data-widget-count",
|
|
4561
4651
|
children: formatCount2(count)
|
|
@@ -4573,8 +4663,7 @@ function DataWidgetContent({
|
|
|
4573
4663
|
/* @__PURE__ */ jsx44(WidgetStatusControl, {
|
|
4574
4664
|
status
|
|
4575
4665
|
}),
|
|
4576
|
-
action
|
|
4577
|
-
help
|
|
4666
|
+
action
|
|
4578
4667
|
]
|
|
4579
4668
|
})
|
|
4580
4669
|
]
|
|
@@ -4605,7 +4694,7 @@ function WidgetContent({
|
|
|
4605
4694
|
});
|
|
4606
4695
|
}
|
|
4607
4696
|
// src/react/ui/VisualizationWidget.tsx
|
|
4608
|
-
import { useState as
|
|
4697
|
+
import { useState as useState15 } from "react";
|
|
4609
4698
|
|
|
4610
4699
|
// src/react/ui/widget-views.ts
|
|
4611
4700
|
function validateWidgetViews(views, selected) {
|
|
@@ -4700,7 +4789,7 @@ function VisualizationWidgetWithViews({
|
|
|
4700
4789
|
insight,
|
|
4701
4790
|
...shell
|
|
4702
4791
|
}) {
|
|
4703
|
-
const [selected, setSelected] =
|
|
4792
|
+
const [selected, setSelected] = useState15(initialView ?? views[0]?.id ?? "");
|
|
4704
4793
|
validateWidgetViews(views, selected);
|
|
4705
4794
|
return /* @__PURE__ */ jsx46(DataWidget, {
|
|
4706
4795
|
...shell,
|
|
@@ -4727,14 +4816,14 @@ function VisualizationWidgetWithViews({
|
|
|
4727
4816
|
});
|
|
4728
4817
|
}
|
|
4729
4818
|
// src/react/ui/TableWidget.tsx
|
|
4730
|
-
import { useState as
|
|
4819
|
+
import { useState as useState18 } from "react";
|
|
4731
4820
|
|
|
4732
4821
|
// src/react/ui/DateTimeTooltip.tsx
|
|
4733
|
-
import { useEffect as
|
|
4822
|
+
import { useEffect as useEffect15, useState as useState17 } from "react";
|
|
4734
4823
|
|
|
4735
4824
|
// src/react/ui/HelpPopover.tsx
|
|
4736
4825
|
import {
|
|
4737
|
-
useState as
|
|
4826
|
+
useState as useState16
|
|
4738
4827
|
} from "react";
|
|
4739
4828
|
import {
|
|
4740
4829
|
autoUpdate as autoUpdate2,
|
|
@@ -4767,8 +4856,8 @@ function HelpPopover({
|
|
|
4767
4856
|
open: openProp,
|
|
4768
4857
|
onOpenChange
|
|
4769
4858
|
}) {
|
|
4770
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
4771
|
-
const [dialogRoot, setDialogRoot] =
|
|
4859
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState16(false);
|
|
4860
|
+
const [dialogRoot, setDialogRoot] = useState16(null);
|
|
4772
4861
|
const open = openProp ?? uncontrolledOpen;
|
|
4773
4862
|
function setOpen(next) {
|
|
4774
4863
|
onOpenChange?.(next);
|
|
@@ -4857,8 +4946,8 @@ function DateTimeTooltip({
|
|
|
4857
4946
|
panelClassName,
|
|
4858
4947
|
...props
|
|
4859
4948
|
}) {
|
|
4860
|
-
const [now, setNow] =
|
|
4861
|
-
|
|
4949
|
+
const [now, setNow] = useState17(Date.now);
|
|
4950
|
+
useEffect15(() => {
|
|
4862
4951
|
const interval = window.setInterval(() => setNow(Date.now()), 30000);
|
|
4863
4952
|
return () => window.clearInterval(interval);
|
|
4864
4953
|
}, []);
|
|
@@ -5058,7 +5147,7 @@ function TableWidgetContent({
|
|
|
5058
5147
|
invariant(keys.every((key) => typeof key === "string" ? !!key.trim() : Number.isFinite(key)) && new Set(keys.map(String)).size === keys.length, "TableWidget row keys must be nonempty and unique.");
|
|
5059
5148
|
const rowKeys = JSON.stringify(keys);
|
|
5060
5149
|
const pageSize = pagination === false || limit !== undefined ? null : pagination?.pageSize ?? 10;
|
|
5061
|
-
const [pageState, setPageState] =
|
|
5150
|
+
const [pageState, setPageState] = useState18({
|
|
5062
5151
|
page: 0,
|
|
5063
5152
|
rowKeys,
|
|
5064
5153
|
searchValue: search?.value,
|
|
@@ -5115,7 +5204,7 @@ function TableWidgetContent({
|
|
|
5115
5204
|
]
|
|
5116
5205
|
})
|
|
5117
5206
|
});
|
|
5118
|
-
const pager = pageSize &&
|
|
5207
|
+
const pager = pageSize && pageCount > 1 && /* @__PURE__ */ jsxs35("nav", {
|
|
5119
5208
|
className: "altertable-table-pagination",
|
|
5120
5209
|
"aria-label": "Table pages",
|
|
5121
5210
|
children: [
|
|
@@ -5587,11 +5676,10 @@ function MetricWidgetContent({
|
|
|
5587
5676
|
const feedback = /* @__PURE__ */ jsx55(WidgetStatusControl, {
|
|
5588
5677
|
status
|
|
5589
5678
|
});
|
|
5590
|
-
const help = evidence ? /* @__PURE__ */
|
|
5591
|
-
|
|
5592
|
-
iconOnly: true,
|
|
5679
|
+
const help = evidence ? /* @__PURE__ */ jsxs40(AboutData, {
|
|
5680
|
+
"aria-label": `Explore ${label}`,
|
|
5593
5681
|
variant: "ghost",
|
|
5594
|
-
className: "altertable-
|
|
5682
|
+
className: "altertable-widget-heading-trigger",
|
|
5595
5683
|
tooltip: "Explore this metric",
|
|
5596
5684
|
references: {
|
|
5597
5685
|
kind: "ids",
|
|
@@ -5611,9 +5699,12 @@ function MetricWidgetContent({
|
|
|
5611
5699
|
]
|
|
5612
5700
|
}),
|
|
5613
5701
|
visualKind: "metric",
|
|
5614
|
-
children:
|
|
5615
|
-
|
|
5616
|
-
|
|
5702
|
+
children: [
|
|
5703
|
+
label,
|
|
5704
|
+
/* @__PURE__ */ jsx55(AppIcon, {
|
|
5705
|
+
name: "openDetails"
|
|
5706
|
+
})
|
|
5707
|
+
]
|
|
5617
5708
|
}) : null;
|
|
5618
5709
|
return /* @__PURE__ */ jsxs40("div", {
|
|
5619
5710
|
...props,
|
|
@@ -5623,14 +5714,13 @@ function MetricWidgetContent({
|
|
|
5623
5714
|
className: "altertable-metric-label",
|
|
5624
5715
|
children: [
|
|
5625
5716
|
/* @__PURE__ */ jsx55("span", {
|
|
5626
|
-
children: label
|
|
5717
|
+
children: help ?? label
|
|
5627
5718
|
}),
|
|
5628
5719
|
/* @__PURE__ */ jsxs40("div", {
|
|
5629
5720
|
className: "altertable-metric-help",
|
|
5630
5721
|
children: [
|
|
5631
5722
|
feedback,
|
|
5632
|
-
action
|
|
5633
|
-
help
|
|
5723
|
+
action
|
|
5634
5724
|
]
|
|
5635
5725
|
})
|
|
5636
5726
|
]
|
|
@@ -5649,7 +5739,7 @@ function MetricWidgetContent({
|
|
|
5649
5739
|
});
|
|
5650
5740
|
}
|
|
5651
5741
|
// src/react/ui/SelectableBarChart.tsx
|
|
5652
|
-
import { useLayoutEffect, useRef as useRef7, useState as
|
|
5742
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef7, useState as useState19 } from "react";
|
|
5653
5743
|
import { jsx as jsx56, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
5654
5744
|
function SelectableBarChart({
|
|
5655
5745
|
items,
|
|
@@ -5659,10 +5749,10 @@ function SelectableBarChart({
|
|
|
5659
5749
|
ariaLabel,
|
|
5660
5750
|
formatValue = (value) => new Intl.NumberFormat().format(value)
|
|
5661
5751
|
}) {
|
|
5662
|
-
const [previewId, setPreviewId] =
|
|
5752
|
+
const [previewId, setPreviewId] = useState19(null);
|
|
5663
5753
|
const scrollport = useRef7(null);
|
|
5664
5754
|
const buttons = useRef7([]);
|
|
5665
|
-
|
|
5755
|
+
useLayoutEffect2(() => {
|
|
5666
5756
|
const element = scrollport.current;
|
|
5667
5757
|
if (element)
|
|
5668
5758
|
element.scrollLeft = element.scrollWidth - element.clientWidth;
|
|
@@ -5747,15 +5837,85 @@ function SelectableBarChart({
|
|
|
5747
5837
|
]
|
|
5748
5838
|
}, item.id))
|
|
5749
5839
|
}),
|
|
5750
|
-
/* @__PURE__ */ jsx56("p", {
|
|
5840
|
+
items.length > 0 && /* @__PURE__ */ jsx56("p", {
|
|
5751
5841
|
className: "altertable-selectable-bars-help",
|
|
5752
5842
|
children: "Select a bar to inspect its day. Use arrow keys to move; press Escape to clear."
|
|
5753
5843
|
})
|
|
5754
5844
|
]
|
|
5755
5845
|
});
|
|
5756
5846
|
}
|
|
5847
|
+
// src/react/ui/DataAppSkeleton.tsx
|
|
5848
|
+
import { jsx as jsx57, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
5849
|
+
var chartHeights = [40, 60, 50, 80, 60, 100, 80, 60];
|
|
5850
|
+
function DataAppSkeleton({
|
|
5851
|
+
header,
|
|
5852
|
+
footer,
|
|
5853
|
+
className,
|
|
5854
|
+
...props
|
|
5855
|
+
}) {
|
|
5856
|
+
return /* @__PURE__ */ jsx57("output", {
|
|
5857
|
+
"aria-label": "Loading data app",
|
|
5858
|
+
...props,
|
|
5859
|
+
"aria-busy": "true",
|
|
5860
|
+
className: classNames("altertable-data-app-skeleton", className),
|
|
5861
|
+
children: /* @__PURE__ */ jsxs42("div", {
|
|
5862
|
+
className: "altertable-data-app-skeleton-content",
|
|
5863
|
+
children: [
|
|
5864
|
+
header != null && header !== false && /* @__PURE__ */ jsx57("div", {
|
|
5865
|
+
className: "altertable-data-app-skeleton-header",
|
|
5866
|
+
children: header
|
|
5867
|
+
}),
|
|
5868
|
+
/* @__PURE__ */ jsxs42("div", {
|
|
5869
|
+
className: "altertable-data-app-skeleton-body",
|
|
5870
|
+
"aria-hidden": "true",
|
|
5871
|
+
children: [
|
|
5872
|
+
/* @__PURE__ */ jsx57(Grid, {
|
|
5873
|
+
columns: 3,
|
|
5874
|
+
gap: "md",
|
|
5875
|
+
children: [0, 1, 2].map((item) => /* @__PURE__ */ jsx57(MetricWidget, {
|
|
5876
|
+
label: "",
|
|
5877
|
+
loading: true
|
|
5878
|
+
}, item))
|
|
5879
|
+
}),
|
|
5880
|
+
/* @__PURE__ */ jsx57(VisualizationWidget, {
|
|
5881
|
+
title: /* @__PURE__ */ jsx57(Skeleton, {
|
|
5882
|
+
className: "altertable-data-app-skeleton-widget-title"
|
|
5883
|
+
}),
|
|
5884
|
+
visual: /* @__PURE__ */ jsx57("div", {
|
|
5885
|
+
className: "altertable-data-app-skeleton-chart",
|
|
5886
|
+
children: chartHeights.map((height, index) => /* @__PURE__ */ jsx57(Skeleton, {
|
|
5887
|
+
style: { height: `${height}%` }
|
|
5888
|
+
}, index))
|
|
5889
|
+
})
|
|
5890
|
+
}),
|
|
5891
|
+
/* @__PURE__ */ jsx57(DataWidget, {
|
|
5892
|
+
title: /* @__PURE__ */ jsx57(Skeleton, {
|
|
5893
|
+
className: "altertable-data-app-skeleton-widget-title"
|
|
5894
|
+
}),
|
|
5895
|
+
children: /* @__PURE__ */ jsx57("div", {
|
|
5896
|
+
className: "altertable-data-app-skeleton-rows",
|
|
5897
|
+
children: [0, 1, 2].map((row) => /* @__PURE__ */ jsxs42("div", {
|
|
5898
|
+
className: "altertable-data-app-skeleton-row",
|
|
5899
|
+
children: [
|
|
5900
|
+
/* @__PURE__ */ jsx57(Skeleton, {}),
|
|
5901
|
+
/* @__PURE__ */ jsx57(Skeleton, {}),
|
|
5902
|
+
/* @__PURE__ */ jsx57(Skeleton, {})
|
|
5903
|
+
]
|
|
5904
|
+
}, row))
|
|
5905
|
+
})
|
|
5906
|
+
})
|
|
5907
|
+
]
|
|
5908
|
+
}),
|
|
5909
|
+
footer != null && footer !== false && /* @__PURE__ */ jsx57("div", {
|
|
5910
|
+
className: "altertable-data-app-skeleton-footer",
|
|
5911
|
+
children: footer
|
|
5912
|
+
})
|
|
5913
|
+
]
|
|
5914
|
+
})
|
|
5915
|
+
});
|
|
5916
|
+
}
|
|
5757
5917
|
// src/react/ui/RefreshRegion.tsx
|
|
5758
|
-
import { jsx as
|
|
5918
|
+
import { jsx as jsx58 } from "react/jsx-runtime";
|
|
5759
5919
|
function RefreshRegion({
|
|
5760
5920
|
refreshing,
|
|
5761
5921
|
dimOnUpdate = false,
|
|
@@ -5764,10 +5924,10 @@ function RefreshRegion({
|
|
|
5764
5924
|
className,
|
|
5765
5925
|
...props
|
|
5766
5926
|
}) {
|
|
5767
|
-
return /* @__PURE__ */
|
|
5927
|
+
return /* @__PURE__ */ jsx58("div", {
|
|
5768
5928
|
...props,
|
|
5769
5929
|
className: classNames("altertable-refresh-region", className),
|
|
5770
|
-
children: /* @__PURE__ */
|
|
5930
|
+
children: /* @__PURE__ */ jsx58("div", {
|
|
5771
5931
|
...contentProps,
|
|
5772
5932
|
className: classNames("altertable-refresh-content", contentProps?.className),
|
|
5773
5933
|
"data-refreshing": refreshing && dimOnUpdate,
|
|
@@ -5777,8 +5937,8 @@ function RefreshRegion({
|
|
|
5777
5937
|
});
|
|
5778
5938
|
}
|
|
5779
5939
|
// src/react/ui/UpdatedAt.tsx
|
|
5780
|
-
import { useEffect as
|
|
5781
|
-
import { jsx as
|
|
5940
|
+
import { useEffect as useEffect16, useState as useState20 } from "react";
|
|
5941
|
+
import { jsx as jsx59, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
5782
5942
|
function UpdatedAt({
|
|
5783
5943
|
timestamp,
|
|
5784
5944
|
locale,
|
|
@@ -5787,8 +5947,8 @@ function UpdatedAt({
|
|
|
5787
5947
|
triggerClassName,
|
|
5788
5948
|
...props
|
|
5789
5949
|
}) {
|
|
5790
|
-
const [now, setNow] =
|
|
5791
|
-
|
|
5950
|
+
const [now, setNow] = useState20(Date.now);
|
|
5951
|
+
useEffect16(() => {
|
|
5792
5952
|
const interval = window.setInterval(() => setNow(Date.now()), 30000);
|
|
5793
5953
|
return () => window.clearInterval(interval);
|
|
5794
5954
|
}, []);
|
|
@@ -5802,11 +5962,11 @@ function UpdatedAt({
|
|
|
5802
5962
|
else if (elapsedMinutes >= 1)
|
|
5803
5963
|
age = relative.format(-elapsedMinutes, "minute");
|
|
5804
5964
|
const date = new Date(timestamp);
|
|
5805
|
-
return /* @__PURE__ */
|
|
5965
|
+
return /* @__PURE__ */ jsx59(DateTimeTooltip, {
|
|
5806
5966
|
...props,
|
|
5807
5967
|
date,
|
|
5808
5968
|
triggerClassName: ["altertable-updated-at", triggerClassName].filter(Boolean).join(" "),
|
|
5809
|
-
children: children ?? /* @__PURE__ */
|
|
5969
|
+
children: children ?? /* @__PURE__ */ jsxs43("time", {
|
|
5810
5970
|
dateTime: date.toISOString(),
|
|
5811
5971
|
children: [
|
|
5812
5972
|
label,
|
|
@@ -5889,7 +6049,7 @@ function createDataContext(queryNames) {
|
|
|
5889
6049
|
return bindDataContext;
|
|
5890
6050
|
}
|
|
5891
6051
|
// src/react/ui/data-identifiers.tsx
|
|
5892
|
-
import { jsx as
|
|
6052
|
+
import { jsx as jsx60, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
5893
6053
|
function qualifiedName(definition) {
|
|
5894
6054
|
const table = definition.kind === "table" ? definition : definition.table;
|
|
5895
6055
|
const path = [table.catalog, table.schema, table.name].join(".");
|
|
@@ -5925,23 +6085,23 @@ function defineDataIdentifiers({ tables, columns }) {
|
|
|
5925
6085
|
const shown = display ?? (definition.kind === "table" ? "qualified" : "short");
|
|
5926
6086
|
const table = definition.kind === "table" ? definition : definition.table;
|
|
5927
6087
|
const prefix = definition.kind === "table" ? [table.catalog, table.schema] : [table.catalog, table.schema, table.name];
|
|
5928
|
-
return /* @__PURE__ */
|
|
6088
|
+
return /* @__PURE__ */ jsxs44("code", {
|
|
5929
6089
|
className: "altertable-data-identifier",
|
|
5930
6090
|
"data-kind": definition.kind,
|
|
5931
6091
|
title: qualified,
|
|
5932
6092
|
"data-identifier-id": id,
|
|
5933
6093
|
children: [
|
|
5934
|
-
shown === "qualified" && /* @__PURE__ */
|
|
6094
|
+
shown === "qualified" && /* @__PURE__ */ jsx60("span", {
|
|
5935
6095
|
className: "altertable-data-identifier-path",
|
|
5936
|
-
children: prefix.map((segment, index) => /* @__PURE__ */
|
|
6096
|
+
children: prefix.map((segment, index) => /* @__PURE__ */ jsxs44("span", {
|
|
5937
6097
|
children: [
|
|
5938
6098
|
segment,
|
|
5939
6099
|
".",
|
|
5940
|
-
/* @__PURE__ */
|
|
6100
|
+
/* @__PURE__ */ jsx60("wbr", {})
|
|
5941
6101
|
]
|
|
5942
6102
|
}, index))
|
|
5943
6103
|
}),
|
|
5944
|
-
/* @__PURE__ */
|
|
6104
|
+
/* @__PURE__ */ jsx60("span", {
|
|
5945
6105
|
className: "altertable-data-identifier-name",
|
|
5946
6106
|
children: definition.name
|
|
5947
6107
|
})
|
|
@@ -5954,7 +6114,7 @@ function defineDataIdentifiers({ tables, columns }) {
|
|
|
5954
6114
|
};
|
|
5955
6115
|
}
|
|
5956
6116
|
// src/react/ui/GlossaryExplanation.tsx
|
|
5957
|
-
import { jsx as
|
|
6117
|
+
import { jsx as jsx61 } from "react/jsx-runtime";
|
|
5958
6118
|
function GlossaryExplanation({
|
|
5959
6119
|
entry,
|
|
5960
6120
|
empty,
|
|
@@ -5966,7 +6126,7 @@ function GlossaryExplanation({
|
|
|
5966
6126
|
className,
|
|
5967
6127
|
...props
|
|
5968
6128
|
}) {
|
|
5969
|
-
return /* @__PURE__ */
|
|
6129
|
+
return /* @__PURE__ */ jsx61(AboutData, {
|
|
5970
6130
|
...props,
|
|
5971
6131
|
shortcut: false,
|
|
5972
6132
|
iconOnly: true,
|
|
@@ -5981,28 +6141,28 @@ function GlossaryExplanation({
|
|
|
5981
6141
|
className: className ?? "altertable-inspect-trigger",
|
|
5982
6142
|
tooltip: "Explore this term",
|
|
5983
6143
|
"aria-label": props["aria-label"] ?? `Explore ${entry.term}`,
|
|
5984
|
-
children: /* @__PURE__ */
|
|
6144
|
+
children: /* @__PURE__ */ jsx61(AppIcon, {
|
|
5985
6145
|
name: "openDetails"
|
|
5986
6146
|
})
|
|
5987
6147
|
});
|
|
5988
6148
|
}
|
|
5989
6149
|
// src/react/ui/GlossaryDefinition.tsx
|
|
5990
|
-
import { jsx as
|
|
6150
|
+
import { jsx as jsx62, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
5991
6151
|
function GlossaryDefinition({
|
|
5992
6152
|
entry,
|
|
5993
6153
|
children
|
|
5994
6154
|
}) {
|
|
5995
|
-
return /* @__PURE__ */
|
|
6155
|
+
return /* @__PURE__ */ jsxs45(HelpPopover, {
|
|
5996
6156
|
trigger: children ?? entry.term,
|
|
5997
6157
|
triggerLabel: `Explain ${entry.term}`,
|
|
5998
6158
|
label: entry.term,
|
|
5999
6159
|
triggerClassName: "altertable-glossary-definition-trigger",
|
|
6000
6160
|
panelClassName: "altertable-glossary-definition-popover",
|
|
6001
6161
|
children: [
|
|
6002
|
-
/* @__PURE__ */
|
|
6162
|
+
/* @__PURE__ */ jsx62("strong", {
|
|
6003
6163
|
children: entry.term
|
|
6004
6164
|
}),
|
|
6005
|
-
/* @__PURE__ */
|
|
6165
|
+
/* @__PURE__ */ jsx62("div", {
|
|
6006
6166
|
children: entry.definition
|
|
6007
6167
|
})
|
|
6008
6168
|
]
|
|
@@ -6024,6 +6184,7 @@ export {
|
|
|
6024
6184
|
ContentSkeleton,
|
|
6025
6185
|
DataApp,
|
|
6026
6186
|
DataAppProvider,
|
|
6187
|
+
DataAppSkeleton,
|
|
6027
6188
|
DataBoundary,
|
|
6028
6189
|
DataSection,
|
|
6029
6190
|
DataTable,
|
|
@@ -6102,4 +6263,4 @@ export {
|
|
|
6102
6263
|
writeSearch
|
|
6103
6264
|
};
|
|
6104
6265
|
|
|
6105
|
-
//# debugId=
|
|
6266
|
+
//# debugId=A173C527FEF0F21F64756E2164756E21
|