diff --git a/src/tui.zig b/src/tui.zig index ee44f9d..e78f359 100644 --- a/src/tui.zig +++ b/src/tui.zig @@ -1634,10 +1634,9 @@ pub const App = struct { } /// Whether the given tab should be treated as disabled in - /// the current App context. All migrated tabs are consulted - /// via their framework-contract `isDisabled` hook. (Portfolio - /// is the only remaining unmigrated tab; it has no disabled - /// predicate today.) + /// the current App context. All tabs are consulted via their + /// framework-contract `isDisabled` hook (tabs without one + /// default to always-enabled). fn isDisabled(self: *App, t: Tab) bool { return self.appPredicate(t, "isDisabled"); } diff --git a/src/tui/portfolio_tab.zig b/src/tui/portfolio_tab.zig index fabe198..4d4978c 100644 --- a/src/tui/portfolio_tab.zig +++ b/src/tui/portfolio_tab.zig @@ -330,6 +330,16 @@ pub const tab = struct { pub const deactivate = framework.noopDeactivate(State); + /// Disabled only when the TUI was opened on a specific symbol + /// (`zfin AAPL`) with no portfolio loaded: there's nothing to show + /// here, so it greys out and becomes unselectable to match the + /// other portfolio-backed tabs (analysis, review, projections, + /// history). A plain `zfin` launch with no portfolio keeps the tab + /// enabled so it can show the welcome screen (`drawWelcomeScreen`). + pub fn isDisabled(app: *App) bool { + return app.portfolio.file == null and app.has_explicit_symbol; + } + /// Manual refresh (r/F5): re-value the portfolio with live /// intraday quotes, then rebuild the summary. `r` means "give me /// current prices now" - it does NOT force candle work. Candle @@ -466,11 +476,6 @@ pub const tab = struct { } } - /// Portfolio is always enabled (the tab itself; data may be - /// empty if no portfolio file is loaded - that's a separate - /// concern handled by `drawWelcomeScreen`). - pub const isDisabled = framework.alwaysEnabled(); - /// Drop UI state that referenced the previous portfolio. /// /// `account_list` holds borrowed strings into the old