gloomberb 0.18.2 → 0.18.3

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 (157) hide show
  1. package/package.json +1 -1
  2. package/patches/electrobun@1.18.1.patch +106 -5
  3. package/src/api-client/data.ts +15 -0
  4. package/src/api-client/index.ts +2 -0
  5. package/src/api-client/request.ts +5 -3
  6. package/src/api-client/telemetry.ts +17 -0
  7. package/src/app/global-shortcuts.ts +1 -16
  8. package/src/app/runtime/update.ts +28 -8
  9. package/src/architecture/pane-tabs-allowlist.json +65 -0
  10. package/src/cli/commands/market.ts +73 -33
  11. package/src/cli/commands/ticker.ts +82 -25
  12. package/src/cli/help.ts +1 -1
  13. package/src/cli/index.ts +8 -0
  14. package/src/cli/issuer-membership.ts +103 -0
  15. package/src/cli/listing-arg.ts +15 -2
  16. package/src/cli/name-entries.ts +51 -12
  17. package/src/cli/pane-functions/capabilities.ts +2 -0
  18. package/src/cli/pane-functions/catalog.ts +16 -0
  19. package/src/cli/pane-functions/dom.ts +2 -1
  20. package/src/cli/pane-functions/headless.ts +25 -6
  21. package/src/cli/pane-functions/index.ts +64 -5
  22. package/src/cli/pane-functions/resolver.ts +19 -5
  23. package/src/cli/report-tables.ts +136 -18
  24. package/src/cli/result.ts +12 -4
  25. package/src/cli/symbol-list.ts +47 -11
  26. package/src/components/chart/composite/composite-chart.tsx +14 -5
  27. package/src/components/chart/composite/drawing-store.ts +26 -6
  28. package/src/components/chart/composite/interactions.ts +2 -1
  29. package/src/components/chart/composite/panel-surface.tsx +11 -0
  30. package/src/components/chart/composite/types.ts +6 -0
  31. package/src/components/chart/composite/use-composite-chart-keyboard.ts +1 -1
  32. package/src/components/command-bar/routes/root/command-items.ts +32 -6
  33. package/src/components/data-table/view.tsx +23 -3
  34. package/src/components/index.ts +1 -0
  35. package/src/components/layout/detached-pane-shell.tsx +1 -0
  36. package/src/components/layout/floating-pane.tsx +1 -0
  37. package/src/components/layout/header.tsx +228 -55
  38. package/src/components/layout/pane/header.tsx +10 -3
  39. package/src/components/layout/pane/index.tsx +1 -0
  40. package/src/components/layout/pane/pane-tabs.tsx +9 -1
  41. package/src/components/ui/stat-grid.tsx +28 -3
  42. package/src/components/ui/status.tsx +3 -1
  43. package/src/core/app-services.ts +4 -0
  44. package/src/i18n/es.ts +22 -0
  45. package/src/i18n/ja.ts +22 -0
  46. package/src/i18n/ko.ts +22 -0
  47. package/src/i18n/zh-cn.ts +22 -0
  48. package/src/i18n/zh-tw.ts +22 -0
  49. package/src/plugins/builtin/alerts/alert-engine.ts +3 -1
  50. package/src/plugins/builtin/alerts/events.ts +1 -0
  51. package/src/plugins/builtin/alerts/research-rules.ts +1 -0
  52. package/src/plugins/builtin/analytics/risk-pane.tsx +10 -7
  53. package/src/plugins/builtin/attention/pane.tsx +16 -14
  54. package/src/plugins/builtin/awards/pane.tsx +6 -6
  55. package/src/plugins/builtin/backtest/export.ts +1 -1
  56. package/src/plugins/builtin/broker-trading/dock.tsx +4 -2
  57. package/src/plugins/builtin/broker-trading/pane.tsx +6 -4
  58. package/src/plugins/builtin/broker-trading/ticket.tsx +10 -5
  59. package/src/plugins/builtin/buildout/pane/index.tsx +9 -6
  60. package/src/plugins/builtin/catalysts/client.ts +2 -2
  61. package/src/plugins/builtin/catalysts/pane.tsx +3 -3
  62. package/src/plugins/builtin/chart-composer/pane.tsx +1 -0
  63. package/src/plugins/builtin/commodity-balances/pane.tsx +3 -4
  64. package/src/plugins/builtin/company-attention/app-rank.tsx +4 -5
  65. package/src/plugins/builtin/company-attention/pane.tsx +13 -11
  66. package/src/plugins/builtin/company-kpis/pane.tsx +4 -3
  67. package/src/plugins/builtin/correlation/headless.ts +2 -1
  68. package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
  69. package/src/plugins/builtin/correlation/settings.ts +1 -0
  70. package/src/plugins/builtin/cot/pane.tsx +4 -3
  71. package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
  72. package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
  73. package/src/plugins/builtin/doe/pane.tsx +1 -1
  74. package/src/plugins/builtin/equity-screener/headless.ts +10 -0
  75. package/src/plugins/builtin/equity-screener/model.ts +28 -0
  76. package/src/plugins/builtin/equity-screener/pane.tsx +105 -98
  77. package/src/plugins/builtin/exposure/pane.tsx +10 -9
  78. package/src/plugins/builtin/gpu/board.tsx +4 -1
  79. package/src/plugins/builtin/gpu/changes.tsx +10 -10
  80. package/src/plugins/builtin/gpu/equities.tsx +4 -1
  81. package/src/plugins/builtin/gpu/history.tsx +4 -2
  82. package/src/plugins/builtin/gpu/pane.tsx +5 -3
  83. package/src/plugins/builtin/holders/client.ts +2 -1
  84. package/src/plugins/builtin/holders/headless.ts +2 -1
  85. package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
  86. package/src/plugins/builtin/insider/base-values.ts +11 -7
  87. package/src/plugins/builtin/insider/client.ts +3 -0
  88. package/src/plugins/builtin/insider/headless.ts +19 -6
  89. package/src/plugins/builtin/insider/index.tsx +17 -8
  90. package/src/plugins/builtin/insider/issuer.ts +34 -4
  91. package/src/plugins/builtin/insider/signals-client.ts +2 -2
  92. package/src/plugins/builtin/insider/table-model.ts +35 -13
  93. package/src/plugins/builtin/insider/table.tsx +5 -2
  94. package/src/plugins/builtin/iv-history/events.ts +145 -0
  95. package/src/plugins/builtin/iv-history/format.ts +3 -0
  96. package/src/plugins/builtin/iv-history/headless.ts +91 -7
  97. package/src/plugins/builtin/jodi/pane.tsx +4 -4
  98. package/src/plugins/builtin/market-movers/client.ts +4 -3
  99. package/src/plugins/builtin/market-movers/screener.ts +4 -3
  100. package/src/plugins/builtin/notes/cli.ts +1 -1
  101. package/src/plugins/builtin/notes/export.ts +17 -6
  102. package/src/plugins/builtin/notes/files.ts +16 -5
  103. package/src/plugins/builtin/options/enrichment-model.ts +10 -9
  104. package/src/plugins/builtin/options/model-spot.ts +70 -4
  105. package/src/plugins/builtin/options/view.tsx +41 -13
  106. package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
  107. package/src/plugins/builtin/options-positioning/headless.ts +11 -3
  108. package/src/plugins/builtin/options-positioning/model.ts +24 -0
  109. package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
  110. package/src/plugins/builtin/options-scenario/client.ts +19 -1
  111. package/src/plugins/builtin/options-scenario/headless.ts +13 -6
  112. package/src/plugins/builtin/options-scenario/pane.tsx +13 -5
  113. package/src/plugins/builtin/plugin-marketplace/pane.tsx +5 -4
  114. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +8 -5
  115. package/src/plugins/builtin/power/client.ts +2 -2
  116. package/src/plugins/builtin/power/pane.tsx +36 -31
  117. package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
  118. package/src/plugins/builtin/reverse-dcf/model.ts +4 -3
  119. package/src/plugins/builtin/seasonality/client.ts +2 -1
  120. package/src/plugins/builtin/sectors/client.ts +4 -3
  121. package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
  122. package/src/plugins/builtin/shared/research-trading.tsx +2 -0
  123. package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
  124. package/src/plugins/builtin/shared/volatility/options.ts +2 -1
  125. package/src/plugins/builtin/social-mentions/client.ts +2 -1
  126. package/src/plugins/builtin/vol-surface/client.ts +23 -3
  127. package/src/plugins/builtin/vol-surface/headless.ts +33 -14
  128. package/src/plugins/builtin/vol-surface/model.ts +30 -10
  129. package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
  130. package/src/plugins/builtin/vol-surface/stored.ts +34 -3
  131. package/src/plugins/builtin/vol-surface/tables.ts +14 -0
  132. package/src/renderers/dom/desktop/controls.tsx +1 -1
  133. package/src/renderers/dom/desktop/query-bar.tsx +2 -0
  134. package/src/renderers/dom/host/tabs.tsx +16 -5
  135. package/src/renderers/dom/host/top-surface.ts +127 -0
  136. package/src/renderers/dom/styles.css +39 -0
  137. package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
  138. package/src/renderers/electrobun/bun/desktop/backend.ts +10 -0
  139. package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
  140. package/src/renderers/electrobun/view/news-source.ts +4 -2
  141. package/src/renderers/electrobun/view/remote/asset-data-client.ts +8 -1
  142. package/src/renderers/opentui/start.tsx +7 -0
  143. package/src/sources/gloomberb-cloud/index.ts +7 -0
  144. package/src/sources/provider-router/index.ts +16 -0
  145. package/src/telemetry/crash-reports.ts +4 -0
  146. package/src/telemetry/update-failures-node.ts +59 -0
  147. package/src/telemetry/update-failures.ts +307 -0
  148. package/src/tickers/company-name-listing.ts +9 -7
  149. package/src/tickers/company-name.ts +43 -0
  150. package/src/tickers/listing-fate.ts +30 -0
  151. package/src/types/data-provider.ts +6 -0
  152. package/src/types/headless.ts +7 -0
  153. package/src/types/issuer-listings.ts +28 -0
  154. package/src/updater/failure.ts +163 -0
  155. package/src/updater/index.ts +87 -23
  156. package/src/utils/currency-pair.ts +26 -0
  157. package/src/utils/sec.ts +68 -0
@@ -1,4 +1,4 @@
1
- import { useEffect, useRef } from "react";
1
+ import { useCallback, useEffect, useRef } from "react";
2
2
  import { usePaneSettingValue } from "../../../state/app/context";
3
3
  import { CHART_DRAWINGS_SETTING_KEY, parseChartDrawings, type ChartDrawing } from "./tools";
4
4
 
@@ -40,6 +40,12 @@ export function ChartDrawingStore({
40
40
  if (restoredRef.current === null) {
41
41
  restoredRef.current = parseChartDrawings(stored);
42
42
  }
43
+ // What the settings hold, so removing the last drawing is told even when the
44
+ // pane opened with none: it is not "nothing to say" but "the stored one is gone".
45
+ const writtenRef = useRef<readonly ChartDrawing[]>(restoredRef.current);
46
+ const pendingRef = useRef<readonly ChartDrawing[] | null>(null);
47
+ const setStoredRef = useRef(setStored);
48
+ setStoredRef.current = setStored;
43
49
 
44
50
  useEffect(() => {
45
51
  const restored = restoredRef.current;
@@ -47,13 +53,27 @@ export function ChartDrawingStore({
47
53
  // Restoring once on mount: later writes must not scroll back in time.
48
54
  }, []);
49
55
 
56
+ const write = useCallback((next: readonly ChartDrawing[]) => {
57
+ pendingRef.current = null;
58
+ writtenRef.current = next;
59
+ setStoredRef.current(next);
60
+ }, []);
61
+
50
62
  useEffect(() => {
51
- const restored = restoredRef.current ?? NO_DRAWINGS;
52
- if (drawings === restored) return;
53
- if (drawings.length === 0 && restored.length === 0) return;
54
- const timer = setTimeout(() => setStored(drawings), DRAWING_PERSIST_DELAY_MS);
63
+ // Untouched, or still waiting for the restore above: nothing of the user's to write.
64
+ if (drawings === NO_DRAWINGS || drawings === writtenRef.current || (drawings.length === 0 && writtenRef.current.length === 0)) {
65
+ pendingRef.current = null;
66
+ return;
67
+ }
68
+ pendingRef.current = drawings;
69
+ const timer = setTimeout(() => write(drawings), DRAWING_PERSIST_DELAY_MS);
55
70
  return () => clearTimeout(timer);
56
- }, [drawings, setStored]);
71
+ }, [drawings, write]);
72
+
73
+ // A change made just before the chart goes away (a tab switch) is still saved.
74
+ useEffect(() => () => {
75
+ if (pendingRef.current) write(pendingRef.current);
76
+ }, [write]);
57
77
 
58
78
  return null;
59
79
  }
@@ -362,7 +362,8 @@ export function resolveCompositeChartInteraction(event: {
362
362
  if (shifted && key === "d") return "arm-line";
363
363
  if (shifted && key === "p") return "arm-pencil";
364
364
  if (shifted && key === "h") return "arm-level";
365
- if (key === "backspace") return "delete-drawing";
365
+ // Delete is the same act on a keyboard that has the key, or on a Mac with fn.
366
+ if (key === "backspace" || key === "delete") return "delete-drawing";
366
367
  if (key === "c" && !event.shift) return "cycle-colour";
367
368
  if (event.shift) return null;
368
369
  if (key === "a") return "pan-left";
@@ -623,6 +623,17 @@ export function CompositePanelSurface({
623
623
  updateCursor(event);
624
624
  return;
625
625
  }
626
+ // With no tool in hand, a press on a drawing or a level picks it so Backspace
627
+ // or Delete can remove it; the press still pans, and one on bare plot lets go.
628
+ const ratios = pointerRatios(event);
629
+ if (ratios) {
630
+ const drawingHit = drawings.length > 0 ? hitTestDrawings(drawings, scene, panel, ratios, plotAspect) : null;
631
+ const levelHit = !drawingHit && levels?.onEdit && levelDomain
632
+ ? hitTestLevel(projectedLevels, ratios.yRatio, levelGrabRatio(panel.height))
633
+ : null;
634
+ onSelectDrawing(drawingHit ? drawingHit.drawing.id : null);
635
+ onSelectLevel(levelHit?.editable ? levelHit.id : null);
636
+ }
626
637
  if (!updateCursor(event)) return;
627
638
  dragRef.current = startPanGesture(
628
639
  frame,
@@ -315,6 +315,12 @@ export interface CompositeChartProps {
315
315
  interaction: "pan" | "reset" | "zoom",
316
316
  ) => void;
317
317
  onActivate?: () => void;
318
+ /**
319
+ * A press on the chart itself (plot, legend or tool bar), not a wheel turn.
320
+ * The chart consumes the press, so an owner that shares the pane with a
321
+ * field that takes typed keys hears it here to hand the keyboard back.
322
+ */
323
+ onPress?: () => void;
318
324
  onToggleSeries?: (seriesId: string) => void;
319
325
  isSeriesToggleable?: (series: ResolvedSeries) => boolean;
320
326
  /**
@@ -424,7 +424,7 @@ export function useCompositeChartKeyboard({
424
424
  stepLevel(event.name === "[" ? -1 : 1);
425
425
  return;
426
426
  }
427
- if (toolsActive && selectedLevel?.editable && levelsEditable && isPlainKey(event, "backspace")) {
427
+ if (toolsActive && selectedLevel?.editable && levelsEditable && isPlainKey(event, "backspace", "delete")) {
428
428
  consume();
429
429
  removeSelectedLevel();
430
430
  return;
@@ -3,11 +3,26 @@ import type { TickerRecord } from "../../../../types/ticker";
3
3
  import { isManualPortfolio } from "../../../../portfolio/mutations";
4
4
  import type { Command } from "../../commands/registry";
5
5
  import type { ResultItem } from "../../list/model";
6
- import { canRestartToApply } from "../../../../updater";
6
+ import { canRestartToApply, type UpdateProgress } from "../../../../updater";
7
7
  import { NIGHTLY_CHANNEL_SUMMARY, resolveUpdateChannel } from "../../../../updater/channel";
8
+ import { updateFailureReason } from "../../../../updater/failure";
9
+ import { t, tf } from "../../../../i18n";
8
10
  import { isPrereleaseVersion } from "../../../../utils/semver";
9
11
  import { VERSION } from "../../../../version";
10
12
 
13
+ /** "Update failed: download interrupted", as the header says it. */
14
+ function failedUpdateLabel(progress: UpdateProgress): string {
15
+ const reason = progress.failure ? t(updateFailureReason(progress.failure)) : (progress.error ?? "").replace(/\s+/g, " ").trim();
16
+ return tf("Update failed: {error}", { error: reason });
17
+ }
18
+
19
+ /** The whole error under the failed update's row, unless the label already says all of it. */
20
+ function failedUpdateLines(progress: UpdateProgress): ResultItem["lines"] {
21
+ const error = (progress.error ?? "").replace(/\s+/g, " ").trim();
22
+ if (!progress.failure || !error) return undefined;
23
+ return [{ segments: [{ text: error, emphasis: "muted" }] }];
24
+ }
25
+
11
26
  interface RootCommandItemBuilderOptions {
12
27
  activeCollectionId: string | null;
13
28
  activeTickerData: TickerRecord | null | undefined;
@@ -88,9 +103,12 @@ export function createRootCommandItemBuilder({
88
103
  return activeTickerSymbol ? `Remove ${activeTickerSymbol} from Portfolio` : command.label;
89
104
  case "set-portfolio-position":
90
105
  return activeTickerSymbol ? `Set Position for ${activeTickerSymbol}` : command.label;
91
- // The row only shows its label, so a downloaded update is announced there.
106
+ // The row only shows its label, so a downloaded update is announced there,
107
+ // and a failed one with its reason; Enter restarts into the one and retries the other.
92
108
  case "check-for-updates":
93
- return state.updateProgress?.phase === "ready" ? "Update ready, restart to apply" : command.label;
109
+ if (state.updateProgress?.phase === "ready") return "Update ready, restart to apply";
110
+ if (state.updateProgress?.phase === "error") return failedUpdateLabel(state.updateProgress);
111
+ return command.label;
94
112
  default:
95
113
  return command.label;
96
114
  }
@@ -140,7 +158,7 @@ export function createRootCommandItemBuilder({
140
158
  return state.updateProgress.message ?? "Update ready, restart to apply";
141
159
  }
142
160
  if (state.updateProgress?.phase === "error") {
143
- return `Update failed: ${state.updateProgress.error}`;
161
+ return `${failedUpdateLabel(state.updateProgress)}. ${state.updateProgress.error ?? ""}`.trim();
144
162
  }
145
163
  if (state.updateCheckInProgress) return "Checking releases now";
146
164
  if (state.updateAvailable) {
@@ -198,8 +216,11 @@ export function createRootCommandItemBuilder({
198
216
  // "update" is a whole word here so it lands on this command before Set
199
217
  // Portfolio Position (whose keywords say "update position") and Release
200
218
  // Channel, which keeps the word further back.
219
+ // Ready and failed rename the row; its own name still finds it.
201
220
  case "check-for-updates":
202
- return state.updateProgress?.phase === "ready" ? "update check for updates restart relaunch" : "update";
221
+ if (state.updateProgress?.phase === "ready") return "update check for updates restart relaunch";
222
+ if (state.updateProgress?.phase === "error") return "update check for updates retry";
223
+ return "update";
203
224
  case "release-channel":
204
225
  return "nightly stable beta prerelease update updates channel";
205
226
  default:
@@ -218,9 +239,14 @@ export function createRootCommandItemBuilder({
218
239
  right: smartRight(command, arg),
219
240
  shortcutQuery: command.prefix || undefined,
220
241
  searchText: smartSearchText(command),
242
+ ...(command.id === "check-for-updates" && state.updateProgress?.phase === "error"
243
+ ? { lines: failedUpdateLines(state.updateProgress) }
244
+ : {}),
245
+ // Busy while it checks, downloads or installs; a failed update is retried from here.
221
246
  disabled:
222
247
  command.id === "check-for-updates" &&
223
- (state.updateCheckInProgress || (!!state.updateProgress && !canRestartToApply(state.updateProgress))),
248
+ (state.updateCheckInProgress
249
+ || (!!state.updateProgress && !canRestartToApply(state.updateProgress) && state.updateProgress.phase !== "error")),
224
250
  action: () => runDirectCommand(command, arg),
225
251
  };
226
252
  };
@@ -11,7 +11,7 @@ import {
11
11
  import type { ScrollBoxRenderable } from "../../ui";
12
12
  import { useBeforeShortcut, useShortcut } from "../../react/input";
13
13
  import { isPlainKey, isPlainKeyboardEvent } from "../../utils/keyboard";
14
- import { DataTable, type DataTableColumn, type DataTableProps } from "../ui";
14
+ import { DataTable, PaneStatusBody, type DataTableColumn, type DataTableProps, type PaneStatusBodyProps } from "../ui";
15
15
  import { useDataTableSortMenu } from "./sort-menu";
16
16
  import {
17
17
  TableViewFrame,
@@ -89,6 +89,19 @@ export type DataTableSelection<T> =
89
89
  ) => void;
90
90
  };
91
91
 
92
+ /**
93
+ * What the table's body shows instead of rows while it has none to show: its
94
+ * first page loading after a tab or filter change, a failed load, a state
95
+ * with nothing to list. The same states `PaneStatusBody` draws, in the
96
+ * table's place under `rootBefore`, so the query bar and figures above stay
97
+ * on screen (and a search field keeps its focus) while the body waits.
98
+ */
99
+ export type DataTableBodyStatus = Omit<PaneStatusBodyProps, "children" | "width" | "height" | "align">;
100
+
101
+ function bodyStatusShown(status: DataTableBodyStatus | undefined): status is DataTableBodyStatus {
102
+ return !!status && (!!status.error || status.loading === true || status.empty === true);
103
+ }
104
+
92
105
  interface SelectionCommitTarget {
93
106
  index: number;
94
107
  id?: string;
@@ -124,6 +137,12 @@ export interface DataTableViewProps<
124
137
  isNavigable?: (item: T, index: number) => boolean;
125
138
  rootBefore?: ReactNode;
126
139
  rootAfter?: ReactNode;
140
+ /**
141
+ * Replaces the table (header and rows) with a loading, error or empty
142
+ * state while `rootBefore` stays. Precedence is the caller's, as with
143
+ * `PaneStatusBody`: pass `loading` only while there is nothing to show.
144
+ */
145
+ status?: DataTableBodyStatus;
127
146
  rootWidth?: number;
128
147
  rootHeight?: number;
129
148
  rootBackgroundColor?: string;
@@ -165,6 +184,7 @@ export function DataTableView<
165
184
  isNavigable,
166
185
  rootBefore,
167
186
  rootAfter,
187
+ status,
168
188
  rootWidth,
169
189
  rootHeight,
170
190
  rootBackgroundColor,
@@ -728,7 +748,7 @@ export function DataTableView<
728
748
  before={rootBefore}
729
749
  after={rootAfter}
730
750
  >
731
- <DataTable<T, C>
751
+ {bodyStatusShown(status) ? <PaneStatusBody {...status} /> : <DataTable<T, C>
732
752
  {...tableProps}
733
753
  headerScrollRef={effectiveHeaderScrollRef}
734
754
  scrollRef={effectiveScrollRef}
@@ -741,7 +761,7 @@ export function DataTableView<
741
761
  onActivate={handleTableActivate}
742
762
  onRowMouseDown={handleRowMouseDown}
743
763
  onRowContextMenu={handleRowContextMenu}
744
- />
764
+ />}
745
765
  </TableViewFrame>
746
766
  );
747
767
  }
@@ -67,6 +67,7 @@ export { usePagedRows } from "./paged-rows";
67
67
  export type { PageLoader, PageRequest, PagedRows, PagedRowsOptions, RowPage } from "./paged-rows";
68
68
  export { DataTableView } from "./data-table/view";
69
69
  export type {
70
+ DataTableBodyStatus,
70
71
  DataTableKeyEvent,
71
72
  DataTableRootKeyContext,
72
73
  DataTableSelectionChangeReason,
@@ -441,6 +441,7 @@ export function DetachedPaneShell({ pluginRegistry, desktopWindowBridge }: Detac
441
441
  onMouseDown: () => toggleQuickSetting(setting.key),
442
442
  }))}
443
443
  tabs={headerTabs}
444
+ bodyBackground={background}
444
445
  titleBar={{
445
446
  rows: headerHeightRows,
446
447
  overlay: titleBarOverlay === true,
@@ -143,6 +143,7 @@ export function FloatingPaneWrapper({
143
143
  showActions={showActions}
144
144
  quickSettings={quickSettings}
145
145
  tabs={headerTabs}
146
+ bodyBackground={bg}
146
147
  topRule
147
148
  onHeaderMouseMove={onHeaderMouseMove}
148
149
  onHeaderMouseDown={onHeaderMouseDown}