[WIP] decompose ReportScreen 5: self-subscribe List and Composer#86119
Draft
adhorodyski wants to merge 18 commits intoExpensify:mainfrom
Draft
[WIP] decompose ReportScreen 5: self-subscribe List and Composer#86119adhorodyski wants to merge 18 commits intoExpensify:mainfrom
adhorodyski wants to merge 18 commits intoExpensify:mainfrom
Conversation
Replace three scattered modules (useAgentZeroStatusIndicator hook, ConciergeReasoningStore, and Pusher reasoning subscriptions in Report/index.ts) with a single AgentZeroStatusContext that uses a two-level gate pattern: - Outer gate (AgentZeroStatusProvider): cheap scalar check — if not Concierge chat, renders children with no hooks/Pusher/state overhead - Inner gate (AgentZeroStatusGate): owns all logic for Concierge chats: Onyx subscription, Pusher subscription with per-callback cleanup, reasoning state with deduplication, debounced label updates Consumers (ConciergeThinkingMessage, ReportActionCompose) now read from context instead of receiving props drilled through 4 levels. The prop chain ReportScreen → ReportActionsView → ReportActionsList → ConciergeThinkingMessage is eliminated. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The new eslint-config-expensify@2.0.107 enforces context-provider-split-values:
contexts must not mix data and functions in a single provider.
Split AgentZeroStatusContext into:
- AgentZeroStatusStateContext: {isProcessing, reasoningHistory, statusLabel}
- AgentZeroStatusActionsContext: {kickoffWaitingIndicator}
Export useAgentZeroStatus() for state and useAgentZeroStatusActions()
for actions. Update ReportActionCompose to use the actions hook.
Update tests to use the appropriate hook per test case — state-only
tests use useAgentZeroStatus(), tests needing both spread inline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…atus-context # Conflicts: # src/hooks/useAgentZeroStatusIndicator.ts # src/pages/inbox/ReportScreen.tsx
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…me state Self-derive shouldSuppressIndicators inside AgentZeroStatusGate using side-panel context and report actions, then expose it via useAgentZeroStatus(). ConciergeThinkingMessage and a new AgentZeroAwareTypingIndicator wrapper consume the flag to hide indicators until the user sends a message. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document the public interface (AgentZeroStatusState, AgentZeroStatusActions) with JSDoc comments explaining each field's purpose, and add inline comments to internal state variables, refs, effects, and derived values in the gate. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…hook Extract useShouldSuppressConciergeIndicators hook that each consumer calls directly, removing shouldSuppressIndicators from AgentZeroStatusState. This keeps the context pure (isProcessing, reasoningHistory, statusLabel) and scopes suppression to Concierge DMs only, fixing the #admins bug. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avoids defaulting to empty string which violates the no-default-id-values lint rule. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the 13-prop interface with just reportID + onLayout. The component now self-subscribes to report data (report, reportActions, reportMetadata, parentReportAction, transactionThreadReportID, isConciergeSidePanel, etc.) via hooks. Update all call sites (ReportScreen, MoneyRequestReportView) to pass only reportID. Widen useConciergeSidePanelReportActions to accept OnyxEntry<Report> to handle the pre-load undefined window. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ReportActionCompose now owns the full submit flow (task detection, addComment, attachment dispatch) and manages the didHideComposerInput latch internally. The onSubmit prop is removed; ReportFooter is simplified to pure layout/gating logic. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Internalize all data subscriptions into ReportActionCompose so it only requires a single `reportID` prop. Computed internally: report (Onyx), isComposerFullSize (Onyx), lastReportAction (paginated actions + combined thread actions), reportTransactions (collection hook), transactionThreadReportID (derived), and pendingAction (ReportUtils). Remove dead onComposerFocus/onComposerBlur props that were never passed by any caller. Update all call sites (ReportFooter, ReportScreen, MoneyRequestReportView) and test fixtures to the new minimal API. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ReportFooter now accepts reportID instead of report, self-subscribes via useOnyx, and returns null when the report is not yet loaded. Moved from report/ReportFooter.tsx to inbox/ReportFooter.tsx to sit alongside the other self-subscribing screen components. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ompose - ReportActionsViewTest: add mocks for usePaginatedReportActions, useParentReportAction, useIsInSidePanel, useSidePanelState, and useReportTransactionsCollection; simplify render helper to accept only reportID; control Concierge side panel state through hook mocks rather than props; fix mockUseOnyx to return mockReport so the component doesn't early-return the skeleton on missing report - ReportActionComposeTest: add mocks for usePaginatedReportActions, useParentReportAction, useReportTransactionsCollection, useShortMentionsList, and useSidePanelState; add beforeEach to pre-populate Onyx with the fake report so the component renders past its early-return guard Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation of Change
Part 5 of a 7-PR series to decompose
ReportScreen(#84895).This PR makes
ReportActionsView,ReportActionCompose, andReportFooterself-subscribing — each component now derives its own data viauseOnyxand custom hooks rather than receiving a large prop surface drilled fromReportScreen.ReportActionsView: reduced from 13 props to 2 (reportID,onLayout). The component now self-subscribes viauseOnyx,usePaginatedReportActions,useParentReportAction, and related hooks.ReportActionCompose: reduced from 11 props to 1 (reportID). Comment submission and task creation logic (previously in the oldReportFooter) were moved into this component. It self-subscribes to the report, transactions, and last report action.ReportFooter: the old 246-linereport/ReportFooter.tsxis deleted and replaced with a thin 118-lineinbox/ReportFooter.tsxorchestrator that needs onlyreportID.ReportScreen: ~50 lines of prop drilling and unused intermediate computations removed.Net change: +487/-531 across 10 files (net -44 lines).
Dependencies: PR #85535 (AgentZero context)
Fixed Issues
$ #84895
PROPOSAL:
Tests
Offline tests
N/A
QA Steps
Same as tests
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari