From 15db848b1d25ec56538637da428cbbce39968de6 Mon Sep 17 00:00:00 2001
From: Claude
Date: Wed, 26 Aug 2026 07:19:07 +0000
Subject: [PATCH] fix(templates): explain a per-member connection instead of a
bare checkbox
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Picking Google Workspace, Linear or YouTrack on the template page produced a
checkbox and nothing else — no button, no note, no hint that the member signs
in later inside the workspace.
The cause is one gate. Every note and button in the block hangs off
`wantsOrgConfig`, which is `chosen !== null && entry.adminForm !== null`. Those
three carry `adminForm: null` in the catalog, so the whole block was skipped for
exactly the providers that most needed a word of explanation.
They now render the sentence the org-key providers already use, so there is one
phrasing rather than a second variant to keep in step.
Also: the repo picker said "Set up GitHub above first" for what the surface
calls connecting. It says "Connect GitHub above first" now.
Both are pinned by tests that fail against the previous renderer.
Co-Authored-By: Claude Opus 5
---
.../webapp/src/files/TemplateConnectionsSection.tsx | 11 +++++++++++
packages/webapp/src/files/TemplateRepoPicker.tsx | 2 +-
packages/webapp/test/template-screen.test.tsx | 10 +++++++---
3 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/packages/webapp/src/files/TemplateConnectionsSection.tsx b/packages/webapp/src/files/TemplateConnectionsSection.tsx
index bbac7132..e0863fee 100644
--- a/packages/webapp/src/files/TemplateConnectionsSection.tsx
+++ b/packages/webapp/src/files/TemplateConnectionsSection.tsx
@@ -80,6 +80,12 @@ export function TemplateConnectionsSection({
const chosen = templateConnections.get(entry.id) ?? null;
const configured = orgCredentialFor(orgConnections, entry.id);
const wantsOrgConfig = chosen !== null && entry.adminForm !== null;
+ // A provider with no admin form has no org-key path at all, so every
+ // branch below — which all hang off wantsOrgConfig — used to skip it.
+ // Selecting Google Workspace, Linear or YouTrack therefore produced a
+ // bare checkbox that explained nothing. They are member-authorized, so
+ // say that, in the sentence the org-key providers already use.
+ const memberOnly = chosen !== null && entry.adminForm === null;
// A provider members can authorize themselves — OAuth or a token
// paste — is usable without any org credential, so its admin form is
// an offer, never a gate.
@@ -135,6 +141,11 @@ export function TemplateConnectionsSection({
Without an org key, members sign in to {entry.title} themselves.
)}
+ {memberOnly && (
+
+ Members sign in to {entry.title} themselves.
+
+ )}
{wantsOrgConfig && !admin && !configured && (
memberPath ? (
diff --git a/packages/webapp/src/files/TemplateRepoPicker.tsx b/packages/webapp/src/files/TemplateRepoPicker.tsx
index 4410e957..c6b08ca8 100644
--- a/packages/webapp/src/files/TemplateRepoPicker.tsx
+++ b/packages/webapp/src/files/TemplateRepoPicker.tsx
@@ -61,7 +61,7 @@ export function TemplateRepoPicker({
return (
{admin
- ? 'Set up GitHub above first. Repos show up here when it saves.'
+ ? 'Connect GitHub above first. Repos show up here when it saves.'
: 'Ask an admin to set up GitHub above. Repos show up here after that.'}
);
diff --git a/packages/webapp/test/template-screen.test.tsx b/packages/webapp/test/template-screen.test.tsx
index 707ab5e9..5939a5d3 100644
--- a/packages/webapp/test/template-screen.test.tsx
+++ b/packages/webapp/test/template-screen.test.tsx
@@ -1661,7 +1661,7 @@ describe('template screen org-credential config', () => {
await view.unmount();
});
- it('keeps per-member providers as plain checkboxes with no admin form', async () => {
+ it('explains a per-member provider when it is picked, with no admin form', async () => {
connectionsStub();
const view = await render(
{
await settle();
await tick(view, 'YouTrack');
// YouTrack is per-member PAT: the template names it, the member pastes
- // inside the workspace. No org form, no ask-your-admin note.
+ // inside the workspace. No org form, no ask-your-admin note. It still owes
+ // the picker one line saying so — a provider with no admin form used to
+ // render a bare checkbox that explained nothing.
expect(view.container.querySelector('.tplf-connections input[name="root"]')).toBeNull();
expect(view.container.querySelector('.tplf-connections')?.textContent)
.not.toContain('Ask an organization admin');
+ expect(view.container.querySelector('.tplf-connections')?.textContent)
+ .toContain('Members sign in to YouTrack themselves.');
await view.unmount();
});
@@ -1719,7 +1723,7 @@ describe('template screen org-credential config', () => {
/>,
);
await settle();
- expect(view.container.textContent).toContain('Set up GitHub above first');
+ expect(view.container.textContent).toContain('Connect GitHub above first');
expect(view.container.querySelector('input[aria-label="Filter repositories"]')).toBeNull();
await tick(view, 'GitHub');