gloomberb 0.16.3 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -91
- package/package.json +7 -1
- package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
- package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
- package/src/account/billing.ts +57 -0
- package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
- package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
- package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
- package/src/account/session.ts +16 -0
- package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +42 -17
- package/src/account/upgrade-personalization.ts +57 -0
- package/src/account/upgrade-tickers.ts +124 -0
- package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
- package/src/api-client/askg.ts +43 -0
- package/src/api-client/auth.ts +15 -0
- package/src/api-client/beneficial-owners.ts +4 -0
- package/src/api-client/chat.ts +19 -0
- package/src/api-client/company-kpis.ts +14 -2
- package/src/api-client/data.ts +58 -18
- package/src/api-client/earnings.ts +6 -0
- package/src/api-client/futures-curve.ts +56 -0
- package/src/api-client/index.ts +16 -1
- package/src/api-client/market-discovery.ts +10 -1
- package/src/api-client/normalizers.ts +27 -0
- package/src/api-client/paths.ts +95 -23
- package/src/api-client/request.ts +2 -1
- package/src/api-client/research-activity.ts +46 -10
- package/src/api-client/socket.ts +39 -8
- package/src/api-client/types.ts +74 -2
- package/src/api-client/upgrade-experiment.ts +90 -0
- package/src/api-client/yield-curves.ts +8 -0
- package/src/app/global-shortcuts.ts +26 -2
- package/src/app/keybindings/actions.ts +10 -0
- package/src/app/pane-runtime/index.tsx +8 -0
- package/src/app/pane-runtime/pane-template-runtime.ts +5 -0
- package/src/app/pane-runtime/plugin-bindings.ts +65 -25
- package/src/app/pane-runtime/ticker-inspector-runtime.ts +12 -0
- package/src/app/pane-runtime/ticker-open-runtime.ts +25 -4
- package/src/app/runtime/desktop-deeplink.ts +5 -0
- package/src/app/star-prompt/model.ts +98 -0
- package/src/app/star-prompt/runtime.ts +41 -0
- package/src/app/star-prompt/status-line.tsx +190 -0
- package/src/app.tsx +13 -7
- package/src/architecture/core-builtin-allowlist.json +61 -0
- package/src/brokers/signed-in/adapter.ts +33 -2
- package/src/brokers/signed-in/client.ts +10 -0
- package/src/brokers/signed-in/sign-in-dialog.tsx +34 -14
- package/src/brokers/signed-in/sign-in.ts +62 -5
- package/src/capabilities/chart-series.ts +11 -1
- package/src/capabilities/registry.ts +8 -1
- package/src/capabilities/types.ts +2 -0
- package/src/cli/commands/crypto-hints.ts +19 -4
- package/src/cli/commands/fred-series.ts +61 -0
- package/src/cli/commands/market.ts +744 -181
- package/src/cli/commands/news-hints.ts +62 -0
- package/src/cli/commands/news-search.ts +53 -0
- package/src/cli/commands/options-chain.ts +172 -0
- package/src/cli/commands/options-leaps.ts +425 -0
- package/src/cli/commands/overview.ts +251 -40
- package/src/cli/commands/remote.ts +2 -1
- package/src/cli/commands/search.ts +109 -15
- package/src/cli/commands/system.ts +151 -24
- package/src/cli/commands/themes.ts +64 -0
- package/src/cli/commands/ticker.ts +149 -40
- package/src/cli/context.ts +45 -14
- package/src/cli/desktop-pane-shot.ts +150 -17
- package/src/cli/earnings-calendar.ts +71 -0
- package/src/cli/errors.ts +25 -2
- package/src/cli/freshness.ts +22 -8
- package/src/cli/fx-pair.ts +57 -0
- package/src/cli/glossary.ts +429 -0
- package/src/cli/help.ts +14 -1
- package/src/cli/history-rows.ts +48 -7
- package/src/cli/index-roots.ts +58 -0
- package/src/cli/index.ts +29 -12
- package/src/cli/known-gaps.ts +27 -0
- package/src/cli/listing-arg.ts +595 -26
- package/src/cli/not-a-ticker.ts +44 -0
- package/src/cli/options.ts +50 -6
- package/src/cli/pane-functions/access-gate.ts +5 -0
- package/src/cli/pane-functions/capabilities.ts +11 -4
- package/src/cli/pane-functions/catalog.ts +48 -7
- package/src/cli/pane-functions/data.ts +48 -13
- package/src/cli/pane-functions/discovery.ts +1 -0
- package/src/cli/pane-functions/dom.ts +41 -19
- package/src/cli/pane-functions/freshness.ts +531 -32
- package/src/cli/pane-functions/function-help.ts +77 -25
- package/src/cli/pane-functions/headless.ts +50 -21
- package/src/cli/pane-functions/index.ts +66 -10
- package/src/cli/pane-functions/market-session.ts +147 -0
- package/src/cli/pane-functions/options.ts +77 -25
- package/src/cli/pane-functions/report-notices.ts +81 -0
- package/src/cli/pane-functions/report.ts +19 -8
- package/src/cli/pane-functions/resolver.ts +53 -18
- package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
- package/src/cli/pane-functions/screenshot.ts +199 -30
- package/src/cli/registry.ts +2 -1
- package/src/cli/report-tables.ts +3 -0
- package/src/cli/result.ts +53 -13
- package/src/cli/row-window.ts +76 -0
- package/src/cli/scroll-truncation.ts +34 -0
- package/src/cli/staged-tickers.ts +52 -0
- package/src/cli/symbol-args.ts +9 -0
- package/src/cli/symbol-list.ts +172 -0
- package/src/cli/ticker-resolution.ts +223 -30
- package/src/cli/types.ts +5 -0
- package/src/components/chart/composite/axis-overlays.tsx +6 -2
- package/src/components/chart/composite/composite-chart.tsx +83 -10
- package/src/components/chart/composite/legend.tsx +88 -8
- package/src/components/chart/composite/panel-surface.tsx +44 -17
- package/src/components/chart/composite/price-axis-labels.tsx +3 -1
- package/src/components/chart/composite/rasterizer.ts +64 -4
- package/src/components/chart/composite/series-cues.ts +71 -0
- package/src/components/chart/composite/text-renderer.ts +16 -8
- package/src/components/chart/composite/types.ts +3 -0
- package/src/components/command-bar/commands/direct/index.ts +9 -1
- package/src/components/command-bar/commands/plugin/items.ts +3 -1
- package/src/components/command-bar/commands/registry.ts +7 -0
- package/src/components/command-bar/layout-items/focused-pane.ts +38 -0
- package/src/components/command-bar/pane-templates/workflow.ts +5 -0
- package/src/components/command-bar/panel/index.tsx +11 -3
- package/src/components/command-bar/panel/runtime.ts +3 -0
- package/src/components/command-bar/panel/types.ts +2 -0
- package/src/components/command-bar/routes/root/command-items.ts +2 -0
- package/src/components/command-bar/routes/root/plugin-turn-on.ts +92 -0
- package/src/components/command-bar/routes/root/provider-search.ts +4 -3
- package/src/components/command-bar/routes/root/results.ts +40 -10
- package/src/components/command-bar/routes/root/runtime.ts +8 -0
- package/src/components/command-bar/routes/root/search-providers.ts +97 -14
- package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
- package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
- package/src/components/command-bar/surface/index.tsx +18 -4
- package/src/components/command-bar/theme-picker.tsx +48 -13
- package/src/components/command-bar/workflow/ops.ts +5 -3
- package/src/components/command-bar/workflow/tickers.ts +23 -4
- package/src/components/data-table/view.tsx +28 -9
- package/src/components/layout/detached-pane-shell.tsx +9 -0
- package/src/components/layout/floating-pane.tsx +9 -2
- package/src/components/layout/header.tsx +20 -5
- package/src/components/layout/market-summary.ts +23 -9
- package/src/components/layout/pane/content.tsx +40 -29
- package/src/components/layout/pane/cycle-order.ts +2 -11
- package/src/components/layout/pane/footer/index.tsx +6 -2
- package/src/components/layout/pane/footer/model.ts +35 -1
- package/src/components/layout/pane/header.tsx +26 -2
- package/src/components/layout/pane/index.tsx +12 -2
- package/src/components/layout/pane/sidebar.tsx +78 -10
- package/src/components/layout/pane/title.ts +1 -1
- package/src/components/layout/presentation.ts +22 -0
- package/src/components/layout/shell/active-drag.ts +21 -5
- package/src/components/layout/shell/drag/index.ts +43 -9
- package/src/components/layout/shell/drag/live.ts +87 -6
- package/src/components/layout/shell/drag/runtime.ts +62 -20
- package/src/components/layout/shell/index.tsx +71 -12
- package/src/components/layout/shell/layout-state.ts +5 -11
- package/src/components/layout/shell/menu.ts +33 -1
- package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
- package/src/components/layout/shell/pane/actions.ts +2 -1
- package/src/components/layout/shell/pane/layers.tsx +216 -28
- package/src/components/layout/shell/pane/management-shortcuts.ts +5 -0
- package/src/components/layout/shell/pane/new-layout.ts +116 -0
- package/src/components/layout/shell/shortcuts.ts +5 -2
- package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
- package/src/components/layout/shell/visible-layout.ts +44 -1
- package/src/components/layout/status-bar.tsx +4 -1
- package/src/components/markdown-text.tsx +69 -23
- package/src/components/metric-treemap/heat-surface.tsx +37 -9
- package/src/components/metric-treemap/heat-tiles.ts +48 -17
- package/src/components/onboarding/account-step/form-panel.tsx +1 -1
- package/src/components/onboarding/account-step/index.tsx +1 -1
- package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
- package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
- package/src/components/onboarding/onboarding-frame.tsx +33 -10
- package/src/components/onboarding/onboarding-keyboard.ts +1 -1
- package/src/components/onboarding/onboarding-wizard.tsx +50 -41
- package/src/components/onboarding/portfolio-step/positions-panel.tsx +5 -2
- package/src/components/onboarding/pro-step-layout.ts +86 -0
- package/src/components/onboarding/use-onboarding-upgrade.ts +8 -4
- package/src/components/onboarding/wizard-account.ts +2 -2
- package/src/components/pane-template-wizard.tsx +9 -1
- package/src/components/price-selector-dialog.tsx +11 -2
- package/src/components/sign-in-gate.tsx +3 -3
- package/src/components/ticker/list-table-view.tsx +24 -1
- package/src/components/ui/action-row.tsx +2 -1
- package/src/components/ui/button.tsx +17 -1
- package/src/components/ui/choice-dialog.tsx +6 -4
- package/src/components/ui/confirm-dialog.tsx +28 -18
- package/src/components/ui/data-table/index.tsx +49 -0
- package/src/components/ui/data-table/opentui/index.tsx +37 -6
- package/src/components/ui/data-table/types.ts +20 -1
- package/src/components/ui/data-table/visible-range.ts +2 -0
- package/src/components/ui/dialog-actions.tsx +64 -0
- package/src/components/ui/display.tsx +17 -3
- package/src/components/ui/frame.tsx +35 -2
- package/src/components/ui/icon.tsx +13 -2
- package/src/components/ui/index.ts +1 -1
- package/src/components/ui/text-prompt-dialog.tsx +11 -9
- package/src/core/connection-health.ts +1 -1
- package/src/core/state/app/layout-reducer.ts +89 -3
- package/src/core/state/app/state.ts +8 -5
- package/src/core/state/app/types.ts +13 -2
- package/src/data/cached-query.ts +2 -0
- package/src/data/config/layout.ts +55 -21
- package/src/data/config/store/fold-panes.ts +149 -0
- package/src/data/config/store/migrations.ts +7 -0
- package/src/data/config/store/node.ts +27 -6
- package/src/data/config/store/normalize.ts +44 -5
- package/src/data/ticker-repository.ts +5 -0
- package/src/data/ticker-store.ts +15 -0
- package/src/docs/content.ts +215 -0
- package/src/docs/load.ts +139 -0
- package/src/docs/requests.ts +39 -0
- package/src/docs/snapshot.chunk.ts +8 -0
- package/src/docs/snapshot.json +7416 -0
- package/src/docs/topics.ts +216 -0
- package/src/i18n/es.ts +75 -5
- package/src/i18n/ja.ts +75 -5
- package/src/i18n/ko.ts +75 -5
- package/src/i18n/zh-cn.ts +75 -5
- package/src/i18n/zh-tw.ts +75 -5
- package/src/layout/desks.ts +2 -3
- package/src/layout/pane-layout-move.ts +264 -0
- package/src/layout/pane-manager/dock-tree.ts +18 -0
- package/src/layout/pane-manager/hidden-panes.ts +160 -0
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/market-data/coordinator/chart.ts +10 -4
- package/src/market-data/coordinator/entries.ts +7 -1
- package/src/market-data/coordinator/index.ts +6 -3
- package/src/market-data/coordinator/quotes.ts +2 -2
- package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
- package/src/market-data/futures-contract.ts +151 -0
- package/src/market-data/hooks.tsx +10 -2
- package/src/market-data/market/format.ts +39 -21
- package/src/market-data/market/freshness.ts +193 -30
- package/src/market-data/market/status.ts +59 -23
- package/src/market-data/options-alternatives.ts +69 -0
- package/src/market-data/published-apac-sessions.ts +23 -1
- package/src/market-data/quotes/contributions.ts +22 -2
- package/src/market-data/quotes/metadata.ts +8 -9
- package/src/market-data/quotes/resolution.ts +2 -0
- package/src/market-data/quotes/screener-live-quotes.ts +61 -9
- package/src/market-data/result-types.ts +2 -0
- package/src/plugins/builtin/account-management/keyboard.ts +3 -0
- package/src/plugins/builtin/account-management/model.ts +2 -56
- package/src/plugins/builtin/account-management/navigation.ts +1 -1
- package/src/plugins/builtin/account-management/pane.tsx +37 -8
- package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
- package/src/plugins/builtin/alerts/cli.ts +313 -47
- package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
- package/src/plugins/builtin/alerts/events.ts +23 -2
- package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
- package/src/plugins/builtin/alerts/history.ts +2 -0
- package/src/plugins/builtin/alerts/index.tsx +41 -9
- package/src/plugins/builtin/alerts/pane.tsx +8 -0
- package/src/plugins/builtin/alerts/quotes.ts +3 -0
- package/src/plugins/builtin/alerts/research-builder.ts +8 -3
- package/src/plugins/builtin/alerts/research-rules.ts +18 -2
- package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
- package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
- package/src/plugins/builtin/alerts/scheduled.ts +254 -0
- package/src/plugins/builtin/alerts/targets.ts +92 -0
- package/src/plugins/builtin/analytics/index.tsx +4 -2
- package/src/plugins/builtin/analytics/risk-headless.ts +33 -13
- package/src/plugins/builtin/analytics/risk-math.ts +91 -27
- package/src/plugins/builtin/analytics/risk-model.ts +71 -12
- package/src/plugins/builtin/analytics/risk-pane.tsx +23 -12
- package/src/plugins/builtin/attention/index.tsx +2 -0
- package/src/plugins/builtin/attention/pane.tsx +3 -1
- package/src/plugins/builtin/attention/series.ts +26 -0
- package/src/plugins/builtin/awards/index.tsx +2 -0
- package/src/plugins/builtin/awards/pane.tsx +3 -1
- package/src/plugins/builtin/awards/series.ts +29 -0
- package/src/plugins/builtin/backtest/pane.tsx +1 -1
- package/src/plugins/builtin/bond-calculator/model.ts +2 -1
- package/src/plugins/builtin/broker-manager/detail.tsx +4 -0
- package/src/plugins/builtin/broker-manager/index.tsx +7 -3
- package/src/plugins/builtin/broker-manager/model.ts +8 -0
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +8 -2
- package/src/plugins/builtin/broker-manager/sign-in-end.ts +82 -0
- package/src/plugins/builtin/broker-manager/table.ts +5 -0
- package/src/plugins/builtin/builtin-plugin-meta.ts +121 -11
- package/src/plugins/builtin/catalysts/pane.tsx +3 -1
- package/src/plugins/builtin/cds/client.ts +70 -13
- package/src/plugins/builtin/cds/headless.ts +116 -19
- package/src/plugins/builtin/cds/index.tsx +3 -1
- package/src/plugins/builtin/cds/model.ts +193 -31
- package/src/plugins/builtin/cds/pane.tsx +56 -14
- package/src/plugins/builtin/cds/series.ts +19 -0
- package/src/plugins/builtin/central-bank-rates/index.tsx +2 -0
- package/src/plugins/builtin/central-bank-rates/series.ts +42 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +192 -255
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
- package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
- package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
- package/src/plugins/builtin/chart-composer/headless.ts +8 -3
- package/src/plugins/builtin/chart-composer/index.tsx +9 -2
- package/src/plugins/builtin/chart-composer/pane.tsx +1 -1
- package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
- package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
- package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
- package/src/plugins/builtin/chat/channels.ts +34 -36
- package/src/plugins/builtin/chat/command-bar.ts +138 -0
- package/src/plugins/builtin/chat/composer-commands.ts +21 -1
- package/src/plugins/builtin/chat/content/composer-runtime.ts +11 -1
- package/src/plugins/builtin/chat/content/footer.tsx +5 -3
- package/src/plugins/builtin/chat/content/index.tsx +21 -1
- package/src/plugins/builtin/chat/content/mentions.ts +2 -1
- package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
- package/src/plugins/builtin/chat/content/user-map.ts +3 -1
- package/src/plugins/builtin/chat/controller/index.ts +50 -0
- package/src/plugins/builtin/chat/conversations.ts +256 -0
- package/src/plugins/builtin/chat/discord-command.ts +91 -0
- package/src/plugins/builtin/chat/edit-window.ts +12 -6
- package/src/plugins/builtin/chat/ghost-user.ts +14 -0
- package/src/plugins/builtin/chat/index.tsx +40 -2
- package/src/plugins/builtin/chat/layout.ts +2 -0
- package/src/plugins/builtin/chat/message/desktop.tsx +2 -1
- package/src/plugins/builtin/chat/message/header.tsx +24 -15
- package/src/plugins/builtin/chat/message/profile-popover.tsx +2 -1
- package/src/plugins/builtin/chat/message/render-state.ts +3 -0
- package/src/plugins/builtin/chat/pane-requests.ts +60 -0
- package/src/plugins/builtin/chat/pane-state.ts +32 -2
- package/src/plugins/builtin/chat/pane.tsx +8 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +223 -23
- package/src/plugins/builtin/cloud/askg/conversation-store.ts +21 -0
- package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
- package/src/plugins/builtin/cloud/askg/manifest.ts +33 -7
- package/src/plugins/builtin/cloud/askg/model.ts +156 -78
- package/src/plugins/builtin/cloud/askg/pane.tsx +772 -377
- package/src/plugins/builtin/cloud/askg/protocol.ts +50 -3
- package/src/plugins/builtin/cloud/askg/tool-display.ts +440 -0
- package/src/plugins/builtin/cloud/askg/tool-timeline.tsx +403 -0
- package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
- package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
- package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
- package/src/plugins/builtin/cloud/company-picker.tsx +1 -9
- package/src/plugins/builtin/cloud/mcp-connect/command.ts +24 -0
- package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +363 -0
- package/src/plugins/builtin/cloud/mcp-connect/model.ts +135 -0
- package/src/plugins/builtin/cloud/mcp-connect/sections.ts +62 -0
- package/src/plugins/builtin/cloud/plugin.tsx +36 -1
- package/src/plugins/builtin/cloud/terminal-relay/acm-tab.tsx +89 -0
- package/src/plugins/builtin/cloud/terminal-relay/client.ts +97 -0
- package/src/plugins/builtin/cloud/terminal-relay/connect-section.tsx +57 -0
- package/src/plugins/builtin/cloud/terminal-relay/engine.ts +734 -0
- package/src/plugins/builtin/cloud/terminal-relay/grants.ts +137 -0
- package/src/plugins/builtin/cloud/terminal-relay/host.tsx +81 -0
- package/src/plugins/builtin/cloud/terminal-relay/indicator.tsx +82 -0
- package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +239 -0
- package/src/plugins/builtin/cloud/terminal-relay/policy.ts +162 -0
- package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +192 -0
- package/src/plugins/builtin/cloud/terminal-relay/redact.ts +73 -0
- package/src/plugins/builtin/cloud/terminal-relay/summary.ts +62 -0
- package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
- package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
- package/src/plugins/builtin/comment-letters/client.ts +1 -3
- package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
- package/src/plugins/builtin/company-attention/headless.ts +19 -5
- package/src/plugins/builtin/company-attention/index.tsx +2 -0
- package/src/plugins/builtin/company-attention/model.ts +26 -7
- package/src/plugins/builtin/company-attention/pane.tsx +12 -9
- package/src/plugins/builtin/company-attention/series.ts +52 -0
- package/src/plugins/builtin/company-kpis/client.ts +23 -8
- package/src/plugins/builtin/company-kpis/headless.ts +3 -1
- package/src/plugins/builtin/company-kpis/pane.tsx +19 -9
- package/src/plugins/builtin/company-kpis/screenshot-evidence.ts +10 -3
- package/src/plugins/builtin/composite-plugins.ts +116 -67
- package/src/plugins/builtin/cot/index.tsx +3 -1
- package/src/plugins/builtin/cot/model.ts +40 -11
- package/src/plugins/builtin/cot/series.ts +27 -0
- package/src/plugins/builtin/credit-boards/cdx-pane.tsx +4 -4
- package/src/plugins/builtin/credit-boards/index.tsx +23 -21
- package/src/plugins/builtin/credit-boards/model.ts +0 -1
- package/src/plugins/builtin/credit-boards/pane.tsx +30 -0
- package/src/plugins/builtin/credit-boards/series.ts +66 -0
- package/src/plugins/builtin/credit-boards/sovr-pane.tsx +4 -4
- package/src/plugins/builtin/credit-conditions/index.tsx +2 -0
- package/src/plugins/builtin/credit-conditions/series.ts +26 -0
- package/src/plugins/builtin/credit-documents/headless.ts +31 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
- package/src/plugins/builtin/crypto-board/headless.ts +2 -3
- package/src/plugins/builtin/crypto-board/index.tsx +2 -0
- package/src/plugins/builtin/crypto-board/model.ts +12 -0
- package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
- package/src/plugins/builtin/crypto-board/series.ts +48 -0
- package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
- package/src/plugins/builtin/debt-maturities/client.ts +37 -9
- package/src/plugins/builtin/debt-maturities/headless.ts +3 -1
- package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +5 -4
- package/src/plugins/builtin/debt-maturities/series.ts +45 -0
- package/src/plugins/builtin/dividend-yield/headless.ts +2 -2
- package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
- package/src/plugins/builtin/dividend-yield/pane.tsx +1 -1
- package/src/plugins/builtin/dividend-yield/series.ts +20 -0
- package/src/plugins/builtin/docs/blocks.tsx +181 -0
- package/src/plugins/builtin/docs/index.tsx +68 -0
- package/src/plugins/builtin/docs/pane.tsx +426 -0
- package/src/plugins/builtin/docs/targets.ts +72 -0
- package/src/plugins/builtin/docs/use-docs.ts +60 -0
- package/src/plugins/builtin/doe/index.tsx +2 -0
- package/src/plugins/builtin/doe/series.ts +62 -0
- package/src/plugins/builtin/earnings/client.ts +3 -2
- package/src/plugins/builtin/earnings/format.ts +1 -5
- package/src/plugins/builtin/earnings/headless.ts +58 -6
- package/src/plugins/builtin/earnings/history-model.ts +15 -1
- package/src/plugins/builtin/earnings/history-table.ts +13 -2
- package/src/plugins/builtin/earnings/history.tsx +7 -3
- package/src/plugins/builtin/earnings-calls/data.ts +28 -7
- package/src/plugins/builtin/earnings-calls/headless.ts +3 -2
- package/src/plugins/builtin/earnings-calls/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +42 -17
- package/src/plugins/builtin/econ/detail-view.tsx +2 -2
- package/src/plugins/builtin/econ/fred-catalog.ts +189 -0
- package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
- package/src/plugins/builtin/econ/index.tsx +70 -22
- package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
- package/src/plugins/builtin/econ-statistics/headless.ts +30 -5
- package/src/plugins/builtin/econ-statistics/pane.tsx +1 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
- package/src/plugins/builtin/econ-statistics/view.ts +17 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
- package/src/plugins/builtin/executives/data.ts +17 -6
- package/src/plugins/builtin/executives/pane.tsx +16 -7
- package/src/plugins/builtin/exposure/holdings.ts +1 -1
- package/src/plugins/builtin/exposure/pane.tsx +3 -1
- package/src/plugins/builtin/fear-greed/index.tsx +4 -0
- package/src/plugins/builtin/fear-greed/series.ts +52 -0
- package/src/plugins/builtin/filing-events/pane.tsx +22 -5
- package/src/plugins/builtin/futures/index.tsx +43 -3
- package/src/plugins/builtin/futures/model.ts +1 -1
- package/src/plugins/builtin/futures/returns.ts +1 -1
- package/src/plugins/builtin/futures/series.ts +13 -0
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +12 -3
- package/src/plugins/builtin/futures-curve/headless.ts +70 -9
- package/src/plugins/builtin/futures-curve/index.tsx +1 -1
- package/src/plugins/builtin/futures-curve/model.ts +66 -11
- package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
- package/src/plugins/builtin/fx-matrix/index.tsx +22 -1
- package/src/plugins/builtin/fx-matrix/pairs.ts +1 -1
- package/src/plugins/builtin/fx-matrix/settings.ts +42 -2
- package/src/plugins/builtin/gpu/board.tsx +13 -10
- package/src/plugins/builtin/gpu/changes.tsx +4 -4
- package/src/plugins/builtin/gpu/client.ts +19 -1
- package/src/plugins/builtin/gpu/equities.tsx +14 -10
- package/src/plugins/builtin/gpu/headless.ts +64 -27
- package/src/plugins/builtin/gpu/history.tsx +3 -3
- package/src/plugins/builtin/gpu/index.tsx +2 -0
- package/src/plugins/builtin/gpu/model.ts +114 -20
- package/src/plugins/builtin/gpu/pane.tsx +28 -12
- package/src/plugins/builtin/gpu/series.ts +38 -0
- package/src/plugins/builtin/help/function-card.tsx +25 -6
- package/src/plugins/builtin/help/index.tsx +18 -8
- package/src/plugins/builtin/holders/beneficial-client.ts +29 -7
- package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
- package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +62 -14
- package/src/plugins/builtin/holders/client.ts +22 -3
- package/src/plugins/builtin/holders/format.ts +18 -3
- package/src/plugins/builtin/holders/headless.ts +42 -134
- package/src/plugins/builtin/holders/pane.tsx +14 -4
- package/src/plugins/builtin/holders/report-header.ts +40 -5
- package/src/plugins/builtin/holders/report-rows.ts +240 -0
- package/src/plugins/builtin/insider/client.ts +35 -20
- package/src/plugins/builtin/insider/headless.ts +41 -11
- package/src/plugins/builtin/insider/index.tsx +27 -10
- package/src/plugins/builtin/insider/insider-data.ts +10 -0
- package/src/plugins/builtin/insider/issuer.ts +49 -0
- package/src/plugins/builtin/insider/model.ts +3 -0
- package/src/plugins/builtin/iv-history/charts.tsx +21 -7
- package/src/plugins/builtin/iv-history/client.ts +26 -6
- package/src/plugins/builtin/iv-history/format.ts +33 -2
- package/src/plugins/builtin/iv-history/headless.ts +27 -12
- package/src/plugins/builtin/iv-history/index.tsx +5 -3
- package/src/plugins/builtin/iv-history/model.ts +172 -20
- package/src/plugins/builtin/iv-history/pane.tsx +11 -3
- package/src/plugins/builtin/iv-history/screen-pane.tsx +45 -25
- package/src/plugins/builtin/iv-history/series.ts +29 -0
- package/src/plugins/builtin/jobs/headless.ts +28 -3
- package/src/plugins/builtin/jobs/index.tsx +3 -1
- package/src/plugins/builtin/jobs/pane.tsx +1 -1
- package/src/plugins/builtin/jobs/series.ts +19 -0
- package/src/plugins/builtin/kelly-sizer/headless.ts +149 -0
- package/src/plugins/builtin/kelly-sizer/history.ts +80 -0
- package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
- package/src/plugins/builtin/kelly-sizer/pane.tsx +111 -40
- package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
- package/src/plugins/builtin/kelly-sizer/sections.tsx +14 -0
- package/src/plugins/builtin/kelly-sizer/types.ts +9 -1
- package/src/plugins/builtin/layout-manager/index.tsx +9 -1
- package/src/plugins/builtin/macro-day/client.ts +68 -3
- package/src/plugins/builtin/macro-day/headless.ts +18 -12
- package/src/plugins/builtin/macro-day/index.tsx +3 -0
- package/src/plugins/builtin/macro-day/model.ts +66 -15
- package/src/plugins/builtin/macro-day/pane.tsx +34 -20
- package/src/plugins/builtin/macro-day/release-table.ts +40 -0
- package/src/plugins/builtin/macro-day/releases.ts +62 -44
- package/src/plugins/builtin/market-heatmap/data.ts +25 -5
- package/src/plugins/builtin/market-heatmap/evidence.ts +90 -0
- package/src/plugins/builtin/market-heatmap/index.tsx +144 -63
- package/src/plugins/builtin/market-heatmap/model.ts +102 -3
- package/src/plugins/builtin/market-heatmap/portfolio.ts +12 -2
- package/src/plugins/builtin/market-movers/client.ts +7 -5
- package/src/plugins/builtin/market-movers/headless.ts +31 -4
- package/src/plugins/builtin/market-movers/index.tsx +11 -3
- package/src/plugins/builtin/market-movers/model.ts +101 -17
- package/src/plugins/builtin/market-movers/screener.ts +31 -0
- package/src/plugins/builtin/market-movers/table.ts +50 -23
- package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
- package/src/plugins/builtin/market-valuation/index.tsx +3 -3
- package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
- package/src/plugins/builtin/members/headless.ts +7 -2
- package/src/plugins/builtin/members/model.ts +31 -3
- package/src/plugins/builtin/members/pane.tsx +3 -6
- package/src/plugins/builtin/mna/headless.ts +15 -3
- package/src/plugins/builtin/money-markets/index.tsx +2 -0
- package/src/plugins/builtin/money-markets/series.ts +41 -0
- package/src/plugins/builtin/news/headless.ts +9 -2
- package/src/plugins/builtin/news/wire/news/footer.ts +10 -0
- package/src/plugins/builtin/notes/cli.ts +12 -7
- package/src/plugins/builtin/openfda/client.ts +1 -1
- package/src/plugins/builtin/options/carry.ts +95 -0
- package/src/plugins/builtin/options/index.tsx +58 -5
- package/src/plugins/builtin/options/strike-window.ts +183 -0
- package/src/plugins/builtin/options/table.ts +55 -3
- package/src/plugins/builtin/options/types.ts +8 -1
- package/src/plugins/builtin/options/view.tsx +162 -13
- package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
- package/src/plugins/builtin/options-positioning/client.ts +7 -3
- package/src/plugins/builtin/options-positioning/headless.ts +5 -2
- package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
- package/src/plugins/builtin/options-scenario/charts.tsx +2 -2
- package/src/plugins/builtin/options-scenario/client.ts +75 -18
- package/src/plugins/builtin/options-scenario/headless.ts +72 -24
- package/src/plugins/builtin/options-scenario/hedge.ts +285 -0
- package/src/plugins/builtin/options-scenario/index.tsx +9 -2
- package/src/plugins/builtin/options-scenario/model.ts +33 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +40 -16
- package/src/plugins/builtin/pe-band/model.ts +2 -2
- package/src/plugins/builtin/pe-band/report-dates.ts +11 -7
- package/src/plugins/builtin/perps/client.ts +40 -6
- package/src/plugins/builtin/perps/equity-row.tsx +33 -8
- package/src/plugins/builtin/perps/freshness.ts +66 -0
- package/src/plugins/builtin/perps/headless.ts +45 -30
- package/src/plugins/builtin/perps/index.tsx +18 -1
- package/src/plugins/builtin/perps/model.ts +32 -6
- package/src/plugins/builtin/perps/pane.tsx +76 -20
- package/src/plugins/builtin/perps/series.ts +76 -0
- package/src/plugins/builtin/plugin-marketplace/model.ts +64 -21
- package/src/plugins/builtin/plugin-marketplace/packs.ts +118 -0
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +357 -39
- package/src/plugins/builtin/plugin-marketplace/store.ts +7 -1
- package/src/plugins/builtin/plugin-module.ts +90 -4
- package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +273 -0
- package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +400 -99
- package/src/plugins/builtin/portfolio-list/cli/render.ts +281 -43
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +26 -16
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +120 -47
- package/src/plugins/builtin/portfolio-list/column-values.ts +1 -1
- package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
- package/src/plugins/builtin/portfolio-list/headless.ts +70 -9
- package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
- package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +6 -1
- package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +17 -1
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +1 -1
- package/src/plugins/builtin/portfolio-list/table.tsx +7 -1
- package/src/plugins/builtin/power/client.ts +16 -0
- package/src/plugins/builtin/power/evidence.ts +6 -2
- package/src/plugins/builtin/power/headless.ts +71 -7
- package/src/plugins/builtin/power/index.tsx +4 -1
- package/src/plugins/builtin/power/model.ts +72 -1
- package/src/plugins/builtin/power/pane.tsx +32 -9
- package/src/plugins/builtin/rate-path/headless.ts +11 -3
- package/src/plugins/builtin/realized-vol/headless.ts +8 -0
- package/src/plugins/builtin/realized-vol/pane.tsx +1 -1
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +7 -4
- package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +1 -1
- package/src/plugins/builtin/research/event-model.ts +68 -24
- package/src/plugins/builtin/research/events-headless.ts +2 -1
- package/src/plugins/builtin/research/headless.ts +2 -1
- package/src/plugins/builtin/revenue-breakdown/client.ts +13 -6
- package/src/plugins/builtin/revenue-breakdown/headless.ts +4 -1
- package/src/plugins/builtin/revenue-breakdown/pane.tsx +7 -4
- package/src/plugins/builtin/reverse-dcf/headless.ts +5 -1
- package/src/plugins/builtin/reverse-dcf/pane.tsx +1 -1
- package/src/plugins/builtin/risk-factors/data.ts +23 -9
- package/src/plugins/builtin/risk-factors/headless.ts +5 -2
- package/src/plugins/builtin/risk-factors/pane.tsx +6 -5
- package/src/plugins/builtin/seasonality/client.ts +15 -7
- package/src/plugins/builtin/seasonality/headless.ts +36 -12
- package/src/plugins/builtin/seasonality/index.tsx +2 -2
- package/src/plugins/builtin/seasonality/model.ts +119 -0
- package/src/plugins/builtin/seasonality/pane.tsx +108 -37
- package/src/plugins/builtin/sec/index.tsx +5 -5
- package/src/plugins/builtin/sectors/client.ts +10 -2
- package/src/plugins/builtin/sectors/headless.ts +35 -6
- package/src/plugins/builtin/sectors/index.tsx +18 -1
- package/src/plugins/builtin/sectors/sector-model.ts +150 -41
- package/src/plugins/builtin/series-inventory.ts +91 -0
- package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
- package/src/plugins/builtin/shared/command-tab.ts +69 -0
- package/src/plugins/builtin/shared/earnings-report.ts +55 -0
- package/src/plugins/builtin/shared/fred-points.ts +20 -0
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
- package/src/plugins/builtin/shared/headless-market-data.ts +33 -1
- package/src/plugins/builtin/shared/members-menu.tsx +4 -4
- package/src/plugins/builtin/shared/open-description.ts +29 -0
- package/src/plugins/builtin/shared/report-freshness.ts +59 -2
- package/src/plugins/builtin/shared/series-warning.ts +5 -0
- package/src/plugins/builtin/shared/ticker-request.ts +25 -1
- package/src/plugins/builtin/shared/use-quote-board.ts +25 -5
- package/src/plugins/builtin/shared/volatility/options.ts +1 -46
- package/src/plugins/builtin/short-interest/headless.ts +1 -0
- package/src/plugins/builtin/short-interest/index.tsx +21 -4
- package/src/plugins/builtin/short-interest/series.ts +36 -0
- package/src/plugins/builtin/short-interest/surface.tsx +4 -4
- package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
- package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
- package/src/plugins/builtin/short-volume/headless.ts +1 -0
- package/src/plugins/builtin/short-volume/index.tsx +3 -10
- package/src/plugins/builtin/short-volume/series.ts +23 -0
- package/src/plugins/builtin/social-mentions/index.tsx +2 -0
- package/src/plugins/builtin/social-mentions/series.ts +23 -0
- package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
- package/src/plugins/builtin/supply-chain/model.ts +1 -1
- package/src/plugins/builtin/supply-chain/pane.tsx +3 -1
- package/src/plugins/builtin/thirteenf/api.ts +1 -0
- package/src/plugins/builtin/thirteenf/data.ts +6 -4
- package/src/plugins/builtin/thirteenf/headless.ts +217 -36
- package/src/plugins/builtin/thirteenf/model.ts +39 -1
- package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
- package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
- package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
- package/src/plugins/builtin/thirteenf/types.ts +2 -0
- package/src/plugins/builtin/ticker-detail/headless.ts +43 -21
- package/src/plugins/builtin/ticker-detail/index.tsx +3 -0
- package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
- package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
- package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +48 -4
- package/src/plugins/builtin/ticker-detail/pane.tsx +4 -5
- package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +94 -6
- package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
- package/src/plugins/builtin/time-sales/headless.ts +1 -0
- package/src/plugins/builtin/treasury-auctions/cache.ts +5 -2
- package/src/plugins/builtin/treasury-auctions/client.ts +22 -8
- package/src/plugins/builtin/treasury-auctions/headless.ts +56 -6
- package/src/plugins/builtin/treasury-auctions/index.tsx +12 -9
- package/src/plugins/builtin/treasury-auctions/model.ts +205 -30
- package/src/plugins/builtin/treasury-auctions/pane.tsx +35 -11
- package/src/plugins/builtin/treasury-auctions/types.ts +11 -1
- package/src/plugins/builtin/vol-surface/charts.tsx +1 -3
- package/src/plugins/builtin/vol-surface/client.ts +6 -2
- package/src/plugins/builtin/vol-surface/evidence.ts +11 -6
- package/src/plugins/builtin/vol-surface/headless.ts +125 -20
- package/src/plugins/builtin/vol-surface/model.ts +23 -11
- package/src/plugins/builtin/vol-surface/pane.tsx +38 -27
- package/src/plugins/builtin/vol-surface/tables.ts +124 -0
- package/src/plugins/builtin/volatility/index.tsx +2 -0
- package/src/plugins/builtin/volatility/series.ts +84 -0
- package/src/plugins/builtin/world-indices/client.ts +22 -4
- package/src/plugins/builtin/world-indices/headless.ts +54 -27
- package/src/plugins/builtin/world-indices/model.ts +4 -2
- package/src/plugins/builtin/world-indices/table.tsx +13 -2
- package/src/plugins/builtin/world-venue-map/geo-series.ts +27 -2
- package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -2
- package/src/plugins/builtin/world-venue-map/layered-pane.tsx +8 -4
- package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
- package/src/plugins/builtin/yield-curve/chart.ts +2 -2
- package/src/plugins/builtin/yield-curve/curves.ts +21 -8
- package/src/plugins/builtin/yield-curve/headless.ts +71 -18
- package/src/plugins/builtin/yield-curve/index.tsx +4 -2
- package/src/plugins/builtin/yield-curve/series.ts +86 -0
- package/src/plugins/builtin-editorial.ts +126 -0
- package/src/plugins/catalog-backend.ts +16 -9
- package/src/plugins/catalog-browser.ts +129 -64
- package/src/plugins/catalog-manifest.ts +73 -40
- package/src/plugins/catalog-ui.ts +26 -6
- package/src/plugins/extracted-plugins.ts +7 -1
- package/src/plugins/ownership.ts +150 -7
- package/src/plugins/plugin-functions.ts +54 -0
- package/src/plugins/plugin-off.ts +36 -0
- package/src/plugins/registry/host-actions.ts +16 -0
- package/src/plugins/registry/index.ts +173 -28
- package/src/plugins/registry/plugin-state.ts +25 -1
- package/src/plugins/runtime/context.tsx +29 -0
- package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
- package/src/portfolio/position-value.ts +40 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
- package/src/public/time-series.ts +17 -0
- package/src/react/auto-refresh.ts +13 -3
- package/src/react/input.ts +48 -1
- package/src/remote/app-host.tsx +25 -4
- package/src/remote/confirm-change.tsx +85 -0
- package/src/remote/controller-utils.ts +8 -1
- package/src/remote/controller.ts +126 -59
- package/src/remote/matching.ts +69 -0
- package/src/remote/pane-screenshot.ts +47 -0
- package/src/remote/schema.ts +63 -1
- package/src/remote/semantic-tree.tsx +14 -0
- package/src/remote/types.ts +32 -0
- package/src/remote/watchlist.ts +306 -0
- package/src/renderers/browser/main.tsx +3 -2
- package/src/renderers/cloudflare/worker.ts +1 -1
- package/src/renderers/dom/data-table/frozen-column.ts +3 -1
- package/src/renderers/dom/data-table/index.tsx +33 -6
- package/src/renderers/dom/data-table/row.tsx +27 -1
- package/src/renderers/dom/desktop/control-styles.ts +63 -1
- package/src/renderers/dom/desktop/controls.tsx +30 -23
- package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
- package/src/renderers/dom/desktop/icons.tsx +21 -0
- package/src/renderers/dom/desktop/query-bar.tsx +59 -32
- package/src/renderers/dom/dom-ui-host.tsx +3 -0
- package/src/renderers/dom/host/box.tsx +4 -1
- package/src/renderers/dom/host/chart-surface.tsx +6 -2
- package/src/renderers/dom/host/drag-shield.ts +17 -6
- package/src/renderers/dom/host/live-frame.ts +14 -2
- package/src/renderers/dom/host/overflow-fade.ts +14 -1
- package/src/renderers/dom/host/size-observer.ts +26 -0
- package/src/renderers/dom/host/surface-3d.tsx +7 -2
- package/src/renderers/dom/host/text.tsx +1 -1
- package/src/renderers/dom/input-host.tsx +6 -1
- package/src/renderers/dom/styles.css +74 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +5 -1
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +12 -1
- package/src/renderers/electrobun/bun/desktop/initialization.ts +2 -1
- package/src/renderers/electrobun/shared/protocol.ts +2 -0
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +18 -3
- package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +109 -5
- package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
- package/src/renderers/electrobun/view/main.tsx +6 -1
- package/src/renderers/opentui/input-host.tsx +6 -1
- package/src/renderers/opentui/start.tsx +9 -0
- package/src/series/capability.ts +75 -0
- package/src/series/csv.ts +160 -0
- package/src/series/files.ts +107 -0
- package/src/series/registry.ts +198 -0
- package/src/series/resolve.ts +107 -0
- package/src/series/standalone.ts +48 -0
- package/src/series/types.ts +145 -0
- package/src/series/validate.ts +171 -0
- package/src/shares/portable-layout.ts +16 -6
- package/src/sources/gloomberb-cloud/index.ts +26 -17
- package/src/sources/gloomberb-cloud/normalizers.ts +5 -1
- package/src/sources/history-result.ts +1 -0
- package/src/sources/listing-symbols.ts +14 -5
- package/src/sources/provider-errors.ts +88 -3
- package/src/sources/provider-router/batches.ts +4 -1
- package/src/sources/provider-router/cache.ts +4 -2
- package/src/sources/provider-router/cached-routes.ts +9 -5
- package/src/sources/provider-router/financial-routes.ts +12 -5
- package/src/sources/provider-router/financials.ts +55 -15
- package/src/sources/provider-router/history.ts +68 -34
- package/src/sources/provider-router/index.ts +1 -1
- package/src/sources/provider-router/primary.ts +23 -5
- package/src/sources/provider-router/search.ts +1 -0
- package/src/sources/sec-edgar.ts +68 -8
- package/src/sync/core-contributors.ts +5 -3
- package/src/test-support/cli-context.ts +2 -1
- package/src/test-support/data-provider.ts +34 -0
- package/src/test-support/shell-pane-keys.tsx +1 -0
- package/src/theme/series-colors.ts +46 -0
- package/src/theme/themes.ts +149 -0
- package/src/tickers/company-name.ts +75 -0
- package/src/tickers/instrument-kind.ts +25 -0
- package/src/tickers/open-target.ts +3 -2
- package/src/tickers/search/index.ts +67 -9
- package/src/tickers/search/ranking.ts +78 -18
- package/src/tickers/search/types.ts +10 -2
- package/src/tickers/starter-symbols.ts +8 -0
- package/src/tickers/us-listing.ts +34 -0
- package/src/time-series/hooks.ts +9 -0
- package/src/time-series/resolve.ts +96 -30
- package/src/time-series/types.ts +4 -2
- package/src/time-series/use-chart-resolution.ts +32 -0
- package/src/types/config.ts +67 -1
- package/src/types/data-provider.ts +5 -0
- package/src/types/financials.ts +52 -1
- package/src/types/headless.ts +72 -0
- package/src/types/instrument.ts +8 -0
- package/src/types/plugin.ts +68 -3
- package/src/types/price-history.ts +7 -0
- package/src/types/ticker.ts +14 -0
- package/src/ui/host.tsx +26 -4
- package/src/ui/index.tsx +2 -0
- package/src/ui/live-resize.ts +81 -0
- package/src/ui/live-stretch.ts +121 -0
- package/src/ui/measured-cells.ts +58 -0
- package/src/ui/pane-fill.ts +11 -0
- package/src/utils/basis-points.ts +17 -0
- package/src/utils/cli-output.ts +21 -2
- package/src/utils/concurrency.ts +25 -0
- package/src/utils/crypto-pair.ts +20 -0
- package/src/utils/currency-pair.ts +19 -0
- package/src/utils/decimal-comma.ts +19 -0
- package/src/utils/dom-screenshot-css.ts +265 -0
- package/src/utils/dom-screenshot-rasters.ts +276 -0
- package/src/utils/dom-screenshot.ts +437 -52
- package/src/utils/exchange-rate-snapshot.ts +6 -2
- package/src/utils/exchanges.ts +120 -1
- package/src/utils/format.ts +17 -3
- package/src/utils/fundamentals.ts +66 -0
- package/src/utils/futures-generic.ts +6 -12
- package/src/utils/fx-market-hours.ts +44 -0
- package/src/utils/option-expiry.ts +126 -0
- package/src/utils/price-history.ts +130 -40
- package/src/utils/rpc-timeout-error.ts +6 -2
- package/src/utils/sec-eps-basis.ts +178 -36
- package/src/utils/sec.ts +98 -40
- package/src/utils/throttled-fetch.ts +51 -22
- package/src/utils/utc-time.ts +51 -4
|
@@ -11,13 +11,13 @@ import { useState } from "react";
|
|
|
11
11
|
import { t } from "../i18n";
|
|
12
12
|
import { useAppLanguage } from "../i18n/react";
|
|
13
13
|
import { matchesKeyChord, parseKeyChord } from "../app/keybindings";
|
|
14
|
-
import { AuthForm, authFormTitle } from "../
|
|
15
|
-
import type { AccountMode } from "../
|
|
14
|
+
import { AuthForm, authFormTitle } from "../account/auth-form";
|
|
15
|
+
import type { AccountMode } from "../account/auth-model";
|
|
16
16
|
import {
|
|
17
17
|
DeviceSignInPanel,
|
|
18
18
|
isDeviceSignInRetryKey,
|
|
19
19
|
useDeviceSignIn,
|
|
20
|
-
} from "../
|
|
20
|
+
} from "../account/device-signin-dialog";
|
|
21
21
|
import { useShortcut, useViewport } from "../react/input";
|
|
22
22
|
import { useThemeColors } from "../theme/theme-context";
|
|
23
23
|
import { Box, Text } from "../ui";
|
|
@@ -29,6 +29,8 @@ import type { QuoteFlashDirection } from "../quote-flash";
|
|
|
29
29
|
import { objectVersion } from "../../utils/object-version";
|
|
30
30
|
import { getCompletedRegularSessionDisplay } from "../../market-data/market/status";
|
|
31
31
|
import { usePaneFooter } from "../layout/pane/footer";
|
|
32
|
+
import { Button } from "../ui/button";
|
|
33
|
+
import { PaneStatusBody } from "../ui/status";
|
|
32
34
|
|
|
33
35
|
export interface TickerTableCell {
|
|
34
36
|
text: string;
|
|
@@ -83,6 +85,13 @@ export interface TickerListTableViewProps {
|
|
|
83
85
|
rowMenuAccelerators?: Readonly<Record<string, string>>;
|
|
84
86
|
emptyTitle?: string;
|
|
85
87
|
emptyHint?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Starts the pane's add-ticker flow. Given, the empty table offers a
|
|
90
|
+
* "+ ticker" button for it and says so before the key.
|
|
91
|
+
*/
|
|
92
|
+
onAddTicker?: () => void;
|
|
93
|
+
/** The pane's key for the same flow, named after the click. The command bar's key when absent. */
|
|
94
|
+
addTickerShortcut?: string;
|
|
86
95
|
virtualize?: boolean;
|
|
87
96
|
overscan?: number;
|
|
88
97
|
}
|
|
@@ -214,11 +223,24 @@ export function TickerListTableView({
|
|
|
214
223
|
rowMenuAccelerators,
|
|
215
224
|
emptyTitle = t("No tickers."),
|
|
216
225
|
emptyHint,
|
|
226
|
+
onAddTicker,
|
|
227
|
+
addTickerShortcut,
|
|
217
228
|
virtualize = true,
|
|
218
229
|
overscan = 4,
|
|
219
230
|
}: TickerListTableViewProps) {
|
|
220
231
|
const commandBarShortcut = useCommandBarShortcut();
|
|
221
|
-
const
|
|
232
|
+
const addLabel = `+ ${t("ticker")}`;
|
|
233
|
+
const resolvedEmptyHint = emptyHint ?? (onAddTicker
|
|
234
|
+
? tf("Click {button} to add one, or press {shortcut}.", { button: addLabel, shortcut: addTickerShortcut ?? commandBarShortcut })
|
|
235
|
+
: tf("Press {shortcut} to add one.", { shortcut: commandBarShortcut }));
|
|
236
|
+
const emptyContent = onAddTicker ? (
|
|
237
|
+
<PaneStatusBody
|
|
238
|
+
empty
|
|
239
|
+
emptyTitle={emptyTitle}
|
|
240
|
+
emptyMessage={resolvedEmptyHint}
|
|
241
|
+
actions={<Button label="Add ticker" displayLabel={addLabel} compact onPress={onAddTicker} />}
|
|
242
|
+
/>
|
|
243
|
+
) : undefined;
|
|
222
244
|
const renderer = useRendererHost();
|
|
223
245
|
const { showContextMenu } = useContextMenu();
|
|
224
246
|
const { nativeContextMenu } = useUiCapabilities();
|
|
@@ -349,6 +371,7 @@ export function TickerListTableView({
|
|
|
349
371
|
getRowVersion={getRowVersion}
|
|
350
372
|
emptyStateTitle={emptyTitle}
|
|
351
373
|
emptyStateHint={resolvedEmptyHint}
|
|
374
|
+
emptyContent={emptyContent}
|
|
352
375
|
virtualize={virtualize}
|
|
353
376
|
overscan={overscan}
|
|
354
377
|
rootBefore={rootBefore}
|
|
@@ -22,7 +22,8 @@ export function ActionRow({ label, children, expanded, active, disabled, fg, ...
|
|
|
22
22
|
const foreground = disabled ? colors.textMuted : fg ?? (active ? colors.textBright : colors.text);
|
|
23
23
|
return (
|
|
24
24
|
<Button {...props} label={label} active={active} disabled={disabled} expanded={expanded} variant="plain" compact flush stopPropagation>
|
|
25
|
-
|
|
25
|
+
{/* A label of two lines reads from the left; a desktop button would centre the shorter one. */}
|
|
26
|
+
<Box flexDirection="row" width="100%" alignItems="center" gap={1} style={{ textAlign: "left" }}>
|
|
26
27
|
{expanded !== undefined && <DisclosureMarker expanded={expanded} color={foreground} width={2} />}
|
|
27
28
|
<Text fg={foreground} attributes={active ? TextAttributes.BOLD : 0}>{t(label)}</Text>
|
|
28
29
|
{children}
|
|
@@ -4,6 +4,7 @@ import { type ComponentType, type ReactNode } from "react";
|
|
|
4
4
|
import type { ThemeColors } from "../../theme/colors";
|
|
5
5
|
import { useThemeColors } from "../../theme/theme-context";
|
|
6
6
|
import { t } from "../../i18n";
|
|
7
|
+
import { displayWidth } from "../../utils/format";
|
|
7
8
|
import { useRemoteUiNode, useRemoteUiScope } from "../../remote/semantic-tree";
|
|
8
9
|
import { useScopedButtonAction } from "./action-scope";
|
|
9
10
|
|
|
@@ -27,6 +28,11 @@ export interface ButtonProps {
|
|
|
27
28
|
disabled?: boolean;
|
|
28
29
|
active?: boolean;
|
|
29
30
|
shortcut?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The key that presses it, as a keycap on the desktop and the web only: for
|
|
33
|
+
* a dialog button whose key the terminal names in the footer line instead.
|
|
34
|
+
*/
|
|
35
|
+
desktopShortcut?: string;
|
|
30
36
|
/** Tooltip, when it should say more than the label. */
|
|
31
37
|
title?: string;
|
|
32
38
|
width?: number;
|
|
@@ -66,6 +72,15 @@ function resolveButtonColors(variant: ButtonVariant, active: boolean, disabled:
|
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Terminal cells a button takes: the padded label, then its key. For a row that
|
|
77
|
+
* has to know whether its buttons fit before it lays them out.
|
|
78
|
+
*/
|
|
79
|
+
export function terminalButtonColumns({ label, displayLabel, shortcut, compact = false }: Pick<ButtonProps, "label" | "displayLabel" | "shortcut" | "compact">): number {
|
|
80
|
+
const text = displayLabel ?? t(label);
|
|
81
|
+
return displayWidth(compact ? text : ` ${text} `) + (shortcut ? 1 + displayWidth(shortcut) : 0);
|
|
82
|
+
}
|
|
83
|
+
|
|
69
84
|
export function Button({
|
|
70
85
|
label: rawLabel,
|
|
71
86
|
displayLabel,
|
|
@@ -76,6 +91,7 @@ export function Button({
|
|
|
76
91
|
disabled = false,
|
|
77
92
|
active = false,
|
|
78
93
|
shortcut,
|
|
94
|
+
desktopShortcut,
|
|
79
95
|
width,
|
|
80
96
|
height,
|
|
81
97
|
compact = false,
|
|
@@ -110,7 +126,7 @@ export function Button({
|
|
|
110
126
|
variant={variant}
|
|
111
127
|
disabled={disabled}
|
|
112
128
|
active={active}
|
|
113
|
-
shortcut={shortcut}
|
|
129
|
+
shortcut={shortcut ?? desktopShortcut}
|
|
114
130
|
title={title}
|
|
115
131
|
width={width}
|
|
116
132
|
height={height}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useEffect, useMemo, useState } from "react";
|
|
2
|
-
import { Box, Text } from "../../ui";
|
|
2
|
+
import { Box, Text, useUiHost } from "../../ui";
|
|
3
3
|
import { type PromptContext, useDialogKeyboard } from "../../ui/dialog";
|
|
4
4
|
import { useThemeColors } from "../../theme/theme-context";
|
|
5
5
|
import { t } from "../../i18n";
|
|
6
|
-
import { DialogFrame } from "./frame";
|
|
6
|
+
import { DialogFrame, fitDialogWidth } from "./frame";
|
|
7
7
|
import { ListView, listCursorMove, type ListViewItem } from "./list-view";
|
|
8
8
|
import { clampIndex } from "../../utils/math";
|
|
9
9
|
|
|
@@ -53,6 +53,7 @@ export function ChoiceDialog({
|
|
|
53
53
|
bgColor,
|
|
54
54
|
}: ChoiceDialogProps) {
|
|
55
55
|
const colors = useThemeColors();
|
|
56
|
+
const desktop = useUiHost().kind === "desktop-web";
|
|
56
57
|
const [index, setIndex] = useState(() =>
|
|
57
58
|
clampIndex(getInitialChoiceIndex(choices, selectedChoiceId), choices.length, -1)
|
|
58
59
|
);
|
|
@@ -90,7 +91,8 @@ export function ChoiceDialog({
|
|
|
90
91
|
|
|
91
92
|
return (
|
|
92
93
|
<DialogFrame title={title} footer={footer} showTitleDivider={false}>
|
|
93
|
-
|
|
94
|
+
{/* Never wider than the dialog: the terminal's box is 60 columns, a phone narrower than the cells asked for. */}
|
|
95
|
+
<Box flexDirection="column" {...(desktop ? { style: { width: fitDialogWidth(width) } } : { width, maxWidth: "100%" })}>
|
|
94
96
|
<ListView
|
|
95
97
|
items={items}
|
|
96
98
|
selectedIndex={selectedIndex}
|
|
@@ -105,7 +107,7 @@ export function ChoiceDialog({
|
|
|
105
107
|
onActivate={(_, nextIndex) => activateChoice(choices[nextIndex])}
|
|
106
108
|
/>
|
|
107
109
|
<Box height={1} />
|
|
108
|
-
<Text fg={colors.textDim} wrapText
|
|
110
|
+
<Text fg={colors.textDim} wrapText>{getChoiceDescription(selectedChoice)}</Text>
|
|
109
111
|
</Box>
|
|
110
112
|
</DialogFrame>
|
|
111
113
|
);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { useCallback, type ReactNode } from "react";
|
|
2
|
-
import { Box, Text } from "../../ui";
|
|
1
|
+
import { useCallback, useRef, type ReactNode } from "react";
|
|
2
|
+
import { Box, Text, useUiHost } from "../../ui";
|
|
3
3
|
import { colors } from "../../theme/colors";
|
|
4
4
|
import { t, tf } from "../../i18n";
|
|
5
5
|
import { type DialogApi, type PromptContext, useDialogKeyboard } from "../../ui/dialog";
|
|
6
6
|
import { isPlainKey } from "../../utils/keyboard";
|
|
7
7
|
import { Button, type ButtonVariant } from "./button";
|
|
8
|
-
import {
|
|
8
|
+
import { DialogActions } from "./dialog-actions";
|
|
9
|
+
import { DialogFrame, fitDialogWidth } from "./frame";
|
|
9
10
|
|
|
10
11
|
export interface ConfirmDialogProps extends PromptContext<boolean> {
|
|
11
12
|
title: string;
|
|
@@ -14,7 +15,10 @@ export interface ConfirmDialogProps extends PromptContext<boolean> {
|
|
|
14
15
|
cancelLabel?: string;
|
|
15
16
|
confirmVariant?: ButtonVariant;
|
|
16
17
|
width?: number;
|
|
17
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* The terminal's key-hint line under the buttons; an empty string leaves it
|
|
20
|
+
* out, and the keys off the desktop buttons too.
|
|
21
|
+
*/
|
|
18
22
|
footer?: string;
|
|
19
23
|
/** A line under the body: the work the confirm started, or why it failed. */
|
|
20
24
|
status?: ReactNode;
|
|
@@ -27,6 +31,11 @@ export interface ConfirmDialogProps extends PromptContext<boolean> {
|
|
|
27
31
|
* action, at the right. By default the action comes first, at the left.
|
|
28
32
|
*/
|
|
29
33
|
formButtons?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* How long after opening Enter and `y` do not confirm, for a confirm that
|
|
36
|
+
* opens on its own while the person may be typing. Esc and `n` always answer.
|
|
37
|
+
*/
|
|
38
|
+
keyGraceMs?: number;
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
export function ConfirmDialog({
|
|
@@ -42,7 +51,10 @@ export function ConfirmDialog({
|
|
|
42
51
|
busy = false,
|
|
43
52
|
onClose,
|
|
44
53
|
formButtons = false,
|
|
54
|
+
keyGraceMs = 0,
|
|
45
55
|
}: ConfirmDialogProps) {
|
|
56
|
+
const desktop = useUiHost().kind === "desktop-web";
|
|
57
|
+
const openedAt = useRef(Date.now());
|
|
46
58
|
const confirm = useCallback(() => resolve(true), [resolve]);
|
|
47
59
|
const cancel = useCallback(() => resolve(false), [resolve]);
|
|
48
60
|
|
|
@@ -61,6 +73,7 @@ export function ConfirmDialog({
|
|
|
61
73
|
}
|
|
62
74
|
if (event.name === "enter" || event.name === "return" || isPlainKey(event, "y")) {
|
|
63
75
|
event.preventDefault();
|
|
76
|
+
if (Date.now() - openedAt.current < keyGraceMs) return;
|
|
64
77
|
confirm();
|
|
65
78
|
return;
|
|
66
79
|
}
|
|
@@ -73,15 +86,19 @@ export function ConfirmDialog({
|
|
|
73
86
|
if (event.name === "tab") event.preventDefault();
|
|
74
87
|
}, { allowEditable: true });
|
|
75
88
|
|
|
76
|
-
|
|
77
|
-
|
|
89
|
+
// The desktop shows the keys on the buttons instead of a footer line; a
|
|
90
|
+
// confirm with no key line keeps its buttons plain there too.
|
|
91
|
+
const keys = footer !== "";
|
|
92
|
+
const confirmButton = <Button label={confirmLabel} variant={confirmVariant} disabled={busy} desktopShortcut={keys ? "Enter" : undefined} onPress={confirm} />;
|
|
93
|
+
const cancelButton = <Button label={cancelLabel} variant="secondary" disabled={busy} desktopShortcut={keys ? "Esc" : undefined} onPress={cancel} />;
|
|
78
94
|
return (
|
|
79
95
|
<DialogFrame
|
|
80
96
|
title={title}
|
|
81
97
|
footer={footer ?? tf("Enter {action} · Esc cancel", { action: t(confirmLabel).toLowerCase() })}
|
|
98
|
+
desktopFooter={null}
|
|
82
99
|
onClose={onClose}
|
|
83
100
|
>
|
|
84
|
-
<Box flexDirection="column" width
|
|
101
|
+
<Box flexDirection="column" {...(desktop ? { style: { width: fitDialogWidth(width) } } : { width })}>
|
|
85
102
|
{renderBody(body)}
|
|
86
103
|
{status && (
|
|
87
104
|
<>
|
|
@@ -90,17 +107,10 @@ export function ConfirmDialog({
|
|
|
90
107
|
</>
|
|
91
108
|
)}
|
|
92
109
|
<Box height={1} />
|
|
93
|
-
{formButtons
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
</Box>
|
|
98
|
-
) : (
|
|
99
|
-
<Box flexDirection="row" gap={1}>
|
|
100
|
-
{confirmButton}
|
|
101
|
-
{cancelButton}
|
|
102
|
-
</Box>
|
|
103
|
-
)}
|
|
110
|
+
<DialogActions alignEnd={formButtons}>
|
|
111
|
+
{formButtons ? cancelButton : confirmButton}
|
|
112
|
+
{formButtons ? confirmButton : cancelButton}
|
|
113
|
+
</DialogActions>
|
|
104
114
|
</Box>
|
|
105
115
|
</DialogFrame>
|
|
106
116
|
);
|
|
@@ -27,6 +27,8 @@ export function DataTable<T, C extends DataTableColumn = DataTableColumn>(
|
|
|
27
27
|
const renderer = useRendererHost();
|
|
28
28
|
const propsRef = useRef(props);
|
|
29
29
|
propsRef.current = props;
|
|
30
|
+
// The semantic snapshot can be taken every frame; the rows are rebuilt only when what they are drawn from changes.
|
|
31
|
+
const reportedRowsRef = useRef<{ source: readonly unknown[]; rows: ReturnType<typeof reportedRows> } | null>(null);
|
|
30
32
|
|
|
31
33
|
useEffect(() => {
|
|
32
34
|
if (!paneId || !renderer.saveTextFile) return;
|
|
@@ -90,6 +92,7 @@ export function DataTable<T, C extends DataTableColumn = DataTableColumn>(
|
|
|
90
92
|
columns: props.columns.map((column) => ({ id: column.id, label: column.label })),
|
|
91
93
|
rowCount: props.items.length,
|
|
92
94
|
selectedId: firstSelectedId(props),
|
|
95
|
+
...(props.reportEveryRow ? { rows: cachedReportedRows(props, reportedRowsRef) } : {}),
|
|
93
96
|
}),
|
|
94
97
|
});
|
|
95
98
|
// Header labels read the same in every table whatever case a pane wrote
|
|
@@ -119,6 +122,52 @@ function resolveTableIndex<T, C extends DataTableColumn>(
|
|
|
119
122
|
return resolveRemoteItemIndex(input, props.items, { id: key, key });
|
|
120
123
|
}
|
|
121
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Every row as a report reads it: the key, whether it is selected and each
|
|
127
|
+
* column's text, the same text the cells draw. Captured with the semantic
|
|
128
|
+
* snapshot, so a row scrolled out of the viewport still reaches the report.
|
|
129
|
+
* A section header sits in the first column and a time cell carries the
|
|
130
|
+
* instant behind its short text, as the capture of a drawn row reads them.
|
|
131
|
+
*/
|
|
132
|
+
function reportedRows<T, C extends DataTableColumn>(props: DataTableProps<T, C>) {
|
|
133
|
+
const normalize = (text: string) => text.replace(/\s+/g, " ").trim();
|
|
134
|
+
const first = props.columns[0];
|
|
135
|
+
return props.items.map((item, index) => {
|
|
136
|
+
const selected = props.isSelected(item, index);
|
|
137
|
+
const section = props.renderSectionHeader?.(item, index);
|
|
138
|
+
const cells = section
|
|
139
|
+
? [{
|
|
140
|
+
...(first ? { columnId: first.id } : {}),
|
|
141
|
+
columnLabel: first?.label ?? "Row",
|
|
142
|
+
text: normalize(section.action ? `${section.text} ${section.action.label}` : section.text),
|
|
143
|
+
}]
|
|
144
|
+
: props.columns.map((column) => {
|
|
145
|
+
const cell = props.renderCell(item, column, index, { selected });
|
|
146
|
+
return {
|
|
147
|
+
columnId: column.id,
|
|
148
|
+
columnLabel: column.label,
|
|
149
|
+
text: normalize(cell.text),
|
|
150
|
+
...(cell.value instanceof Date && Number.isFinite(cell.value.getTime()) ? { instant: cell.value.toISOString() } : {}),
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
return { key: props.getItemKey(item, index), selected, cells: cells.filter((cell) => cell.text.length > 0) };
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function cachedReportedRows<T, C extends DataTableColumn>(
|
|
158
|
+
props: DataTableProps<T, C>,
|
|
159
|
+
cache: { current: { source: readonly unknown[]; rows: ReturnType<typeof reportedRows> } | null },
|
|
160
|
+
) {
|
|
161
|
+
const source = [props.items, props.columns, props.renderCell, props.isSelected, props.renderSectionHeader];
|
|
162
|
+
const cached = cache.current;
|
|
163
|
+
if (cached && cached.source.length === source.length && cached.source.every((value, index) => value === source[index])) {
|
|
164
|
+
return cached.rows;
|
|
165
|
+
}
|
|
166
|
+
const rows = reportedRows(props);
|
|
167
|
+
cache.current = { source, rows };
|
|
168
|
+
return rows;
|
|
169
|
+
}
|
|
170
|
+
|
|
122
171
|
function firstSelectedId<T, C extends DataTableColumn>(props: DataTableProps<T, C>): string | null {
|
|
123
172
|
const index = props.items.findIndex((item, itemIndex) => props.isSelected(item, itemIndex));
|
|
124
173
|
const item = props.items[index];
|
|
@@ -72,11 +72,14 @@ function OpenTuiDataTableRowInner<
|
|
|
72
72
|
renderCell,
|
|
73
73
|
renderSectionHeader,
|
|
74
74
|
rowContextMenuSurface,
|
|
75
|
+
sectionWidth,
|
|
75
76
|
selected,
|
|
76
77
|
selectedTextOverridesCellColor,
|
|
77
78
|
}: {
|
|
78
79
|
/** Only compared by the row memo; see `getRowVersion`. */
|
|
79
80
|
rowVersion?: unknown;
|
|
81
|
+
/** Columns of the row in view, which a section header's action keeps to. */
|
|
82
|
+
sectionWidth: number;
|
|
80
83
|
colors: ReturnType<typeof useThemeColors>;
|
|
81
84
|
columnGap: number;
|
|
82
85
|
columnStarts: number[];
|
|
@@ -108,6 +111,7 @@ function OpenTuiDataTableRowInner<
|
|
|
108
111
|
if (sectionHeader) {
|
|
109
112
|
// A header the cursor can land on (a collapsible group) shows it like a row.
|
|
110
113
|
const headerColor = sectionHeader.color ?? (selected ? colors.selectedText : colors.textBright);
|
|
114
|
+
const action = sectionHeader.action;
|
|
111
115
|
return (
|
|
112
116
|
<Box
|
|
113
117
|
flexDirection="row"
|
|
@@ -125,12 +129,37 @@ function OpenTuiDataTableRowInner<
|
|
|
125
129
|
{sectionHeader.expanded !== undefined && (
|
|
126
130
|
<Text fg={headerColor}>{sectionHeader.expanded ? "\u25be " : "\u25b8 "}</Text>
|
|
127
131
|
)}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
{action ? (
|
|
133
|
+
// Kept to the columns in view, so a table wider than its pane does not push the action out of sight.
|
|
134
|
+
<Box flexDirection="row" height={1} flexShrink={1} minWidth={0} width={Math.max(1, sectionWidth - horizontalPadding * 2)}>
|
|
135
|
+
<Text attributes={sectionHeader.attributes ?? TextAttributes.BOLD} fg={headerColor} wrapMode="none" truncate flexShrink={1} minWidth={0}>
|
|
136
|
+
{sectionHeader.text}
|
|
137
|
+
</Text>
|
|
138
|
+
<Box flexGrow={1} minWidth={1} />
|
|
139
|
+
<Box
|
|
140
|
+
flexShrink={0}
|
|
141
|
+
height={1}
|
|
142
|
+
cursor="pointer"
|
|
143
|
+
hoverBackgroundColor={selected ? undefined : hoverBg(colors)}
|
|
144
|
+
onMouseDown={(event: any) => {
|
|
145
|
+
// The action, not the header's own press (a group's collapse).
|
|
146
|
+
event.stopPropagation?.();
|
|
147
|
+
event.preventDefault?.();
|
|
148
|
+
focusPane();
|
|
149
|
+
action.onPress();
|
|
150
|
+
}}
|
|
151
|
+
>
|
|
152
|
+
<Text fg={selected ? colors.selectedText : colors.text}>{action.label}</Text>
|
|
153
|
+
</Box>
|
|
154
|
+
</Box>
|
|
155
|
+
) : (
|
|
156
|
+
<Text
|
|
157
|
+
attributes={sectionHeader.attributes ?? TextAttributes.BOLD}
|
|
158
|
+
fg={headerColor}
|
|
159
|
+
>
|
|
160
|
+
{sectionHeader.text}
|
|
161
|
+
</Text>
|
|
162
|
+
)}
|
|
134
163
|
</Box>
|
|
135
164
|
);
|
|
136
165
|
}
|
|
@@ -320,6 +349,7 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
|
|
|
320
349
|
const horizontalScrollbarVisible = showHorizontalScrollbar
|
|
321
350
|
&& hasMeaningfulTableHorizontalOverflow(tableWidth, measuredViewportWidth, columnGap);
|
|
322
351
|
const contentWidth = fillAvailableWidth ? measuredContentWidth : tableWidth;
|
|
352
|
+
const sectionWidth = measuredViewportWidth > 0 ? Math.min(contentWidth, measuredViewportWidth) : contentWidth;
|
|
323
353
|
const displayColumns = useMemo(
|
|
324
354
|
() => expandTableColumns(columns, contentWidth, columnGap, horizontalPadding),
|
|
325
355
|
[columnGap, columns, contentWidth, horizontalPadding],
|
|
@@ -634,6 +664,7 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
|
|
|
634
664
|
renderSectionHeader={renderSectionHeader}
|
|
635
665
|
rowContextMenuSurface={rowContextMenuSurface}
|
|
636
666
|
rowVersion={getRowVersion?.(item, index)}
|
|
667
|
+
sectionWidth={sectionWidth}
|
|
637
668
|
selected={isSelected(item, index)}
|
|
638
669
|
selectedTextOverridesCellColor={selectedTextOverridesCellColor}
|
|
639
670
|
/>
|
|
@@ -58,9 +58,22 @@ export interface DataTableSectionHeader {
|
|
|
58
58
|
* `onMouseDown` instead of `onActivate`.
|
|
59
59
|
*/
|
|
60
60
|
expanded?: boolean;
|
|
61
|
+
/**
|
|
62
|
+
* A quiet control at the right end of the header that acts on the whole
|
|
63
|
+
* group, such as the preset its rows are set to. A header is not a stop for
|
|
64
|
+
* the cursor, so the pane gives the same action a key (a footer hint).
|
|
65
|
+
*/
|
|
66
|
+
action?: {
|
|
67
|
+
/** What the control says, already translated: the group's current setting. */
|
|
68
|
+
label: string;
|
|
69
|
+
/** Desktop tooltip: what pressing it does. */
|
|
70
|
+
title?: string;
|
|
71
|
+
onPress: () => void;
|
|
72
|
+
};
|
|
61
73
|
}
|
|
62
74
|
|
|
63
|
-
|
|
75
|
+
/** Where `scrollToIndex` puts its row: the nearest edge, the middle, or the top of the viewport. */
|
|
76
|
+
export type DataTableScrollAlign = "nearest" | "center" | "start";
|
|
64
77
|
|
|
65
78
|
interface DataTableRowState {
|
|
66
79
|
selected: boolean;
|
|
@@ -146,6 +159,12 @@ export interface DataTableProps<
|
|
|
146
159
|
freezeFirstColumn?: boolean;
|
|
147
160
|
/** Append export-only source records after the displayed table. */
|
|
148
161
|
getExportMetadata?: () => readonly (readonly unknown[])[];
|
|
162
|
+
/**
|
|
163
|
+
* A rendered-view report (`gloomberb fn`) reads every row, not only those
|
|
164
|
+
* the viewport shows. For a bounded table a reader needs whole, such as an
|
|
165
|
+
* option chain's strike window; leave it off for long or paged lists.
|
|
166
|
+
*/
|
|
167
|
+
reportEveryRow?: boolean;
|
|
149
168
|
scrollToIndex?: number | null;
|
|
150
169
|
scrollToIndexAlign?: DataTableScrollAlign;
|
|
151
170
|
scrollToIndexVersion?: number;
|
|
@@ -36,6 +36,8 @@ export function resolveDataTableScrollTop(
|
|
|
36
36
|
let nextTop = currentTop;
|
|
37
37
|
if (align === "center") {
|
|
38
38
|
nextTop = targetIndex - Math.floor(visibleHeight / 2);
|
|
39
|
+
} else if (align === "start") {
|
|
40
|
+
nextTop = targetIndex;
|
|
39
41
|
} else if (targetIndex < currentTop) {
|
|
40
42
|
nextTop = targetIndex;
|
|
41
43
|
} else if (targetIndex >= currentTop + visibleHeight) {
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type ComponentType, type ReactNode } from "react";
|
|
2
|
+
import { Box, Text, useUiHost } from "../../ui";
|
|
3
|
+
import { t } from "../../i18n";
|
|
4
|
+
import { useThemeColors } from "../../theme/theme-context";
|
|
5
|
+
import type { DialogDesktopFooter, DialogKeyHint } from "./frame";
|
|
6
|
+
|
|
7
|
+
export interface DialogActionsProps {
|
|
8
|
+
/** The dialog's buttons. */
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
/** The buttons sit at the right, as a form's Cancel and Submit do. */
|
|
11
|
+
alignEnd?: boolean;
|
|
12
|
+
/** Buttons that do not fit wrap to another row. */
|
|
13
|
+
wrap?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Desktop and web: keys no button carries and a quiet note, across from
|
|
16
|
+
* the buttons. The terminal says these in the dialog's footer line.
|
|
17
|
+
*/
|
|
18
|
+
hints?: DialogDesktopFooter;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The row of buttons that answers a dialog. On the desktop and the web the
|
|
23
|
+
* buttons show their keys and `hints` sit on the same row, so the dialog
|
|
24
|
+
* needs no key line under it.
|
|
25
|
+
*/
|
|
26
|
+
export function DialogActions({ children, alignEnd = false, wrap = false, hints }: DialogActionsProps) {
|
|
27
|
+
const HostDialogActions = useUiHost().DialogActions as ComponentType<DialogActionsProps> | undefined;
|
|
28
|
+
if (HostDialogActions) {
|
|
29
|
+
return <HostDialogActions alignEnd={alignEnd} wrap={wrap} hints={hints}>{children}</HostDialogActions>;
|
|
30
|
+
}
|
|
31
|
+
return (
|
|
32
|
+
<Box
|
|
33
|
+
flexDirection="row"
|
|
34
|
+
gap={1}
|
|
35
|
+
{...(alignEnd ? { justifyContent: "flex-end" as const } : {})}
|
|
36
|
+
{...(wrap ? { flexWrap: "wrap" as const } : {})}
|
|
37
|
+
>
|
|
38
|
+
{children}
|
|
39
|
+
</Box>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface DialogHintsProps {
|
|
44
|
+
keys?: DialogKeyHint[];
|
|
45
|
+
note?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Keys and a note for a dialog that has no button to put them on, such as a
|
|
50
|
+
* sign-in code waiting for a phone: keycaps on the desktop and the web, one
|
|
51
|
+
* muted line in the terminal.
|
|
52
|
+
*/
|
|
53
|
+
export function DialogHints({ keys = [], note }: DialogHintsProps) {
|
|
54
|
+
const colors = useThemeColors();
|
|
55
|
+
const HostDialogHints = useUiHost().DialogHints as ComponentType<DialogHintsProps> | undefined;
|
|
56
|
+
if (HostDialogHints) return <HostDialogHints keys={keys} note={note} />;
|
|
57
|
+
const parts = [...keys.map((hint) => `${hint.key} ${t(hint.label)}`), ...(note ? [t(note)] : [])];
|
|
58
|
+
if (parts.length === 0) return null;
|
|
59
|
+
return (
|
|
60
|
+
<Box height={1}>
|
|
61
|
+
<Text fg={colors.textMuted}>{parts.join(" · ")}</Text>
|
|
62
|
+
</Box>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import { t } from "../../i18n";
|
|
3
|
-
import { blendHex } from "../../theme/colors";
|
|
3
|
+
import { blendHex, hoverBg } from "../../theme/colors";
|
|
4
4
|
import { useThemeColors } from "../../theme/theme-context";
|
|
5
5
|
import { Box, Text, TextAttributes, useUiCapabilities } from "../../ui";
|
|
6
6
|
import { truncateToDisplayWidth } from "../../utils/format";
|
|
7
|
+
import { usePaneLinkMenuEntry } from "./external-link";
|
|
7
8
|
import { titleCase } from "./header-case";
|
|
8
9
|
import { statToneColor, type StatTone } from "./stat-grid";
|
|
9
10
|
|
|
@@ -55,11 +56,24 @@ export interface KeyValueRowProps {
|
|
|
55
56
|
width?: number;
|
|
56
57
|
labelWidth?: number;
|
|
57
58
|
emphasis?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Opens what the value names (a security's DES, a function): the whole row is the target, and inside a
|
|
61
|
+
* `PaneLinkMenu` the pane menu lists it as `link.label`, so the keyboard reaches what a click opens.
|
|
62
|
+
*/
|
|
63
|
+
link?: { label: string; onOpen: () => void };
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
/** Aligned labels and values; a bounded row reserves room for an optional detail. */
|
|
61
|
-
export function KeyValueRow({ label, value, detail, tone, color, width, labelWidth, emphasis = true }: KeyValueRowProps) {
|
|
67
|
+
export function KeyValueRow({ label, value, detail, tone, color, width, labelWidth, emphasis = true, link }: KeyValueRowProps) {
|
|
62
68
|
const colors = useThemeColors();
|
|
69
|
+
usePaneLinkMenuEntry(link ? `key-value:${label}:${value}` : null, link?.label ?? "", () => link?.onOpen());
|
|
70
|
+
const target = link ? {
|
|
71
|
+
cursor: "pointer" as const,
|
|
72
|
+
hoverBackgroundColor: hoverBg(colors),
|
|
73
|
+
onMouseDown: (event?: { button?: number }) => { if ((event?.button ?? 0) === 0) link.onOpen(); },
|
|
74
|
+
"data-gloom-interactive": "true",
|
|
75
|
+
"data-gloom-label": link.label,
|
|
76
|
+
} : {};
|
|
63
77
|
const rowWidth = width === undefined ? undefined : Math.max(0, Math.floor(width));
|
|
64
78
|
const preferredLabelWidth = Math.max(0, labelWidth ?? (rowWidth === undefined ? 14 : Math.min(12, Math.max(8, Math.floor(rowWidth * 0.32)))));
|
|
65
79
|
const labelColumns = rowWidth === undefined ? preferredLabelWidth : Math.min(preferredLabelWidth, Math.max(0, rowWidth - 1));
|
|
@@ -69,7 +83,7 @@ export function KeyValueRow({ label, value, detail, tone, color, width, labelWid
|
|
|
69
83
|
: availableWidth;
|
|
70
84
|
const detailWidth = availableWidth === undefined ? undefined : availableWidth - valueWidth!;
|
|
71
85
|
return (
|
|
72
|
-
<Box height={1} width={rowWidth} flexDirection="row" overflow="hidden" data-gloom-ui="key-value-row">
|
|
86
|
+
<Box height={1} width={rowWidth} flexDirection="row" overflow="hidden" data-gloom-ui="key-value-row" {...target}>
|
|
73
87
|
<Box width={labelColumns} flexShrink={0} overflow="hidden">
|
|
74
88
|
<Text fg={colors.textDim}>{t(label)}</Text>
|
|
75
89
|
</Box>
|
|
@@ -32,12 +32,45 @@ export function modalSurfaceStyle(colors: ThemeColors, options: ModalSurfaceOpti
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/** A key and what it does, drawn on the desktop and the web as a keycap and a word. */
|
|
36
|
+
export interface DialogKeyHint {
|
|
37
|
+
/** As the terminal names it: "Enter", "Esc", "Shift+Enter", "Tab", "↑↓", "y". */
|
|
38
|
+
key: string;
|
|
39
|
+
/** What it does, short and lowercase; translated where it is drawn. */
|
|
40
|
+
label: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* What a dialog's footer says on the desktop and the web. The buttons there
|
|
45
|
+
* carry their own keys, so this keeps only keys no button has and a quiet
|
|
46
|
+
* note, such as a deadline.
|
|
47
|
+
*/
|
|
48
|
+
export interface DialogDesktopFooter {
|
|
49
|
+
keys?: DialogKeyHint[];
|
|
50
|
+
/** After the keys; translated where it is drawn. */
|
|
51
|
+
note?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Desktop and web: the width of a dialog body laid out `columns` cells wide,
|
|
56
|
+
* narrowed to fit a phone, where the fixed width would run past the edge.
|
|
57
|
+
*/
|
|
58
|
+
export function fitDialogWidth(columns: number): string {
|
|
59
|
+
return `min(calc(var(--cell-w) * ${columns}), calc(100vw - 80px))`;
|
|
60
|
+
}
|
|
61
|
+
|
|
35
62
|
export interface DialogFrameProps {
|
|
36
63
|
title: string;
|
|
37
64
|
/** Muted line under the title. */
|
|
38
65
|
subtitle?: string;
|
|
39
66
|
children: ReactNode;
|
|
67
|
+
/** The terminal's key line under the dialog. */
|
|
40
68
|
footer?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Desktop and web: what shows instead of `footer`; `null` shows nothing.
|
|
71
|
+
* Left out, `footer` shows there as one quiet line.
|
|
72
|
+
*/
|
|
73
|
+
desktopFooter?: DialogDesktopFooter | null;
|
|
41
74
|
showTitleDivider?: boolean;
|
|
42
75
|
/** Adds a close button at the right of the title (desktop). Esc still closes every dialog. */
|
|
43
76
|
onClose?: () => void;
|
|
@@ -48,14 +81,14 @@ export interface DialogFrameProps {
|
|
|
48
81
|
shrinkable?: boolean;
|
|
49
82
|
}
|
|
50
83
|
|
|
51
|
-
export function DialogFrame({ title: rawTitle, subtitle, children, footer: rawFooter, showTitleDivider = false, onClose, shrinkable }: DialogFrameProps) {
|
|
84
|
+
export function DialogFrame({ title: rawTitle, subtitle, children, footer: rawFooter, desktopFooter, showTitleDivider = false, onClose, shrinkable }: DialogFrameProps) {
|
|
52
85
|
const title = t(rawTitle);
|
|
53
86
|
const footer = rawFooter === undefined ? undefined : t(rawFooter);
|
|
54
87
|
const colors = useThemeColors();
|
|
55
88
|
const HostDialogFrame = useUiHost().DialogFrame as ComponentType<DialogFrameProps> | undefined;
|
|
56
89
|
if (HostDialogFrame) {
|
|
57
90
|
return (
|
|
58
|
-
<HostDialogFrame title={title} subtitle={subtitle} footer={footer} showTitleDivider={showTitleDivider} onClose={onClose} shrinkable={shrinkable}>
|
|
91
|
+
<HostDialogFrame title={title} subtitle={subtitle} footer={footer} desktopFooter={desktopFooter} showTitleDivider={showTitleDivider} onClose={onClose} shrinkable={shrinkable}>
|
|
59
92
|
{children}
|
|
60
93
|
</HostDialogFrame>
|
|
61
94
|
);
|