| … | … | @@ -102,7 +103,8 @@ export function HomeRouteScreen() { | |
| 104 | 105 | const selectedEnvironmentId = listOptions.selectedEnvironmentId; | |
| 105 | - | const [selectedProjectKey, setSelectedProjectKey] = useState<string | null>(null); | |
| 106 | + | const [projectScopeKey, setSelectedProjectKey] = useState<string | null>(null); | |
| 107 | + | const selectedProjectKey = resolveScratchProjectScopeKey(projectScopeKey, projects); | |
🟡 Medium home/HomeRouteScreen.tsx:107
Removing or disabling environment A clears the selected project filter and exposes ordinary-project threads, even when environment B still provides the combined scratch scope. selectedProjectKey resolves A's physical key for display but never updates projectScopeKey, so the missing-option effect later clears the stale selection. Persist the resolved key when it changes to keep the logical scratch selection.
Also found in 1 other location(s)
apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx:210
The resolved scratch key is never written back to
projectScopeKey. If a user selects environment A's physical scratch filter before config arrives, it later displays the combined “No project” filter, but state still holds A's physical key. Removing/disabling A then removes its projects fromprojectsAtom(which aggregates only enabled environments); the resolver returns the obsolete physical key even when environment B still supplies the combined scratch scope. The missing-option effect clears the selection, unexpectedly showing all projects. Persist the migrated logical key so the combined filter survives removal of its original host.
No longer relevant as of a6d00ed33ffbfbc169ed7a4f6754c7724fd5d825
Fixed in a6d00ed in both mobile filter owners. When the resolved key changes, they save the logical scratch key using a guarded render update, so removing the original environment cannot revert it to the old physical key. Regression coverage migrates a pre-config selection in each grouping mode, removes its original host, and verifies the surviving scratch scope and project references.
Sorry, I'm unable to act on this request because you do not have permissions within this repository.
| … | … | @@ -156,6 +160,19 @@ export function deriveLogicalProjectKeyFromSettings( | |
| 168 | + | >, | |
| 169 | + | ): string | null { | |
| 170 | + | if (key === null || key === SCRATCH_PROJECT_SCOPE_KEY) return key; | |
| 171 | + | return projects.some((project) => project.isScratch && derivePhysicalProjectKey(project) === key) | |
🟡 Medium state/projectGrouping.ts:171
When a scratch project was selected before config arrived in repository or repository_path mode, this returns its stale repository-derived key instead of SCRATCH_PROJECT_SCOPE_KEY, so the mobile and web selection effects clear the filter after config marks it scratch. The lookup only matches derivePhysicalProjectKey; preserve the pre-config logical key as well when resolving the scratch scope.
No longer relevant as of a6d00ed33ffbfbc169ed7a4f6754c7724fd5d825
Fixed in a6d00ed. The resolver now checks the pre-config repository key using the active grouping mode and overrides, as well as the physical key. Both clients pass their grouping settings. Existing ordinary repository scopes take precedence. Regression tests cover repository, repository_path, and separate migration, plus the ordinary-scope case.
Sorry, I'm unable to act on this request because you do not have permissions within this repository.
| … | … | @@ -2644,15 +2649,28 @@ export default function Sidebar() { | |
| 2652 | + | // Configs identify scratch projects, so both they and live project snapshots | |
| 2653 | + | // must arrive before a persisted scope can be considered missing. | |
| 2650 | 2654 | const allProjectSnapshotsReady = useAllEnvironmentProjectSnapshotsReady(); | |
| 2655 | + | const allProjectConfigsReady = environments.every((environment) => | |
🟡 Medium components/Sidebar.tsx:2655
A saved scope for a removed project is never cleared when any catalog environment is switched off, so the picker shows “All projects” while retaining a stale selection that can reactivate later. allProjectConfigsReady checks every environment from useEnvironmentIdentities(), but serverConfigs only contains enabled environments; restrict this readiness check to enabled environments, as the snapshot readiness check does.
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/web/src/components/Sidebar.tsx around line 2655: |
| 2 | |
| 3 | A saved scope for a removed project is never cleared when any catalog environment is switched off, so the picker shows “All projects” while retaining a stale selection that can reactivate later. `allProjectConfigsReady` checks every `environment` from `useEnvironmentIdentities()`, but `serverConfigs` only contains enabled environments; restrict this readiness check to enabled environments, as the snapshot readiness check does. |
Fixed in a6d00ed. Config readiness now derives from enabledEnvironmentIds(catalog), matching project aggregation and snapshot readiness. A missing config from a disabled environment no longer prevents stale-filter cleanup. The atom regression test verifies disabled, re-enabled, and not-yet-ready catalog transitions.
Sorry, I'm unable to act on this request because you do not have permissions within this repository.