diff --git a/datajunction-ui/src/app/components/NamespaceHeader.jsx b/datajunction-ui/src/app/components/NamespaceHeader.jsx index b7503ec01..19856611f 100644 --- a/datajunction-ui/src/app/components/NamespaceHeader.jsx +++ b/datajunction-ui/src/app/components/NamespaceHeader.jsx @@ -1066,7 +1066,13 @@ export default function NamespaceHeader({ (() => { const repoBranch = gitConfig?.git_branch || gitConfig?.default_branch; - const editableBranch = gitShape === 'branch' && !isGitManaged; + // Editable = the branch root (shape `branch`) OR a sub-namespace + // of a feature branch (resolves as `flat`, no parent_namespace of + // its own, so `gitShape` alone misses it — same trap as the + // read-only verdict). Without isFeatureBranch these sub-namespaces + // fall through to the not-git "Connect to Git" button. + const editableBranch = + !isGitManaged && (gitShape === 'branch' || isFeatureBranch); const gitUrl = viewInGitUrl(); // Read-only: fork to propose a change; everything else in the menu. diff --git a/datajunction-ui/src/app/components/__tests__/NamespaceHeader.test.jsx b/datajunction-ui/src/app/components/__tests__/NamespaceHeader.test.jsx index 7d740a1bb..65a20d281 100644 --- a/datajunction-ui/src/app/components/__tests__/NamespaceHeader.test.jsx +++ b/datajunction-ui/src/app/components/__tests__/NamespaceHeader.test.jsx @@ -795,6 +795,24 @@ describe('', () => { }); }, ); + + // Regression: same `flat`-shape trap on the git action button. A feature + // branch sub-namespace is editable, so it must show the "Sync to Git" + // control — not the not-git "Connect to Git" button. + it('shows Sync to Git (not Connect to Git) for a feature branch sub-namespace', async () => { + renderReadOnlyVerdict({ + namespace: 'test.feature.metrics', + configByNamespace: { + 'test.feature.metrics': branchCfg('feature', 'test.feature.metrics'), + 'test.feature': branchCfg('feature', 'test.feature'), + test: GIT_ROOT, + }, + }); + await waitFor(() => + expect(screen.getByText('Sync to Git')).toBeInTheDocument(), + ); + expect(screen.queryByText('Connect to Git')).not.toBeInTheDocument(); + }); }); it('should open Create Branch modal when button is clicked', async () => {