Skip to content

feat(scm-first-messaging-integration): Adding providerRow component - #121728

Open
Abdkhan14 wants to merge 4 commits into
abdk/useScmMessagingProviders-hookfrom
abdk/rendering-provider-rows
Open

feat(scm-first-messaging-integration): Adding providerRow component#121728
Abdkhan14 wants to merge 4 commits into
abdk/useScmMessagingProviders-hookfrom
abdk/rendering-provider-rows

Conversation

@Abdkhan14

@Abdkhan14 Abdkhan14 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Problem

The new inline messaging step renders one row per curated provider (Slack, Discord, MS Teams), and each row has to represent a lot of states: not yet installed, install in progress, install failed, freshly installed, connected, ineligible (tenant MS Teams), configuring a destination, configured, and confirming removal. The useScmMessagingProviders hook already exposes the settled data per provider, but there was no component to turn that view model — plus the live install flow and the destination saved in session — into a single coherent row UI.

Change

Adds ScmMessagingProviderRow, a self-contained row component for one messaging provider. It drives installs through useAddIntegration and collapses the view model, install-flow state, and session setup into one pure deriveVisualState function, so each render resolves to exactly one visual state (installable, installing, install-error, loading, permission-limited, connected, configuring, configured, removing). The install lifecycle is fully wired — Connect opens the flow, a spinner covers the post-install window, errors surface a retry, and remove asks for confirmation — while

@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Aug 11, 2026
@Abdkhan14
Abdkhan14 marked this pull request as ready for review August 13, 2026 16:36

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f0b6cac. Configure here.

Comment thread static/app/components/onboarding/scm/scmMessagingProviderRow.tsx Outdated
Comment thread static/app/components/onboarding/scm/scmMessagingProviderRow.tsx Outdated
Comment thread static/app/components/onboarding/scm/scmMessagingProviderRow.tsx Outdated
Comment thread static/app/components/onboarding/scm/scmMessagingProviderRow.tsx Outdated
if (installState.status === 'installing') {
return 'installing';
}
if (installState.status === 'error') {

@jaydgoss jaydgoss Aug 13, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium: if the install errors but the integration actually exists (the integrations query is shared, so a successful install on another row can refetch and surface it), this row stays stuck on the error alert and Try again would reinstall an existing integration. worth gating this on viewModel.status === 'installable'?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid bug, the pushed the fix: wrapped both install-error branches in a viewModel.status === 'installable' guard. If a shared-query refetch (triggered by another row's successful install) reveals this provider's integration, the row now falls through to the connected/configured state instead of stranding on the error alert whose "Try again" would reinstall an already-installed integration.

added a test

messagingSetup: ScmMessagingSetup;
onInstallComplete: () => void;
onMessagingSetupChange: (setup: ScmMessagingSetup) => void;
viewModel: ScmMessagingProviderViewModel;

@jaydgoss jaydgoss Aug 13, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: viewModel is not very helpful / descriptive as a prop name IMO. maybe resolvedProvider, with the type renamed to ResolvedMessagingProvider back in #121631? non-blocking, fine to punt given the stack churn

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm noting down some of these post merge refactor suggestions, punting for now, will address separately, thanks

[onMessagingSetupChange]
);

const errorMessage =

@jaydgoss jaydgoss Aug 13, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: would be much easier to grok as a function with early returns

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, addressed this and the two below which are similar

Comment thread static/app/components/onboarding/scm/scmMessagingProviderRow.tsx Outdated
Comment thread static/app/components/onboarding/scm/scmMessagingProviderRow.tsx Outdated
Comment thread static/app/components/onboarding/scm/scmMessagingProviderRow.tsx
Comment thread static/app/components/onboarding/scm/scmMessagingProviderRow.tsx

expect(screen.getByRole('button', {name: /Edit/})).toBeInTheDocument();
expect(
screen.queryByText(/The .* workspace will remain connected/)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the Edit assertion already proves we returned to configured no? i think this negative check can go.

await userEvent.click(screen.getByRole('button', {name: /Remove/}));

const [confirmBtn] = screen.getAllByRole('button', {name: /Remove/});
await userEvent.click(confirmBtn);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like there's still a type err here
Argument of type 'HTMLElement | undefined' is not assignable to parameter of type 'Element'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants