@lunora/studio 0.0.0 → 1.0.0-alpha.1

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.
Files changed (81) hide show
  1. package/LICENSE.md +105 -0
  2. package/README.md +123 -9
  3. package/__assets__/package-og.svg +14 -0
  4. package/dist/index.d.ts +1402 -0
  5. package/dist/index.js +41 -0
  6. package/dist/mount.d.ts +21 -0
  7. package/dist/mount.js +26 -0
  8. package/dist/packem_shared/ADMIN_FUNCTION_PREFIX-DmBqMZ-z.js +45 -0
  9. package/dist/packem_shared/ApiDocsPanel-DpRjJhG5.js +842 -0
  10. package/dist/packem_shared/ApiReferencePanel-DMIUp-kK.js +229 -0
  11. package/dist/packem_shared/ApiTab-DURGU15e.js +251 -0
  12. package/dist/packem_shared/AuditPanel-BC59Nhst.js +212 -0
  13. package/dist/packem_shared/CommandPalette-Dx_CoB9i.js +373 -0
  14. package/dist/packem_shared/ConfirmButton-WQVUoGFb.js +59 -0
  15. package/dist/packem_shared/ConnectionBadge-Bxagrip8.js +111 -0
  16. package/dist/packem_shared/DEFAULT_AUTO_REFRESH_MS-Vxwaxx51.js +50 -0
  17. package/dist/packem_shared/DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js +89 -0
  18. package/dist/packem_shared/DataBrowser-Coz6jJE6.js +4542 -0
  19. package/dist/packem_shared/DataFilters-FNquMaiu.js +249 -0
  20. package/dist/packem_shared/ErrorBoundary-BzAApI7J.js +66 -0
  21. package/dist/packem_shared/ExportImportPanel-WO34fJxy.js +193 -0
  22. package/dist/packem_shared/FileBrowser-Zcr-Qgxo.js +2932 -0
  23. package/dist/packem_shared/FunctionRunner-j0Rd5m9t.js +343 -0
  24. package/dist/packem_shared/FunctionStatsPanel-DboBl-XL.js +432 -0
  25. package/dist/packem_shared/GlobalDataBrowser-9MhPEfgN.js +318 -0
  26. package/dist/packem_shared/HealthPanel-DOIgbUtx.js +640 -0
  27. package/dist/packem_shared/HomePanel-bdOCNA-p.js +1273 -0
  28. package/dist/packem_shared/InsightsPanel-DaZPnSgt.js +423 -0
  29. package/dist/packem_shared/LogsPanel-CWdqAGpQ.js +839 -0
  30. package/dist/packem_shared/MailPanel-D_EGtDnS.js +447 -0
  31. package/dist/packem_shared/MetricsPanel-E4Gv6wTO.js +1625 -0
  32. package/dist/packem_shared/MigrationsPanel-DQdPY9io.js +246 -0
  33. package/dist/packem_shared/OpenRpcReferencePanel-j2p3HB0s.js +191 -0
  34. package/dist/packem_shared/PitrPanel-BbBkQR6t.js +252 -0
  35. package/dist/packem_shared/STUDIO_ROOT_CLASS-D12gX2dV.js +3 -0
  36. package/dist/packem_shared/ScheduledJobs-Ok1CYYwI.js +159 -0
  37. package/dist/packem_shared/SchemaViewer-D8XGnp-X.js +2512 -0
  38. package/dist/packem_shared/SecurityAdvisorPanel-Cdm2IxLW.js +79 -0
  39. package/dist/packem_shared/SettingsPanel-D3WF2mBU.js +176 -0
  40. package/dist/packem_shared/ShardInput-DNCsT1KW.js +107 -0
  41. package/dist/packem_shared/SqlEditorPanel-BuQ7f2Hs.js +13 -0
  42. package/dist/packem_shared/Studio-D36od9Oz.js +33 -0
  43. package/dist/packem_shared/StudioApp-dvywkJ8I.js +383 -0
  44. package/dist/packem_shared/StudioI18nProvider-Dcajsznk.js +48 -0
  45. package/dist/packem_shared/TableEditor-DIVDk3vT.js +371 -0
  46. package/dist/packem_shared/advisor-view-DBlzJi6C.js +159 -0
  47. package/dist/packem_shared/aggregateMetrics-D4nUHEKU.js +108 -0
  48. package/dist/packem_shared/app.d-CCmwDEVs.d.ts +300 -0
  49. package/dist/packem_shared/badge-B2PKA1-5.js +49 -0
  50. package/dist/packem_shared/bar-chart-CzJAgqkp.js +3245 -0
  51. package/dist/packem_shared/button-BhsN2uZH.js +49 -0
  52. package/dist/packem_shared/card-DURq3ElK.js +175 -0
  53. package/dist/packem_shared/cf-links-BZfRdxSE.js +8 -0
  54. package/dist/packem_shared/checkbox-UNkzAxl-.js +63 -0
  55. package/dist/packem_shared/createStudioI18n-CgvlmDkN.js +27 -0
  56. package/dist/packem_shared/data-grid-CCh2Couo.js +183 -0
  57. package/dist/packem_shared/dropdown-menu-WY4B_eJO.js +280 -0
  58. package/dist/packem_shared/empty-state-DY_oe0k6.js +98 -0
  59. package/dist/packem_shared/grid-features-DTjG6Sex.js +840 -0
  60. package/dist/packem_shared/input-XH4r1Pt1.js +53 -0
  61. package/dist/packem_shared/internal-BBZYexre.js +68 -0
  62. package/dist/packem_shared/label-D8ykjn5J.js +46 -0
  63. package/dist/packem_shared/live-status-bPff1O7Y.js +44 -0
  64. package/dist/packem_shared/reference-view-BCKIoai7.js +2180 -0
  65. package/dist/packem_shared/shard-history-DyebH1R5.js +38 -0
  66. package/dist/packem_shared/sparkline-10dG-_f0.js +93 -0
  67. package/dist/packem_shared/sql-editor-panel-CW2y2x9h.js +2562 -0
  68. package/dist/packem_shared/storage-tier-CL98eOvn.js +85 -0
  69. package/dist/packem_shared/studio-BDVd7rIV.js +10303 -0
  70. package/dist/packem_shared/table-_RzNvy3R.js +246 -0
  71. package/dist/packem_shared/table-list-sidebar-aZHLq70w.js +832 -0
  72. package/dist/packem_shared/textarea-D3gaCU_-.js +46 -0
  73. package/dist/packem_shared/use-live-admin-D1h1Fzsd.js +73 -0
  74. package/dist/packem_shared/use-live-shard-seed-B74RYcOy.js +76 -0
  75. package/dist/packem_shared/useDebounced-Dxncpg6z.js +32 -0
  76. package/dist/packem_shared/utils-B05Dmz_H.js +8 -0
  77. package/dist/packem_shared/virtual-rect-CVMUskSm.js +10 -0
  78. package/dist/standalone/studio.js +356 -0
  79. package/dist/styles.css +2 -0
  80. package/package.json +77 -17
  81. package/src/theme.css +59 -0
@@ -0,0 +1,832 @@
1
+ import { c } from 'react/compiler-runtime';
2
+ import { useT } from './createStudioI18n-CgvlmDkN.js';
3
+ import { jsxDEV } from 'react/jsx-dev-runtime';
4
+ import { useState, useRef, useMemo } from 'react';
5
+ import { f as fireAndForget, e as errorMessage } from './internal-BBZYexre.js';
6
+ import { useVirtualizer } from '@tanstack/react-virtual';
7
+ import { c as cn } from './utils-B05Dmz_H.js';
8
+ import { f as flooredRectObserver } from './virtual-rect-CVMUskSm.js';
9
+
10
+ const formatValue = (value) => {
11
+ if (value === null || value === void 0) {
12
+ return "∅";
13
+ }
14
+ if (value === "") {
15
+ return "(empty)";
16
+ }
17
+ if (typeof value === "object") {
18
+ return JSON.stringify(value);
19
+ }
20
+ return String(value);
21
+ };
22
+ const FacetSection = (t0) => {
23
+ const $ = c(32);
24
+ const {
25
+ column,
26
+ onFacetFilter,
27
+ state
28
+ } = t0;
29
+ const t = useT();
30
+ let t1;
31
+ if ($[0] !== column || $[1] !== onFacetFilter || $[2] !== state.result?.values) {
32
+ t1 = (event) => {
33
+ const index = Number(event.currentTarget.dataset.index);
34
+ const entry = state.result?.values[index];
35
+ if (entry !== void 0) {
36
+ onFacetFilter(column, entry.value);
37
+ }
38
+ };
39
+ $[0] = column;
40
+ $[1] = onFacetFilter;
41
+ $[2] = state.result?.values;
42
+ $[3] = t1;
43
+ } else {
44
+ t1 = $[3];
45
+ }
46
+ const onValueClick = t1;
47
+ const t2 = `db-facet-${column}`;
48
+ let t3;
49
+ if ($[4] !== column) {
50
+ t3 = /* @__PURE__ */ jsxDEV("span", {
51
+ className: "font-medium text-foreground",
52
+ children: column
53
+ }, void 0, false);
54
+ $[4] = column;
55
+ $[5] = t3;
56
+ } else {
57
+ t3 = $[5];
58
+ }
59
+ let t4;
60
+ if ($[6] !== state.loading || $[7] !== state.result || $[8] !== t) {
61
+ t4 = state.loading && state.result === null && /* @__PURE__ */ jsxDEV("span", {
62
+ className: "text-muted-foreground",
63
+ children: t("Loading…")
64
+ }, void 0, false);
65
+ $[6] = state.loading;
66
+ $[7] = state.result;
67
+ $[8] = t;
68
+ $[9] = t4;
69
+ } else {
70
+ t4 = $[9];
71
+ }
72
+ let t5;
73
+ if ($[10] !== state.error) {
74
+ t5 = state.error !== null && /* @__PURE__ */ jsxDEV("span", {
75
+ className: "text-destructive",
76
+ role: "alert",
77
+ children: state.error
78
+ }, void 0, false);
79
+ $[10] = state.error;
80
+ $[11] = t5;
81
+ } else {
82
+ t5 = $[11];
83
+ }
84
+ let t6;
85
+ if ($[12] !== state.result?.values) {
86
+ t6 = state.result?.values ?? [];
87
+ $[12] = state.result?.values;
88
+ $[13] = t6;
89
+ } else {
90
+ t6 = $[13];
91
+ }
92
+ let t7;
93
+ if ($[14] !== column || $[15] !== onValueClick || $[16] !== t6) {
94
+ let t82;
95
+ if ($[18] !== column || $[19] !== onValueClick) {
96
+ t82 = (entry_0, index_0) => /* @__PURE__ */ jsxDEV("button", {
97
+ className: "flex items-center justify-between gap-2 rounded px-1 py-0.5 text-left text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
98
+ "data-index": index_0,
99
+ "data-testid": `db-facet-value-${column}`,
100
+ onClick: onValueClick,
101
+ type: "button",
102
+ children: [/* @__PURE__ */ jsxDEV("span", {
103
+ className: "truncate",
104
+ children: formatValue(entry_0.value)
105
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
106
+ className: "shrink-0 tabular-nums text-foreground/70",
107
+ children: entry_0.count
108
+ }, void 0, false)]
109
+ }, formatValue(entry_0.value), true);
110
+ $[18] = column;
111
+ $[19] = onValueClick;
112
+ $[20] = t82;
113
+ } else {
114
+ t82 = $[20];
115
+ }
116
+ t7 = t6.map(t82);
117
+ $[14] = column;
118
+ $[15] = onValueClick;
119
+ $[16] = t6;
120
+ $[17] = t7;
121
+ } else {
122
+ t7 = $[17];
123
+ }
124
+ let t8;
125
+ if ($[21] !== column || $[22] !== state.result || $[23] !== t) {
126
+ t8 = state.result?.truncated === true && /* @__PURE__ */ jsxDEV("span", {
127
+ className: "text-muted-foreground",
128
+ "data-testid": `db-facet-truncated-${column}`,
129
+ children: t("Showing the {n} most common values.", {
130
+ n: state.result.values.length
131
+ })
132
+ }, void 0, false);
133
+ $[21] = column;
134
+ $[22] = state.result;
135
+ $[23] = t;
136
+ $[24] = t8;
137
+ } else {
138
+ t8 = $[24];
139
+ }
140
+ let t9;
141
+ if ($[25] !== t2 || $[26] !== t3 || $[27] !== t4 || $[28] !== t5 || $[29] !== t7 || $[30] !== t8) {
142
+ t9 = /* @__PURE__ */ jsxDEV("section", {
143
+ className: "flex flex-col gap-1",
144
+ "data-testid": t2,
145
+ children: [t3, t4, t5, t7, t8]
146
+ }, void 0, true);
147
+ $[25] = t2;
148
+ $[26] = t3;
149
+ $[27] = t4;
150
+ $[28] = t5;
151
+ $[29] = t7;
152
+ $[30] = t8;
153
+ $[31] = t9;
154
+ } else {
155
+ t9 = $[31];
156
+ }
157
+ return t9;
158
+ };
159
+ const DataFacets = (t0) => {
160
+ const $ = c(26);
161
+ const {
162
+ columns,
163
+ facets,
164
+ onFacetFilter,
165
+ onToggleFacet
166
+ } = t0;
167
+ const t = useT();
168
+ let t1;
169
+ if ($[0] !== onToggleFacet) {
170
+ t1 = (event) => {
171
+ const {
172
+ column
173
+ } = event.currentTarget.dataset;
174
+ if (column !== void 0) {
175
+ onToggleFacet(column);
176
+ }
177
+ };
178
+ $[0] = onToggleFacet;
179
+ $[1] = t1;
180
+ } else {
181
+ t1 = $[1];
182
+ }
183
+ const toggle = t1;
184
+ if (columns.length === 0) {
185
+ return null;
186
+ }
187
+ let t2;
188
+ if ($[2] !== t) {
189
+ t2 = t("Facets");
190
+ $[2] = t;
191
+ $[3] = t2;
192
+ } else {
193
+ t2 = $[3];
194
+ }
195
+ let t3;
196
+ if ($[4] !== t2) {
197
+ t3 = /* @__PURE__ */ jsxDEV("span", {
198
+ className: "font-mono text-[11px] tracking-wide uppercase text-muted-foreground",
199
+ children: t2
200
+ }, void 0, false);
201
+ $[4] = t2;
202
+ $[5] = t3;
203
+ } else {
204
+ t3 = $[5];
205
+ }
206
+ let t4;
207
+ if ($[6] !== columns || $[7] !== facets || $[8] !== toggle) {
208
+ let t52;
209
+ if ($[10] !== facets || $[11] !== toggle) {
210
+ t52 = (column_0) => /* @__PURE__ */ jsxDEV("button", {
211
+ "aria-pressed": column_0 in facets,
212
+ className: "rounded border border-border px-1.5 py-0.5 text-muted-foreground transition-colors hover:bg-accent aria-pressed:bg-accent aria-pressed:text-accent-foreground",
213
+ "data-column": column_0,
214
+ "data-testid": `db-facet-toggle-${column_0}`,
215
+ onClick: toggle,
216
+ type: "button",
217
+ children: column_0
218
+ }, column_0, false);
219
+ $[10] = facets;
220
+ $[11] = toggle;
221
+ $[12] = t52;
222
+ } else {
223
+ t52 = $[12];
224
+ }
225
+ t4 = columns.map(t52);
226
+ $[6] = columns;
227
+ $[7] = facets;
228
+ $[8] = toggle;
229
+ $[9] = t4;
230
+ } else {
231
+ t4 = $[9];
232
+ }
233
+ let t5;
234
+ if ($[13] !== t4) {
235
+ t5 = /* @__PURE__ */ jsxDEV("div", {
236
+ className: "flex flex-wrap gap-1",
237
+ children: t4
238
+ }, void 0, false);
239
+ $[13] = t4;
240
+ $[14] = t5;
241
+ } else {
242
+ t5 = $[14];
243
+ }
244
+ let t6;
245
+ if ($[15] !== t3 || $[16] !== t5) {
246
+ t6 = /* @__PURE__ */ jsxDEV("div", {
247
+ className: "flex flex-col gap-1.5",
248
+ children: [t3, t5]
249
+ }, void 0, true);
250
+ $[15] = t3;
251
+ $[16] = t5;
252
+ $[17] = t6;
253
+ } else {
254
+ t6 = $[17];
255
+ }
256
+ let t7;
257
+ if ($[18] !== facets) {
258
+ t7 = Object.entries(facets);
259
+ $[18] = facets;
260
+ $[19] = t7;
261
+ } else {
262
+ t7 = $[19];
263
+ }
264
+ let t8;
265
+ if ($[20] !== onFacetFilter || $[21] !== t7) {
266
+ t8 = t7.map((t92) => {
267
+ const [column_1, state] = t92;
268
+ return /* @__PURE__ */ jsxDEV(FacetSection, {
269
+ column: column_1,
270
+ onFacetFilter,
271
+ state
272
+ }, column_1, false);
273
+ });
274
+ $[20] = onFacetFilter;
275
+ $[21] = t7;
276
+ $[22] = t8;
277
+ } else {
278
+ t8 = $[22];
279
+ }
280
+ let t9;
281
+ if ($[23] !== t6 || $[24] !== t8) {
282
+ t9 = /* @__PURE__ */ jsxDEV("aside", {
283
+ className: "flex w-56 shrink-0 flex-col gap-3 overflow-auto border-l border-border p-3 text-xs",
284
+ "data-testid": "db-facets",
285
+ children: [t6, t8]
286
+ }, void 0, true);
287
+ $[23] = t6;
288
+ $[24] = t8;
289
+ $[25] = t9;
290
+ } else {
291
+ t9 = $[25];
292
+ }
293
+ return t9;
294
+ };
295
+
296
+ const PAGE_SIZE_OPTIONS = [25, 50, 100, 250];
297
+ const PageSizeSelect = (t0) => {
298
+ const $ = c(18);
299
+ const {
300
+ onChange,
301
+ options,
302
+ prefix,
303
+ value
304
+ } = t0;
305
+ const t = useT();
306
+ let t1;
307
+ if ($[0] !== onChange) {
308
+ t1 = (event) => {
309
+ onChange(Number.parseInt(event.target.value, 10));
310
+ };
311
+ $[0] = onChange;
312
+ $[1] = t1;
313
+ } else {
314
+ t1 = $[1];
315
+ }
316
+ const onSelect = t1;
317
+ const t2 = `${prefix}-page-size`;
318
+ let t3;
319
+ if ($[2] !== t) {
320
+ t3 = t("Rows per page");
321
+ $[2] = t;
322
+ $[3] = t3;
323
+ } else {
324
+ t3 = $[3];
325
+ }
326
+ let t4;
327
+ if ($[4] !== t3) {
328
+ t4 = /* @__PURE__ */ jsxDEV("span", {
329
+ children: t3
330
+ }, void 0, false);
331
+ $[4] = t3;
332
+ $[5] = t4;
333
+ } else {
334
+ t4 = $[5];
335
+ }
336
+ const t5 = `${prefix}-page-size`;
337
+ const t6 = `${prefix}-page-size`;
338
+ let t7;
339
+ if ($[6] !== options) {
340
+ t7 = options.map(_temp);
341
+ $[6] = options;
342
+ $[7] = t7;
343
+ } else {
344
+ t7 = $[7];
345
+ }
346
+ let t8;
347
+ if ($[8] !== onSelect || $[9] !== t5 || $[10] !== t6 || $[11] !== t7 || $[12] !== value) {
348
+ t8 = /* @__PURE__ */ jsxDEV("select", {
349
+ className: "h-6 rounded-md border border-border bg-background px-1 tabular-nums outline-none focus-visible:border-ring",
350
+ "data-testid": t5,
351
+ id: t6,
352
+ onChange: onSelect,
353
+ value,
354
+ children: t7
355
+ }, void 0, false);
356
+ $[8] = onSelect;
357
+ $[9] = t5;
358
+ $[10] = t6;
359
+ $[11] = t7;
360
+ $[12] = value;
361
+ $[13] = t8;
362
+ } else {
363
+ t8 = $[13];
364
+ }
365
+ let t9;
366
+ if ($[14] !== t2 || $[15] !== t4 || $[16] !== t8) {
367
+ t9 = /* @__PURE__ */ jsxDEV("label", {
368
+ className: "flex items-center gap-1.5",
369
+ htmlFor: t2,
370
+ children: [t4, t8]
371
+ }, void 0, true);
372
+ $[14] = t2;
373
+ $[15] = t4;
374
+ $[16] = t8;
375
+ $[17] = t9;
376
+ } else {
377
+ t9 = $[17];
378
+ }
379
+ return t9;
380
+ };
381
+ const PageJump = (t0) => {
382
+ const $ = c(25);
383
+ const {
384
+ onJump,
385
+ page,
386
+ pages,
387
+ prefix
388
+ } = t0;
389
+ const t = useT();
390
+ let t1;
391
+ if ($[0] !== onJump || $[1] !== pages) {
392
+ t1 = (raw) => {
393
+ const next = Number.parseInt(raw, 10);
394
+ if (!Number.isNaN(next)) {
395
+ onJump(Math.min(Math.max(1, next), Math.max(1, pages)));
396
+ }
397
+ };
398
+ $[0] = onJump;
399
+ $[1] = pages;
400
+ $[2] = t1;
401
+ } else {
402
+ t1 = $[2];
403
+ }
404
+ const commit = t1;
405
+ let t2;
406
+ if ($[3] !== commit) {
407
+ t2 = (event) => {
408
+ if (event.key === "Enter") {
409
+ commit(event.currentTarget.value);
410
+ }
411
+ };
412
+ $[3] = commit;
413
+ $[4] = t2;
414
+ } else {
415
+ t2 = $[4];
416
+ }
417
+ const onKeyDown = t2;
418
+ let t3;
419
+ if ($[5] !== commit) {
420
+ t3 = (event_0) => {
421
+ commit(event_0.currentTarget.value);
422
+ };
423
+ $[5] = commit;
424
+ $[6] = t3;
425
+ } else {
426
+ t3 = $[6];
427
+ }
428
+ const onBlur = t3;
429
+ let t4;
430
+ if ($[7] !== t) {
431
+ t4 = t("Page");
432
+ $[7] = t;
433
+ $[8] = t4;
434
+ } else {
435
+ t4 = $[8];
436
+ }
437
+ let t5;
438
+ if ($[9] !== t) {
439
+ t5 = t("Page");
440
+ $[9] = t;
441
+ $[10] = t5;
442
+ } else {
443
+ t5 = $[10];
444
+ }
445
+ const t6 = `${prefix}-page-jump`;
446
+ const t7 = Math.max(1, pages);
447
+ let t8;
448
+ if ($[11] !== onBlur || $[12] !== onKeyDown || $[13] !== page || $[14] !== t5 || $[15] !== t6 || $[16] !== t7) {
449
+ t8 = /* @__PURE__ */ jsxDEV("input", {
450
+ "aria-label": t5,
451
+ className: "h-6 w-12 rounded-md border border-border bg-background px-1 text-center tabular-nums outline-none focus-visible:border-ring",
452
+ "data-testid": t6,
453
+ defaultValue: page,
454
+ max: t7,
455
+ min: 1,
456
+ onBlur,
457
+ onKeyDown,
458
+ type: "number"
459
+ }, page, false);
460
+ $[11] = onBlur;
461
+ $[12] = onKeyDown;
462
+ $[13] = page;
463
+ $[14] = t5;
464
+ $[15] = t6;
465
+ $[16] = t7;
466
+ $[17] = t8;
467
+ } else {
468
+ t8 = $[17];
469
+ }
470
+ let t9;
471
+ if ($[18] !== pages || $[19] !== t) {
472
+ t9 = t("of {pages}", {
473
+ pages
474
+ });
475
+ $[18] = pages;
476
+ $[19] = t;
477
+ $[20] = t9;
478
+ } else {
479
+ t9 = $[20];
480
+ }
481
+ let t10;
482
+ if ($[21] !== t4 || $[22] !== t8 || $[23] !== t9) {
483
+ t10 = /* @__PURE__ */ jsxDEV("span", {
484
+ className: "flex items-center gap-1.5 tabular-nums",
485
+ children: [t4, t8, t9]
486
+ }, void 0, true);
487
+ $[21] = t4;
488
+ $[22] = t8;
489
+ $[23] = t9;
490
+ $[24] = t10;
491
+ } else {
492
+ t10 = $[24];
493
+ }
494
+ return t10;
495
+ };
496
+ const GridPagination = ({
497
+ hasNext,
498
+ hasPrevious,
499
+ onJumpToPage,
500
+ onNext,
501
+ onPageSizeChange,
502
+ onPrevious,
503
+ pageSize,
504
+ pageSizeOptions = PAGE_SIZE_OPTIONS,
505
+ prefix,
506
+ rangeEnd,
507
+ rangeStart,
508
+ total
509
+ }) => {
510
+ const t = useT();
511
+ const buttonClass = "rounded-md border border-border px-2.5 py-1 text-xs font-medium text-foreground outline-none transition-colors hover:bg-accent focus-visible:bg-accent disabled:pointer-events-none disabled:opacity-50";
512
+ const pages = pageSize !== void 0 && pageSize > 0 ? Math.max(1, Math.ceil(total / pageSize)) : 1;
513
+ const page = pageSize !== void 0 && pageSize > 0 ? Math.floor(Math.max(0, rangeStart - 1) / pageSize) + 1 : 1;
514
+ return /* @__PURE__ */ jsxDEV("div", {
515
+ className: "flex w-full items-center justify-between gap-3 text-xs text-muted-foreground",
516
+ children: [/* @__PURE__ */ jsxDEV("div", {
517
+ className: "flex items-center gap-3",
518
+ children: [pageSize !== void 0 && onPageSizeChange !== void 0 && /* @__PURE__ */ jsxDEV(PageSizeSelect, {
519
+ onChange: onPageSizeChange,
520
+ options: pageSizeOptions,
521
+ prefix,
522
+ value: pageSize
523
+ }, void 0, false), /* @__PURE__ */ jsxDEV("span", {
524
+ className: "tabular-nums",
525
+ "data-testid": `${prefix}-page-info`,
526
+ children: t("{rangeStart}-{rangeEnd} of {total}", {
527
+ rangeEnd,
528
+ rangeStart,
529
+ total
530
+ })
531
+ }, void 0, false)]
532
+ }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
533
+ className: "flex items-center gap-3",
534
+ children: [/* @__PURE__ */ jsxDEV("button", {
535
+ className: buttonClass,
536
+ "data-testid": `${prefix}-prev`,
537
+ disabled: !hasPrevious,
538
+ onClick: onPrevious,
539
+ type: "button",
540
+ children: t("Previous")
541
+ }, void 0, false), pageSize !== void 0 && onJumpToPage !== void 0 && /* @__PURE__ */ jsxDEV(PageJump, {
542
+ onJump: onJumpToPage,
543
+ page,
544
+ pages,
545
+ prefix
546
+ }, void 0, false), /* @__PURE__ */ jsxDEV("button", {
547
+ className: buttonClass,
548
+ "data-testid": `${prefix}-next`,
549
+ disabled: !hasNext,
550
+ onClick: onNext,
551
+ type: "button",
552
+ children: t("Next")
553
+ }, void 0, false)]
554
+ }, void 0, true)]
555
+ }, void 0, true);
556
+ };
557
+ function _temp(option) {
558
+ return /* @__PURE__ */ jsxDEV("option", {
559
+ value: option,
560
+ children: option
561
+ }, option, false);
562
+ }
563
+
564
+ const useFacets = () => {
565
+ const [facets, setFacets] = useState({});
566
+ const facetsRef = useRef(facets);
567
+ facetsRef.current = facets;
568
+ const fetchFacet = async (column, fetcher) => {
569
+ setFacets((current) => column in current ? {
570
+ ...current,
571
+ [column]: {
572
+ error: null,
573
+ loading: true,
574
+ result: current[column]?.result ?? null
575
+ }
576
+ } : current);
577
+ try {
578
+ const result = await fetcher(column);
579
+ setFacets((current_1) => column in current_1 ? {
580
+ ...current_1,
581
+ [column]: {
582
+ error: null,
583
+ loading: false,
584
+ result
585
+ }
586
+ } : current_1);
587
+ } catch (error) {
588
+ setFacets((current_0) => column in current_0 ? {
589
+ ...current_0,
590
+ [column]: {
591
+ error: errorMessage(error),
592
+ loading: false,
593
+ result: null
594
+ }
595
+ } : current_0);
596
+ }
597
+ };
598
+ const toggleFacet = (column_0, fetcher_0) => {
599
+ setFacets((current_2) => {
600
+ if (column_0 in current_2) {
601
+ return Object.fromEntries(Object.entries(current_2).filter(([name]) => name !== column_0));
602
+ }
603
+ if (fetcher_0 !== null) {
604
+ fireAndForget(fetchFacet(column_0, fetcher_0));
605
+ }
606
+ return {
607
+ ...current_2,
608
+ [column_0]: {
609
+ error: null,
610
+ loading: true,
611
+ result: null
612
+ }
613
+ };
614
+ });
615
+ };
616
+ const refetchFacets = (fetcher_1) => {
617
+ for (const column_1 of Object.keys(facetsRef.current)) {
618
+ fireAndForget(fetchFacet(column_1, fetcher_1));
619
+ }
620
+ };
621
+ const clearFacets = () => {
622
+ setFacets({});
623
+ facetsRef.current = {};
624
+ };
625
+ return {
626
+ clearFacets,
627
+ facets,
628
+ facetsRef,
629
+ refetchFacets,
630
+ toggleFacet
631
+ };
632
+ };
633
+
634
+ const TABLE_ROW_HEIGHT = 34;
635
+ const TABLE_LIST_VIEWPORT = 600;
636
+ const TableListButton = (t0) => {
637
+ const $ = c(21);
638
+ const {
639
+ item,
640
+ onSelect,
641
+ prefix,
642
+ selected,
643
+ start
644
+ } = t0;
645
+ let t1;
646
+ if ($[0] !== item.name || $[1] !== onSelect) {
647
+ t1 = () => {
648
+ onSelect(item.name);
649
+ };
650
+ $[0] = item.name;
651
+ $[1] = onSelect;
652
+ $[2] = t1;
653
+ } else {
654
+ t1 = $[2];
655
+ }
656
+ const onClick = t1;
657
+ const t2 = `translateY(${String(start)}px)`;
658
+ let t3;
659
+ if ($[3] !== t2) {
660
+ t3 = {
661
+ insetInline: 0,
662
+ position: "absolute",
663
+ top: 0,
664
+ transform: t2
665
+ };
666
+ $[3] = t2;
667
+ $[4] = t3;
668
+ } else {
669
+ t3 = $[4];
670
+ }
671
+ const style = t3;
672
+ const t4 = selected ? "bg-accent font-medium text-accent-foreground" : "text-foreground";
673
+ let t5;
674
+ if ($[5] !== t4) {
675
+ t5 = cn("flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-start text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent", t4);
676
+ $[5] = t4;
677
+ $[6] = t5;
678
+ } else {
679
+ t5 = $[6];
680
+ }
681
+ const t6 = `${prefix}-table-${item.name}`;
682
+ let t7;
683
+ if ($[7] !== item.name) {
684
+ t7 = /* @__PURE__ */ jsxDEV("span", {
685
+ className: "truncate",
686
+ children: item.name
687
+ }, void 0, false);
688
+ $[7] = item.name;
689
+ $[8] = t7;
690
+ } else {
691
+ t7 = $[8];
692
+ }
693
+ let t8;
694
+ if ($[9] !== item.rowCount) {
695
+ t8 = /* @__PURE__ */ jsxDEV("span", {
696
+ className: "shrink-0 rounded bg-muted px-1.5 text-xs tabular-nums text-muted-foreground",
697
+ children: item.rowCount
698
+ }, void 0, false);
699
+ $[9] = item.rowCount;
700
+ $[10] = t8;
701
+ } else {
702
+ t8 = $[10];
703
+ }
704
+ let t9;
705
+ if ($[11] !== onClick || $[12] !== selected || $[13] !== t5 || $[14] !== t6 || $[15] !== t7 || $[16] !== t8) {
706
+ t9 = /* @__PURE__ */ jsxDEV("button", {
707
+ "aria-pressed": selected,
708
+ className: t5,
709
+ "data-testid": t6,
710
+ onClick,
711
+ type: "button",
712
+ children: [t7, t8]
713
+ }, void 0, true);
714
+ $[11] = onClick;
715
+ $[12] = selected;
716
+ $[13] = t5;
717
+ $[14] = t6;
718
+ $[15] = t7;
719
+ $[16] = t8;
720
+ $[17] = t9;
721
+ } else {
722
+ t9 = $[17];
723
+ }
724
+ let t10;
725
+ if ($[18] !== style || $[19] !== t9) {
726
+ t10 = /* @__PURE__ */ jsxDEV("li", {
727
+ style,
728
+ children: t9
729
+ }, void 0, false);
730
+ $[18] = style;
731
+ $[19] = t9;
732
+ $[20] = t10;
733
+ } else {
734
+ t10 = $[20];
735
+ }
736
+ return t10;
737
+ };
738
+ const TableListSidebar = ({
739
+ header,
740
+ onReload,
741
+ onSelect,
742
+ prefix,
743
+ reloadLabel,
744
+ selected,
745
+ tables
746
+ }) => {
747
+ const t = useT();
748
+ const [query, setQuery] = useState("");
749
+ const scrollRef = useRef(null);
750
+ const onQueryChange = (event) => {
751
+ setQuery(event.target.value);
752
+ };
753
+ const filtered = useMemo(() => {
754
+ const needle = query.trim().toLowerCase();
755
+ return needle === "" ? tables : tables.filter((item) => item.name.toLowerCase().includes(needle));
756
+ }, [query, tables]);
757
+ const virtualizer = useVirtualizer({
758
+ count: filtered.length,
759
+ estimateSize: () => TABLE_ROW_HEIGHT,
760
+ getScrollElement: () => scrollRef.current,
761
+ initialRect: {
762
+ height: TABLE_LIST_VIEWPORT,
763
+ width: 240
764
+ },
765
+ observeElementRect: (instance, callback) => flooredRectObserver(instance, callback, TABLE_LIST_VIEWPORT),
766
+ overscan: 12
767
+ });
768
+ const virtualRows = virtualizer.getVirtualItems();
769
+ const trackStyle = {
770
+ height: filtered.length * TABLE_ROW_HEIGHT
771
+ };
772
+ return /* @__PURE__ */ jsxDEV("aside", {
773
+ className: "flex h-full w-60 shrink-0 flex-col border-e border-border bg-sidebar",
774
+ "data-testid": `${prefix}-table-list`,
775
+ children: [header, /* @__PURE__ */ jsxDEV("div", {
776
+ className: "flex h-9 shrink-0 items-center justify-between gap-2 border-b border-border px-3",
777
+ children: [/* @__PURE__ */ jsxDEV("span", {
778
+ className: "font-mono text-[11px] tracking-wide uppercase text-muted-foreground",
779
+ children: t("Tables")
780
+ }, void 0, false), onReload !== void 0 && /* @__PURE__ */ jsxDEV("button", {
781
+ "aria-label": reloadLabel ?? t("Refresh"),
782
+ className: "flex size-6 items-center justify-center rounded-md text-muted-foreground outline-none transition-colors hover:bg-accent hover:text-foreground focus-visible:bg-accent",
783
+ "data-testid": `${prefix}-load-tables`,
784
+ onClick: onReload,
785
+ title: reloadLabel ?? t("Refresh"),
786
+ type: "button",
787
+ children: /* @__PURE__ */ jsxDEV("svg", {
788
+ "aria-hidden": "true",
789
+ className: "size-3.5",
790
+ fill: "none",
791
+ stroke: "currentColor",
792
+ strokeLinecap: "round",
793
+ strokeLinejoin: "round",
794
+ strokeWidth: 1.6,
795
+ viewBox: "0 0 24 24",
796
+ children: /* @__PURE__ */ jsxDEV("path", {
797
+ d: "M4 12a8 8 0 0 1 13.7-5.6L20 8M20 4v4h-4M20 12a8 8 0 0 1-13.7 5.6L4 16m0 4v-4h4"
798
+ }, void 0, false)
799
+ }, void 0, false)
800
+ }, void 0, false)]
801
+ }, void 0, true), /* @__PURE__ */ jsxDEV("div", {
802
+ className: "shrink-0 border-b border-border p-2",
803
+ children: /* @__PURE__ */ jsxDEV("input", {
804
+ className: "h-7 w-full rounded-md border border-border bg-background px-2 text-xs outline-none placeholder:text-muted-foreground focus-visible:border-ring",
805
+ "data-testid": `${prefix}-table-search`,
806
+ onChange: onQueryChange,
807
+ placeholder: t("search table…"),
808
+ type: "search",
809
+ value: query
810
+ }, void 0, false)
811
+ }, void 0, false), /* @__PURE__ */ jsxDEV("ul", {
812
+ className: "relative flex-1 overflow-y-auto p-1.5",
813
+ "data-testid": `${prefix}-table-list-rows`,
814
+ ref: scrollRef,
815
+ children: [/* @__PURE__ */ jsxDEV("li", {
816
+ "aria-hidden": "true",
817
+ style: trackStyle
818
+ }, void 0, false), virtualRows.map((vrow) => {
819
+ const item_0 = filtered[vrow.index];
820
+ return item_0 === void 0 ? null : /* @__PURE__ */ jsxDEV(TableListButton, {
821
+ item: item_0,
822
+ onSelect,
823
+ prefix,
824
+ selected: selected === item_0.name,
825
+ start: vrow.start
826
+ }, item_0.name, false);
827
+ })]
828
+ }, void 0, true)]
829
+ }, void 0, true);
830
+ };
831
+
832
+ export { DataFacets as D, GridPagination as G, TableListSidebar as T, useFacets as u };