gloomberb 0.18.3 → 0.18.4
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 +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +84 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +22 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +21 -4
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1117 -264
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +192 -47
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +19 -13
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +24 -18
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +300 -41
- package/src/cli/name-entries.ts +30 -18
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +75 -20
- package/src/cli/pane-functions/catalog.ts +24 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +10 -7
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +24 -11
- package/src/cli/pane-functions/index.ts +18 -16
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +47 -10
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +61 -16
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +111 -22
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +198 -68
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +373 -16
- package/src/components/chart/composite/interactions.ts +7 -2
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +305 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +13 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +12 -6
- package/src/components/layout/header.tsx +7 -6
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +29 -12
- package/src/i18n/ja.ts +29 -12
- package/src/i18n/ko.ts +29 -12
- package/src/i18n/zh-cn.ts +29 -12
- package/src/i18n/zh-tw.ts +29 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +107 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +76 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
- package/src/plugins/builtin/attention/pane.tsx +6 -2
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +6 -3
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +6 -8
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
- package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +79 -23
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +5 -3
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +3 -2
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +18 -11
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +68 -6
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +6 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +6 -1
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +13 -1
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +46 -7
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/headless.ts +1 -1
- package/src/plugins/builtin/insider/signals-client.ts +1 -1
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/headless.ts +4 -4
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +10 -4
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +33 -19
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +29 -8
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +49 -14
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/view.tsx +10 -10
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-scenario/client.ts +123 -28
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +36 -15
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +4 -1
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +8 -1
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +2 -1
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +21 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +5 -4
- package/src/plugins/builtin/vol-surface/headless.ts +12 -3
- package/src/plugins/builtin/vol-surface/model.ts +4 -2
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/styles.css +76 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +5 -5
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +1 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +32 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +17 -4
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +210 -33
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +14 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +76 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/index.ts +10 -5
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +3 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { useMemo, useState, type ReactNode } from "react";
|
|
2
2
|
import { useThemeColors } from "../../theme/theme-context";
|
|
3
3
|
import type { PricePoint } from "../../types/financials";
|
|
4
|
-
import { Box } from "../../ui";
|
|
4
|
+
import { Box, useUiCapabilities } from "../../ui";
|
|
5
5
|
import { compareSortValues, nextHeaderSort, type SortPreference } from "../../utils/sort-values";
|
|
6
6
|
import { DataTableStackView } from "../data-table/stack-view";
|
|
7
7
|
import { PriceSparkline } from "../price-sparkline/view";
|
|
8
8
|
import { PaneStatusBody, StatGrid, statGridRows, type DataTableColumn, type DataTableCell, type StatItem } from "../ui";
|
|
9
|
+
import { withCountryFlag, withFlagRoom } from "../ui/country-flag";
|
|
9
10
|
import { getTableWidth } from "../ui/table-layout";
|
|
10
11
|
|
|
11
12
|
export interface MarketBoardRow {
|
|
@@ -13,6 +14,11 @@ export interface MarketBoardRow {
|
|
|
13
14
|
label: string;
|
|
14
15
|
/** Secondary name shown beside the label, such as the instrument a jurisdiction sets. */
|
|
15
16
|
labelDetail?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The country the row is (a jurisdiction, a sovereign), as a code or a
|
|
19
|
+
* name: its flag leads the label on the desktop and the web.
|
|
20
|
+
*/
|
|
21
|
+
country?: string | null;
|
|
16
22
|
value: number | null;
|
|
17
23
|
valueText: string;
|
|
18
24
|
change: number | null;
|
|
@@ -138,6 +144,8 @@ export function MarketBoardStack<T extends MarketBoardRow>({ rows, width, height
|
|
|
138
144
|
labelWidth = 18, labelHeader = "INSTRUMENT", labelDetailHeader = "DETAIL", labelDetailWidth = 22, valueLabel = "LEVEL", percentileLabel = "PCTL 1Y", asOfWidth = 10, signedChange = false, extraColumns,
|
|
139
145
|
rootBefore, emptyTitle = "No observations." }: MarketBoardStackProps<T>) {
|
|
140
146
|
const colors = useThemeColors();
|
|
147
|
+
// A board of countries leads each name with its flag where one is drawn.
|
|
148
|
+
const flagged = useUiCapabilities().nativePaneChrome === true && rows.some((row) => row.country !== undefined);
|
|
141
149
|
const [sort, setSort] = useState<SortPreference<string>>({ columnId: null, direction: "asc" });
|
|
142
150
|
const items = useMemo(() => sort.columnId ? [...rows].sort((a, b) => {
|
|
143
151
|
const key = sort.columnId as "label" | "labelDetail" | "value" | "change" | "percentile" | "asOf" | "changeAsOf";
|
|
@@ -149,7 +157,7 @@ export function MarketBoardStack<T extends MarketBoardRow>({ rows, width, height
|
|
|
149
157
|
// A stale or partial row's date carries a word, so the column has room for both and the date is never cut.
|
|
150
158
|
const wordWidth = Math.max(0, ...rows.map((row) => (row.status ? STATUS_WORDS[row.status]?.length : 0) ?? 0));
|
|
151
159
|
const { columns, shortAsOf } = fitBoardColumns([
|
|
152
|
-
{ id: "label", label: labelHeader, width: labelWidth, align: "left" },
|
|
160
|
+
withFlagRoom({ id: "label", label: labelHeader, width: labelWidth, align: "left" }, flagged),
|
|
153
161
|
...(rows.some((row) => row.labelDetail !== undefined)
|
|
154
162
|
? [{ id: "labelDetail", label: labelDetailHeader, width: labelDetailWidth, align: "left" as const }] : []),
|
|
155
163
|
{ id: "value", label: valueLabel, width: valueWidth, align: "right" },
|
|
@@ -164,7 +172,7 @@ export function MarketBoardStack<T extends MarketBoardRow>({ rows, width, height
|
|
|
164
172
|
const extra = extraColumns?.find((item) => item.column.id === column.id);
|
|
165
173
|
if (extra) return extra.renderCell(row);
|
|
166
174
|
const muted = row.status === "unavailable" ? colors.textDim : colors.text;
|
|
167
|
-
if (column.id === "label") return { text: row.label, color: muted };
|
|
175
|
+
if (column.id === "label") return withCountryFlag({ text: row.label, color: muted }, row.country, flagged);
|
|
168
176
|
if (column.id === "labelDetail") return { text: row.labelDetail ?? "", color: colors.textMuted };
|
|
169
177
|
if (column.id === "value") return { text: row.valueText, color: muted };
|
|
170
178
|
if (column.id === "change") return { text: row.changeText,
|
|
@@ -161,6 +161,7 @@ function useOnboardingWizard({ pluginRegistry, importBrokerPositions, onComplete
|
|
|
161
161
|
importBrokerPositions,
|
|
162
162
|
getConfig: () => stateRef.current.config,
|
|
163
163
|
createBrokerInstance: (brokerType, label, values) => pluginRegistry.createBrokerInstance(brokerType, label, values),
|
|
164
|
+
enableBrokerInstance: (instanceId) => pluginRegistry.updateBrokerInstance(instanceId, {}, { enabled: true }),
|
|
164
165
|
onSynced: handleBrokerSynced,
|
|
165
166
|
setEditingField,
|
|
166
167
|
setPortfolioSub,
|
|
@@ -91,13 +91,13 @@ export function BrokerSetupPanel({
|
|
|
91
91
|
<Text fg={colors.textDim}>{t(" Enable \"ActiveX and Socket Clients\"")}</Text>
|
|
92
92
|
</Box>
|
|
93
93
|
<Box height={desktop ? 1 : 2} overflow="hidden">
|
|
94
|
-
<Text fg={colors.textDim}>{t("
|
|
94
|
+
<Text fg={colors.textDim}>{t(" Gloom can auto-detect local API ports (4001, 4002, 7496, 7497)")}</Text>
|
|
95
95
|
</Box>
|
|
96
96
|
<Box height={desktop ? 1 : 2} overflow="hidden">
|
|
97
97
|
<Text fg={colors.textDim}>{t(" Use Manual setup only if you need a custom host or exact socket port")}</Text>
|
|
98
98
|
</Box>
|
|
99
99
|
<Box height={1}>
|
|
100
|
-
<Text fg={colors.textDim}>{t("4. Keep it running while using
|
|
100
|
+
<Text fg={colors.textDim}>{t("4. Keep it running while using Gloom")}</Text>
|
|
101
101
|
</Box>
|
|
102
102
|
<Box height={desktop ? 2 : 1} />
|
|
103
103
|
<GuideLink url={IBKR_GATEWAY_DOWNLOAD_URL} />
|
|
@@ -59,6 +59,7 @@ export function useOnboardingBrokerSync({
|
|
|
59
59
|
importBrokerPositions,
|
|
60
60
|
getConfig,
|
|
61
61
|
createBrokerInstance,
|
|
62
|
+
enableBrokerInstance,
|
|
62
63
|
onSynced,
|
|
63
64
|
setEditingField,
|
|
64
65
|
setPortfolioSub,
|
|
@@ -71,6 +72,7 @@ export function useOnboardingBrokerSync({
|
|
|
71
72
|
/** The live config and profile creation, for the signed-in path that Add Broker shares. */
|
|
72
73
|
getConfig: () => AppConfig;
|
|
73
74
|
createBrokerInstance: (brokerType: string, label: string, values: Record<string, unknown>) => Promise<BrokerInstanceConfig>;
|
|
75
|
+
enableBrokerInstance: (instanceId: string) => Promise<void>;
|
|
74
76
|
onSynced: (result: SyncBrokerInstanceResult, config: AppConfig) => void | Promise<void>;
|
|
75
77
|
setEditingField: (editing: boolean) => void;
|
|
76
78
|
setPortfolioSub: Dispatch<SetStateAction<PortfolioSub>>;
|
|
@@ -227,6 +229,7 @@ export function useOnboardingBrokerSync({
|
|
|
227
229
|
const connected = await connectSignedInBrokerProfile(broker, {
|
|
228
230
|
getConfig,
|
|
229
231
|
createBrokerInstance,
|
|
232
|
+
enableBrokerInstance,
|
|
230
233
|
syncBrokerInstance: (instanceId) => {
|
|
231
234
|
if (brokerSyncAttemptRef.current === attemptId) showSyncing();
|
|
232
235
|
return importInto(instanceId, attemptId, abortController.signal);
|
|
@@ -237,7 +240,7 @@ export function useOnboardingBrokerSync({
|
|
|
237
240
|
} catch (error) {
|
|
238
241
|
failSync(attemptId, error);
|
|
239
242
|
}
|
|
240
|
-
}, [beginAttempt, createBrokerInstance, failSync, finishSync, getConfig, importInto, setEditingField, showSyncing]);
|
|
243
|
+
}, [beginAttempt, createBrokerInstance, enableBrokerInstance, failSync, finishSync, getConfig, importInto, setEditingField, showSyncing]);
|
|
241
244
|
|
|
242
245
|
const syncSelectedBroker = useCallback(async (brokerValueOverrides?: Record<string, string>) => {
|
|
243
246
|
const signedIn = brokerOptions.find((option) => option.id === selectedBrokerId)?.signedIn;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { Box, Text } from "../../ui";
|
|
2
2
|
import { useEffect, useId, type ReactNode } from "react";
|
|
3
|
-
import type { PaneSettingField } from "../../types/plugin";
|
|
3
|
+
import type { PaneSettingField, PaneSettingRowNote } from "../../types/plugin";
|
|
4
4
|
import { colors } from "../../theme/colors";
|
|
5
5
|
import { SelectField, type SelectFieldHandle } from "../ui/select-field";
|
|
6
6
|
import { Checkbox } from "../ui/checkbox";
|
|
7
7
|
import { Button } from "../ui/button";
|
|
8
8
|
import { Badge } from "../ui/display";
|
|
9
9
|
import { DialogFrame } from "../ui/frame";
|
|
10
|
-
import { isPaneSettingDisabled, summarizePaneSettingValue } from "./value";
|
|
10
|
+
import { isPaneSettingDisabled, noteColor, summarizePaneSettingValue } from "./value";
|
|
11
11
|
|
|
12
12
|
const DESKTOP_TEXT_STYLE = {
|
|
13
13
|
letterSpacing: 0,
|
|
@@ -74,6 +74,7 @@ function DesktopSettingsRow({
|
|
|
74
74
|
field,
|
|
75
75
|
selected,
|
|
76
76
|
currentValue,
|
|
77
|
+
note,
|
|
77
78
|
onHover,
|
|
78
79
|
onEdit,
|
|
79
80
|
onSelectRef,
|
|
@@ -82,6 +83,8 @@ function DesktopSettingsRow({
|
|
|
82
83
|
field: PaneSettingField;
|
|
83
84
|
selected: boolean;
|
|
84
85
|
currentValue: unknown;
|
|
86
|
+
/** What its action said on it: the state beside its button, the reason in place of its description. */
|
|
87
|
+
note: PaneSettingRowNote | null;
|
|
85
88
|
onHover: () => void;
|
|
86
89
|
onEdit: () => void;
|
|
87
90
|
onSelectRef: (fieldKey: string, element: SelectFieldHandle | null) => void;
|
|
@@ -91,6 +94,7 @@ function DesktopSettingsRow({
|
|
|
91
94
|
const disabled = isPaneSettingDisabled(field);
|
|
92
95
|
const rowId = useFollowHighlight(selected);
|
|
93
96
|
const summary = summarizePaneSettingValue(field, currentValue);
|
|
97
|
+
const description = note?.text ?? field.description;
|
|
94
98
|
const control = field.type === "toggle" ? (
|
|
95
99
|
<Checkbox label={field.label} displayLabel="" checked={currentValue === true} onChange={(checked) => onApply(field, checked)} />
|
|
96
100
|
) : field.type === "select" ? (
|
|
@@ -104,7 +108,10 @@ function DesktopSettingsRow({
|
|
|
104
108
|
/>
|
|
105
109
|
) : field.type === "action" ? (
|
|
106
110
|
// The button says what pressing the row does, and presses it: the row's own press is not repeated.
|
|
107
|
-
<
|
|
111
|
+
<Box flexDirection="row" alignItems="center" gap={1}>
|
|
112
|
+
{note ? <Text fg={noteColor(note)} style={desktopText()}>{note.status}</Text> : null}
|
|
113
|
+
<Button label={summary} variant="secondary" disabled={disabled} onPress={onEdit} stopPropagation />
|
|
114
|
+
</Box>
|
|
108
115
|
) : (
|
|
109
116
|
<Box flexDirection="row" alignItems="center" gap={1}>
|
|
110
117
|
<Badge label={summary} />
|
|
@@ -116,7 +123,7 @@ function DesktopSettingsRow({
|
|
|
116
123
|
<Box
|
|
117
124
|
id={rowId}
|
|
118
125
|
flexDirection="column"
|
|
119
|
-
minHeight={
|
|
126
|
+
minHeight={description ? undefined : 2}
|
|
120
127
|
data-gloom-role="pane-setting-row"
|
|
121
128
|
data-selected={selected ? "true" : "false"}
|
|
122
129
|
backgroundColor={selected ? "var(--gloom-hover-fill)" : "transparent"}
|
|
@@ -143,9 +150,9 @@ function DesktopSettingsRow({
|
|
|
143
150
|
</Box>
|
|
144
151
|
{control}
|
|
145
152
|
</Box>
|
|
146
|
-
{
|
|
147
|
-
<Text fg={colors.textMuted} wrapText style={desktopText()}>
|
|
148
|
-
{
|
|
153
|
+
{description && (
|
|
154
|
+
<Text fg={note?.text ? noteColor(note) : colors.textMuted} wrapText style={desktopText()}>
|
|
155
|
+
{description}
|
|
149
156
|
</Text>
|
|
150
157
|
)}
|
|
151
158
|
</Box>
|
|
@@ -156,6 +163,7 @@ function DesktopSettingsList({
|
|
|
156
163
|
fields,
|
|
157
164
|
selectedIndex,
|
|
158
165
|
settings,
|
|
166
|
+
noteFor,
|
|
159
167
|
onHover,
|
|
160
168
|
onEdit,
|
|
161
169
|
onSelectRef,
|
|
@@ -164,6 +172,7 @@ function DesktopSettingsList({
|
|
|
164
172
|
fields: PaneSettingField[];
|
|
165
173
|
selectedIndex: number;
|
|
166
174
|
settings: Record<string, unknown>;
|
|
175
|
+
noteFor?: (field: PaneSettingField) => PaneSettingRowNote | null;
|
|
167
176
|
onHover: (field: PaneSettingField, index: number) => void;
|
|
168
177
|
onEdit: (field: PaneSettingField, index: number) => void;
|
|
169
178
|
onSelectRef: (fieldKey: string, element: SelectFieldHandle | null) => void;
|
|
@@ -182,6 +191,7 @@ function DesktopSettingsList({
|
|
|
182
191
|
field={field}
|
|
183
192
|
selected={index === selectedIndex}
|
|
184
193
|
currentValue={settings[field.key]}
|
|
194
|
+
note={noteFor?.(field) ?? null}
|
|
185
195
|
onHover={() => onHover(field, index)}
|
|
186
196
|
onEdit={() => onEdit(field, index)}
|
|
187
197
|
onSelectRef={onSelectRef}
|
|
@@ -208,6 +218,7 @@ export function DesktopPaneSettingsDialogBody({
|
|
|
208
218
|
fields,
|
|
209
219
|
selectedIndex,
|
|
210
220
|
settings,
|
|
221
|
+
noteFor,
|
|
211
222
|
onHover,
|
|
212
223
|
onEdit,
|
|
213
224
|
onSelectRef,
|
|
@@ -218,6 +229,7 @@ export function DesktopPaneSettingsDialogBody({
|
|
|
218
229
|
fields: PaneSettingField[];
|
|
219
230
|
selectedIndex: number;
|
|
220
231
|
settings: Record<string, unknown>;
|
|
232
|
+
noteFor?: (field: PaneSettingField) => PaneSettingRowNote | null;
|
|
221
233
|
onHover: (field: PaneSettingField, index: number) => void;
|
|
222
234
|
onEdit: (field: PaneSettingField, index: number) => void;
|
|
223
235
|
onSelectRef: (fieldKey: string, element: SelectFieldHandle | null) => void;
|
|
@@ -237,6 +249,7 @@ export function DesktopPaneSettingsDialogBody({
|
|
|
237
249
|
fields={fields}
|
|
238
250
|
selectedIndex={selectedIndex}
|
|
239
251
|
settings={settings}
|
|
252
|
+
noteFor={noteFor}
|
|
240
253
|
onHover={onHover}
|
|
241
254
|
onEdit={onEdit}
|
|
242
255
|
onSelectRef={onSelectRef}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Box, Text } from "../../ui";
|
|
2
2
|
import { t } from "../../i18n";
|
|
3
3
|
import { TextAttributes } from "../../ui";
|
|
4
|
-
import type { PaneSettingField } from "../../types/plugin";
|
|
4
|
+
import type { PaneSettingField, PaneSettingRowNote } from "../../types/plugin";
|
|
5
5
|
import { colors } from "../../theme/colors";
|
|
6
6
|
import { useViewport } from "../../react/input";
|
|
7
7
|
import { DialogFrame, ListView } from "../ui";
|
|
8
8
|
import type { ListViewProps } from "../ui/list-view";
|
|
9
|
-
import { isPaneSettingDisabled, summarizePaneSettingValue } from "./value";
|
|
9
|
+
import { isPaneSettingDisabled, noteColor, summarizePaneSettingValue } from "./value";
|
|
10
10
|
|
|
11
11
|
/** Terminal rows a settings dialog spends around its list: edge, frame, title, description. */
|
|
12
12
|
const TUI_DIALOG_LIST_CHROME_ROWS = 11;
|
|
@@ -21,7 +21,10 @@ export function useTuiDialogListRows(): number {
|
|
|
21
21
|
* for it scrolls to the cursor instead of running under the dialog's edge,
|
|
22
22
|
* and the highlighted row's description sits under it.
|
|
23
23
|
*/
|
|
24
|
-
export function TuiDialogList(props: ListViewProps
|
|
24
|
+
export function TuiDialogList({ descriptionColor, ...props }: ListViewProps & {
|
|
25
|
+
/** The highlighted row's description in a tone: what its action ran into. */
|
|
26
|
+
descriptionColor?: (index: number) => string | undefined;
|
|
27
|
+
}) {
|
|
25
28
|
const maxRows = useTuiDialogListRows();
|
|
26
29
|
const scrollable = props.items.length > maxRows;
|
|
27
30
|
const description = props.selectedIndex >= 0 ? props.items[props.selectedIndex]?.description : undefined;
|
|
@@ -37,7 +40,7 @@ export function TuiDialogList(props: ListViewProps) {
|
|
|
37
40
|
<>
|
|
38
41
|
<Box height={1} />
|
|
39
42
|
<Box>
|
|
40
|
-
<Text fg={colors.textDim}>{" "}{t(description)}</Text>
|
|
43
|
+
<Text fg={descriptionColor?.(props.selectedIndex) ?? colors.textDim}>{" "}{t(description)}</Text>
|
|
41
44
|
</Box>
|
|
42
45
|
</>
|
|
43
46
|
)}
|
|
@@ -58,6 +61,7 @@ export function TuiPaneSettingsDialogBody({
|
|
|
58
61
|
fields,
|
|
59
62
|
selectedIndex,
|
|
60
63
|
settings,
|
|
64
|
+
noteFor,
|
|
61
65
|
onSelect,
|
|
62
66
|
onActivate,
|
|
63
67
|
}: {
|
|
@@ -65,26 +69,30 @@ export function TuiPaneSettingsDialogBody({
|
|
|
65
69
|
fields: PaneSettingField[];
|
|
66
70
|
selectedIndex: number;
|
|
67
71
|
settings: Record<string, unknown>;
|
|
72
|
+
/** What an action said on its own row: its state in place of the row's value, its reason in place of the description. */
|
|
73
|
+
noteFor?: (field: PaneSettingField) => PaneSettingRowNote | null;
|
|
68
74
|
onSelect: (index: number) => void;
|
|
69
75
|
onActivate: (field: PaneSettingField | undefined) => void;
|
|
70
76
|
}) {
|
|
77
|
+
const notes = fields.map((field) => noteFor?.(field) ?? null);
|
|
71
78
|
return (
|
|
72
79
|
<DialogFrame title={t(title)}>
|
|
73
80
|
<TuiDialogList
|
|
74
|
-
items={fields.map((field) => ({
|
|
81
|
+
items={fields.map((field, index) => ({
|
|
75
82
|
id: field.key,
|
|
76
83
|
label: t(field.label),
|
|
77
|
-
description: field.description ? t(field.description) : field.description,
|
|
78
|
-
detail: summarizePaneSettingValue(field, settings[field.key]),
|
|
84
|
+
description: notes[index]?.text ?? (field.description ? t(field.description) : field.description),
|
|
85
|
+
detail: notes[index]?.status ?? summarizePaneSettingValue(field, settings[field.key]),
|
|
79
86
|
disabled: isPaneSettingDisabled(field),
|
|
80
87
|
}))}
|
|
88
|
+
descriptionColor={(index) => (notes[index]?.text ? noteColor(notes[index]) : undefined)}
|
|
81
89
|
selectedIndex={selectedIndex}
|
|
82
90
|
bgColor={colors.commandBg}
|
|
83
91
|
onSelect={onSelect}
|
|
84
92
|
onActivate={(_, index) => {
|
|
85
93
|
onActivate(fields[index]);
|
|
86
94
|
}}
|
|
87
|
-
renderRow={(item, rowState) => (
|
|
95
|
+
renderRow={(item, rowState, index) => (
|
|
88
96
|
<Box flexDirection="row" justifyContent="space-between" width="100%">
|
|
89
97
|
<Box flexDirection="row">
|
|
90
98
|
<Text fg={rowState.selected ? colors.selectedText : colors.textDim}>
|
|
@@ -97,7 +105,7 @@ export function TuiPaneSettingsDialogBody({
|
|
|
97
105
|
{item.label}
|
|
98
106
|
</Text>
|
|
99
107
|
</Box>
|
|
100
|
-
<Text fg={colors.textMuted}>
|
|
108
|
+
<Text fg={noteColor(notes[index]) ?? colors.textMuted}>
|
|
101
109
|
{item.detail}
|
|
102
110
|
</Text>
|
|
103
111
|
</Box>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { PaneSettingField } from "../../types/plugin";
|
|
1
|
+
import type { PaneSettingField, PaneSettingRowNote } from "../../types/plugin";
|
|
2
2
|
import { t } from "../../i18n";
|
|
3
|
+
import { colors } from "../../theme/colors";
|
|
3
4
|
|
|
4
5
|
export function isSpaceKey(event: { name?: string; sequence?: string }): boolean {
|
|
5
6
|
return event.name === "space" || event.name === " " || event.sequence === " ";
|
|
@@ -10,6 +11,12 @@ export function isPaneSettingDisabled(field: PaneSettingField): boolean {
|
|
|
10
11
|
return field.type === "action" && field.disabled === true;
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
/** A row note's tone, for its state and its reason. */
|
|
15
|
+
export function noteColor(note: PaneSettingRowNote | null | undefined): string | undefined {
|
|
16
|
+
if (!note) return undefined;
|
|
17
|
+
return note.tone === "negative" ? colors.negative : colors.warning;
|
|
18
|
+
}
|
|
19
|
+
|
|
13
20
|
export function summarizePaneSettingValue(field: PaneSettingField, value: unknown): string {
|
|
14
21
|
switch (field.type) {
|
|
15
22
|
case "action":
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useUiCapabilities } from "../ui";
|
|
2
2
|
import { type AlertContext, useDialog, useDialogKeyboard } from "../ui/dialog";
|
|
3
3
|
import { useEffect, useRef, useState } from "react";
|
|
4
|
-
import type { PaneSettingField } from "../types/plugin";
|
|
4
|
+
import type { PaneSettingField, PaneSettingRowNote } from "../types/plugin";
|
|
5
5
|
import type { PluginRegistry } from "../plugins/registry";
|
|
6
6
|
import { isPlainKey } from "../utils/keyboard";
|
|
7
7
|
import { openSelectField, type SelectFieldHandle } from "./ui/select-field";
|
|
@@ -20,6 +20,13 @@ import {
|
|
|
20
20
|
TuiUnavailablePaneSettingsDialog,
|
|
21
21
|
} from "./pane-settings-dialog/tui";
|
|
22
22
|
import { isPaneSettingDisabled, isSpaceKey, stepPaneSettingSelect } from "./pane-settings-dialog/value";
|
|
23
|
+
import { useRowNotes } from "./ui/row-notes";
|
|
24
|
+
|
|
25
|
+
const fieldKey = (field: PaneSettingField) => field.key;
|
|
26
|
+
/** What an action row shows of its own state: a note on it goes once that moves on (it connected elsewhere, say). */
|
|
27
|
+
const actionRowSignature = (field: PaneSettingField) => (
|
|
28
|
+
field.type === "action" ? `${field.actionLabel ?? ""}\u0000${field.description ?? ""}\u0000${field.disabled === true}` : ""
|
|
29
|
+
);
|
|
23
30
|
|
|
24
31
|
interface PaneSettingsDialogContentProps extends AlertContext {
|
|
25
32
|
paneId: string;
|
|
@@ -48,6 +55,11 @@ export function PaneSettingsDialogContent({
|
|
|
48
55
|
});
|
|
49
56
|
const [, setSettingsRevision] = useState(0);
|
|
50
57
|
const desktopSelectRefs = useRef(new Map<string, SelectFieldHandle>());
|
|
58
|
+
// What an action said on its own row (setRowNote), while the dialog is open.
|
|
59
|
+
const { noteFor, setNote: setRowNote } = useRowNotes<PaneSettingField, PaneSettingRowNote>(fields, { key: fieldKey, signature: actionRowSignature });
|
|
60
|
+
const running = useRef(new Set<string>());
|
|
61
|
+
const mounted = useRef(true);
|
|
62
|
+
useEffect(() => () => { mounted.current = false; }, []);
|
|
51
63
|
|
|
52
64
|
useEffect(() => {
|
|
53
65
|
if (selectedIndex < fields.length) return;
|
|
@@ -68,24 +80,41 @@ export function PaneSettingsDialogContent({
|
|
|
68
80
|
const openFieldEditor = async (field: PaneSettingField | undefined) => {
|
|
69
81
|
if (!field || !descriptor) return;
|
|
70
82
|
if (field.type === "action") {
|
|
71
|
-
|
|
83
|
+
// A row whose action is still running is not run again.
|
|
84
|
+
if (field.disabled || running.current.has(field.key)) return;
|
|
72
85
|
let closed = false;
|
|
73
86
|
const close = () => {
|
|
74
87
|
if (closed) return;
|
|
75
88
|
closed = true;
|
|
76
89
|
dismiss();
|
|
77
90
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
running.current.add(field.key);
|
|
92
|
+
setRowNote(field.key, null);
|
|
93
|
+
try {
|
|
94
|
+
await field.action({
|
|
95
|
+
...descriptor.context,
|
|
96
|
+
surface: "pane-dialog",
|
|
97
|
+
close,
|
|
98
|
+
openCommandBar: (query) => {
|
|
99
|
+
close();
|
|
100
|
+
queueMicrotask(() => pluginRegistry.openCommandBar(query));
|
|
101
|
+
},
|
|
102
|
+
notify: (notification) => pluginRegistry.notify(notification),
|
|
103
|
+
setRowNote: (note) => {
|
|
104
|
+
// The row is off screen once the dialog has closed, or once its field has left the settings (an
|
|
105
|
+
// account that disconnected and has nothing left to connect). The settings are read again here, as
|
|
106
|
+
// the action may have changed them since the dialog last drew.
|
|
107
|
+
if (closed || !mounted.current) return false;
|
|
108
|
+
const current = pluginRegistry.resolvePaneSettings(paneId)?.settingsDef.fields ?? [];
|
|
109
|
+
if (!current.some((entry) => entry.key === field.key)) return false;
|
|
110
|
+
setRowNote(field.key, note);
|
|
111
|
+
return true;
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
} finally {
|
|
115
|
+
running.current.delete(field.key);
|
|
116
|
+
}
|
|
117
|
+
if (!closed && mounted.current) setSettingsRevision((revision) => revision + 1);
|
|
89
118
|
return;
|
|
90
119
|
}
|
|
91
120
|
const currentValue = descriptor.context.settings[field.key];
|
|
@@ -191,6 +220,7 @@ export function PaneSettingsDialogContent({
|
|
|
191
220
|
fields={fields}
|
|
192
221
|
selectedIndex={selectedIndex}
|
|
193
222
|
settings={descriptor.context.settings}
|
|
223
|
+
noteFor={noteFor}
|
|
194
224
|
onHover={(_field, index) => setSelectedIndex(index)}
|
|
195
225
|
onSelectRef={setDesktopSelectRef}
|
|
196
226
|
onEdit={(field, index) => {
|
|
@@ -208,6 +238,7 @@ export function PaneSettingsDialogContent({
|
|
|
208
238
|
fields={fields}
|
|
209
239
|
selectedIndex={selectedIndex}
|
|
210
240
|
settings={descriptor.context.settings}
|
|
241
|
+
noteFor={noteFor}
|
|
211
242
|
onSelect={setSelectedIndex}
|
|
212
243
|
onActivate={(field) => {
|
|
213
244
|
void openFieldEditor(field).catch(() => {});
|
|
@@ -42,7 +42,14 @@ export function desktopQrModulePx(modules: number, availablePx: number, cellHeig
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
interface SignInCodePanelProps {
|
|
45
|
+
/** The page the browser button opens. */
|
|
45
46
|
url: string | null;
|
|
47
|
+
/**
|
|
48
|
+
* The link shown and drawn as the QR code, when it differs from `url`: a
|
|
49
|
+
* short link that leads to the same page. Null shows neither, for a page
|
|
50
|
+
* whose own address is too long to read or scan. Defaults to `url`.
|
|
51
|
+
*/
|
|
52
|
+
link?: string | null;
|
|
46
53
|
/**
|
|
47
54
|
* A code to show under the QR code: Gloom's own sign-in compares it with
|
|
48
55
|
* the page it opens. A broker connect shows none.
|
|
@@ -62,10 +69,10 @@ interface SignInCodePanelProps {
|
|
|
62
69
|
|
|
63
70
|
/**
|
|
64
71
|
* A browser hand-off: button, QR code, an optional short code, the URL, and a
|
|
65
|
-
* live status. Used to sign in to Gloom
|
|
66
|
-
* height: the QR needs its full module grid in the
|
|
67
|
-
* terminals drop decoration first and finally fall back to
|
|
68
|
-
* which works over SSH too. The desktop draws the QR as an image in whole
|
|
72
|
+
* live status. Used to sign in to Gloom, to connect a broker and to finish a
|
|
73
|
+
* Pro checkout. Degrades by height: the QR needs its full module grid in the
|
|
74
|
+
* terminal, so short terminals drop decoration first and finally fall back to
|
|
75
|
+
* the URL (and code), which works over SSH too. The desktop draws the QR as an image in whole
|
|
69
76
|
* pixel modules, smaller when the rows run out.
|
|
70
77
|
*/
|
|
71
78
|
export function SignInCodePanel(props: SignInCodePanelProps) {
|
|
@@ -86,17 +93,18 @@ export function SignInCodePanel(props: SignInCodePanelProps) {
|
|
|
86
93
|
}} />
|
|
87
94
|
)
|
|
88
95
|
: null;
|
|
96
|
+
const link = props.link === undefined ? url : props.link;
|
|
89
97
|
return desktop
|
|
90
|
-
? <DesktopPanel {...props} button={button} />
|
|
91
|
-
: <TerminalPanel {...props} button={button} />;
|
|
98
|
+
? <DesktopPanel {...props} link={link} button={button} />
|
|
99
|
+
: <TerminalPanel {...props} link={link} button={button} />;
|
|
92
100
|
}
|
|
93
101
|
|
|
94
|
-
type PanelBodyProps = SignInCodePanelProps & { button: React.ReactNode };
|
|
102
|
+
type PanelBodyProps = Omit<SignInCodePanelProps, "link"> & { link: string | null; button: React.ReactNode };
|
|
95
103
|
|
|
96
104
|
/** Laid out by the browser: a QR image in whole-pixel modules, the code as a figure. */
|
|
97
|
-
function DesktopPanel({
|
|
105
|
+
function DesktopPanel({ link, code, status, height, button }: PanelBodyProps) {
|
|
98
106
|
const { cellHeightPx = 18 } = useUiCapabilities();
|
|
99
|
-
const qr = useMemo(() => (
|
|
107
|
+
const qr = useMemo(() => (link ? renderQrSvgDataUri(link) : null), [link]);
|
|
100
108
|
const besideQr = DESKTOP_ROWS_BESIDE_QR + (code ? DESKTOP_CODE_ROWS : 0);
|
|
101
109
|
const modulePx = qr ? desktopQrModulePx(qr.modules, (height - besideQr) * cellHeightPx, cellHeightPx) : null;
|
|
102
110
|
const qrPx = qr && modulePx ? modulePx * qr.modules : 0;
|
|
@@ -119,7 +127,7 @@ function DesktopPanel({ url, code, status, height, button }: PanelBodyProps) {
|
|
|
119
127
|
}}
|
|
120
128
|
/>
|
|
121
129
|
)}
|
|
122
|
-
{
|
|
130
|
+
{link && !qrPx && (
|
|
123
131
|
<Box marginTop={1}>
|
|
124
132
|
<Text fg={colors.textDim}>{t("Not enough room to draw the QR code.")}</Text>
|
|
125
133
|
</Box>
|
|
@@ -129,9 +137,9 @@ function DesktopPanel({ url, code, status, height, button }: PanelBodyProps) {
|
|
|
129
137
|
<FigureText>{code}</FigureText>
|
|
130
138
|
</Box>
|
|
131
139
|
)}
|
|
132
|
-
{
|
|
140
|
+
{link && (
|
|
133
141
|
<Box marginTop={code ? 0 : 1} maxWidth="100%">
|
|
134
|
-
<Text fg={colors.textMuted} wrapText selectable style={{ textAlign: "center" }}>{
|
|
142
|
+
<Text fg={colors.textMuted} wrapText selectable style={{ textAlign: "center" }}>{link}</Text>
|
|
135
143
|
</Box>
|
|
136
144
|
)}
|
|
137
145
|
<Box marginTop={1}>
|
|
@@ -142,16 +150,16 @@ function DesktopPanel({ url, code, status, height, button }: PanelBodyProps) {
|
|
|
142
150
|
}
|
|
143
151
|
|
|
144
152
|
/** Laid out in cells: half-block QR lines need their full grid, so short terminals drop rows first. */
|
|
145
|
-
function TerminalPanel({
|
|
146
|
-
const qrLines = useMemo(() => (
|
|
153
|
+
function TerminalPanel({ link, code, status, height, button }: PanelBodyProps) {
|
|
154
|
+
const qrLines = useMemo(() => (link ? renderQrLines(link) : []), [link]);
|
|
147
155
|
// Reserve the browser button before fitting the QR, code, and status.
|
|
148
|
-
const contentHeight = height - (
|
|
156
|
+
const contentHeight = height - (button ? 2 : 0);
|
|
149
157
|
const codeRows = code ? 1 : 0;
|
|
150
158
|
const showQr = qrLines.length > 0 && contentHeight >= qrLines.length + codeRows + 1;
|
|
151
159
|
const qrRows = showQr ? qrLines.length : 0;
|
|
152
160
|
// A blank row before the code, the link and the status when there is room.
|
|
153
|
-
const spacious = showQr && contentHeight >= qrRows + codeRows * 2 + (
|
|
154
|
-
const showUrl = !!
|
|
161
|
+
const spacious = showQr && contentHeight >= qrRows + codeRows * 2 + (link ? 2 : 0) + 2;
|
|
162
|
+
const showUrl = !!link && (!showQr || spacious || contentHeight >= qrRows + codeRows + 2);
|
|
155
163
|
|
|
156
164
|
return (
|
|
157
165
|
<Box flexDirection="column" alignItems="center">
|
|
@@ -165,7 +173,7 @@ function TerminalPanel({ url, code, status, height, button }: PanelBodyProps) {
|
|
|
165
173
|
))}
|
|
166
174
|
</Box>
|
|
167
175
|
)}
|
|
168
|
-
{!showQr &&
|
|
176
|
+
{!showQr && link && (
|
|
169
177
|
<Box height={1}>
|
|
170
178
|
<Text fg={colors.textDim}>{t("Not enough room to draw the QR code.")}</Text>
|
|
171
179
|
</Box>
|
|
@@ -182,7 +190,7 @@ function TerminalPanel({ url, code, status, height, button }: PanelBodyProps) {
|
|
|
182
190
|
<>
|
|
183
191
|
{spacious && <Box height={1} />}
|
|
184
192
|
<Box height={1}>
|
|
185
|
-
<Text fg={colors.textMuted}>{
|
|
193
|
+
<Text fg={colors.textMuted}>{link}</Text>
|
|
186
194
|
</Box>
|
|
187
195
|
</>
|
|
188
196
|
)}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from "react";
|
|
2
2
|
import { Box, Text, useUiCapabilities } from "../../ui";
|
|
3
|
+
import { hoverBg } from "../../theme/colors";
|
|
3
4
|
import { useThemeColors } from "../../theme/theme-context";
|
|
4
5
|
import { displayWidth, padTo, truncateToDisplayWidth } from "../../utils/format";
|
|
5
|
-
import { ExternalLinkText } from "./external-link";
|
|
6
|
+
import { ExternalLinkText, usePaneLinkMenuEntry } from "./external-link";
|
|
6
7
|
|
|
7
8
|
/** One column of a ColumnGrid. */
|
|
8
9
|
export interface ColumnGridColumn {
|
|
@@ -20,9 +21,19 @@ export interface ColumnGridColumn {
|
|
|
20
21
|
gapBefore?: number;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
/**
|
|
25
|
+
* What a cell's text opens (a row's market, a security's DES): the text is the
|
|
26
|
+
* target, as a key-value row's value is, and inside a `PaneLinkMenu` the pane
|
|
27
|
+
* menu lists it as `label`, so the keyboard reaches what a click opens.
|
|
28
|
+
*/
|
|
29
|
+
export interface ColumnGridLink {
|
|
30
|
+
label: string;
|
|
31
|
+
onOpen: () => void;
|
|
32
|
+
}
|
|
33
|
+
|
|
23
34
|
/** Text the grid fits to its column (padded on the terminal, cut by CSS on the desktop), or content the column holds. */
|
|
24
35
|
export type ColumnGridCell =
|
|
25
|
-
| { text: string; color?: string }
|
|
36
|
+
| { text: string; color?: string; link?: ColumnGridLink }
|
|
26
37
|
| { content: ReactNode }
|
|
27
38
|
| null;
|
|
28
39
|
|
|
@@ -76,6 +87,35 @@ function gridTemplate(columns: readonly ColumnGridColumn[]): { template: string;
|
|
|
76
87
|
return { template: tracks.join(" "), gap: undefined, lines };
|
|
77
88
|
}
|
|
78
89
|
|
|
90
|
+
/** A link cell's pointer handling and its pane-menu entry; nothing for a plain cell. */
|
|
91
|
+
function useLinkTarget(link: ColumnGridLink | undefined) {
|
|
92
|
+
const colors = useThemeColors();
|
|
93
|
+
usePaneLinkMenuEntry(link ? `column-grid:${link.label}` : null, link?.label ?? "", () => link?.onOpen());
|
|
94
|
+
return link ? {
|
|
95
|
+
cursor: "pointer" as const,
|
|
96
|
+
hoverBackgroundColor: hoverBg(colors),
|
|
97
|
+
onMouseDown: (event?: { button?: number }) => { if ((event?.button ?? 0) === 0) link.onOpen(); },
|
|
98
|
+
"data-gloom-interactive": "true",
|
|
99
|
+
"data-gloom-label": link.label,
|
|
100
|
+
} : {};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** A text cell that opens something, in the terminal: its padded text is the target. */
|
|
104
|
+
function TerminalLinkCell({ text, color, link, width, align }: { text: string; color?: string; link: ColumnGridLink; width: number; align?: "left" | "right" }) {
|
|
105
|
+
const target = useLinkTarget(link);
|
|
106
|
+
return <Box width={width} flexDirection="row" {...target}><Text fg={color}>{padTo(text, width, align)}</Text></Box>;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** A text cell that opens something, on the desktop and the web. */
|
|
110
|
+
function NativeLinkCell({ text, color, link, column, place }: { text: string; color?: string; link: ColumnGridLink; column: ColumnGridColumn; place: CSSProperties }) {
|
|
111
|
+
const target = useLinkTarget(link);
|
|
112
|
+
return (
|
|
113
|
+
<Text fg={color} data-gloom-ui="column-grid-text" {...clipOf(text, column)} {...target} style={{ ...place, ...TEXT_BOX, textAlign: column.align ?? "left" }}>
|
|
114
|
+
{text}
|
|
115
|
+
</Text>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
79
119
|
/**
|
|
80
120
|
* Columns of single-line text that line up from row to row: a table of
|
|
81
121
|
* figures under its header, or label and value pairs set in columns. The terminal lays the
|
|
@@ -83,7 +123,8 @@ function gridTemplate(columns: readonly ColumnGridColumn[]): { template: string;
|
|
|
83
123
|
* them. The desktop and the web lay out one CSS grid whose tracks are counted
|
|
84
124
|
* in characters, so the columns follow a resize to the pixel, every row and
|
|
85
125
|
* the header share the same tracks, and text that does not fit ends in an
|
|
86
|
-
* ellipsis instead of being cut to a count of cells.
|
|
126
|
+
* ellipsis instead of being cut to a count of cells. A text cell with a `link`
|
|
127
|
+
* opens it on a click and is listed in the pane menu.
|
|
87
128
|
*/
|
|
88
129
|
export function ColumnGrid({ columns, rows, width, role }: ColumnGridProps) {
|
|
89
130
|
const { nativePaneChrome } = useUiCapabilities();
|
|
@@ -98,7 +139,9 @@ export function ColumnGrid({ columns, rows, width, role }: ColumnGridProps) {
|
|
|
98
139
|
<Box key={index} flexDirection="row">
|
|
99
140
|
{column.gapBefore ? <Box width={column.gapBefore} /> : null}
|
|
100
141
|
{cell && "text" in cell
|
|
101
|
-
?
|
|
142
|
+
? cell.link
|
|
143
|
+
? <TerminalLinkCell text={cell.text} color={cell.color} link={cell.link} width={column.width} align={column.align} />
|
|
144
|
+
: <Text fg={cell.color}>{padTo(cell.text, column.width, column.align)}</Text>
|
|
102
145
|
: <Box width={column.width} flexDirection="row">{cell?.content}</Box>}
|
|
103
146
|
</Box>
|
|
104
147
|
);
|
|
@@ -126,6 +169,7 @@ export function ColumnGrid({ columns, rows, width, role }: ColumnGridProps) {
|
|
|
126
169
|
const cell = row[index] ?? null;
|
|
127
170
|
if (!cell) return null;
|
|
128
171
|
const place: CSSProperties = { gridColumn: lines[index], gridRow: rowIndex + 1 };
|
|
172
|
+
if ("text" in cell && cell.link) return <NativeLinkCell key={index} text={cell.text} color={cell.color} link={cell.link} column={column} place={place} />;
|
|
129
173
|
return "text" in cell
|
|
130
174
|
? (
|
|
131
175
|
<Text
|