| author | |
| committer | |
| log | cb395ee13b5b5ddd4352e7c3d4216181501cc2e5 |
| tree | df70cd8a05e11a7cbb18a74a9fc1b9d51df03c92 |
| parent | e093789dd2340d8a41ee7ac12341fb011f9ff86c |
| signature | Signed by PGP key B5690EEEBB952194 |
4 files changed, 67 insertions(+), 5 deletions(-)
apps/mobile/src/features/pull-requests/PullRequestsScreen.tsx+10-3| ... | ... | @@ -34,6 +34,7 @@ import { |
| 34 | 34 | scopedPullRequestListKey as pullRequestKey, |
| 35 | 35 | type EnvironmentPullRequestListEntry, |
| 36 | 36 | PR_LIST_PAGE_SIZE, |
| 37 | withoutScratchProjectScope, | |
| 37 | 38 | } from "./pullRequestList"; |
| 38 | 39 | import { useDebouncedValue } from "../../state/queries"; |
| 39 | 40 | import { useWorkspaceTabs } from "../workspace/WorkspaceTabsContext"; |
| ... | ... | @@ -102,7 +103,12 @@ export function PullRequestsScreen( |
| 102 | 103 | }, |
| 103 | 104 | [navigation, selectAndroidWorkspace], |
| 104 | 105 | ); |
| 105 | const controls = listControls.controlsFor(environmentId); | |
| 106 | const allProjects = useProjects(); | |
| 107 | const savedControls = listControls.controlsFor(environmentId); | |
| 108 | const controls = useMemo( | |
| 109 | () => withoutScratchProjectScope(savedControls, allProjects), | |
| 110 | [allProjects, savedControls], | |
| 111 | ); | |
| 106 | 112 | const targets = useMemo( |
| 107 | 113 | () => |
| 108 | 114 | environments |
| ... | ... | @@ -175,8 +181,9 @@ export function PullRequestsScreen( |
| 175 | 181 | ].sort(), |
| 176 | 182 | })); |
| 177 | 183 | } |
| 178 | const projects = useProjects().filter( | |
| 179 | (project) => environmentId === null || project.environmentId === environmentId, | |
| 184 | const projects = allProjects.filter( | |
| 185 | (project) => | |
| 186 | !project.isScratch && (environmentId === null || project.environmentId === environmentId), | |
| 180 | 187 | ); |
| 181 | 188 | const renderPullRequest = useCallback( |
| 182 | 189 | ({ item }: { readonly item: EnvironmentPullRequestListEntry }) => ( |
apps/mobile/src/features/pull-requests/pullRequestList.test.ts+37| ... | ... | @@ -18,6 +18,7 @@ import { |
| 18 | 18 | pullRequestLabelColor, |
| 19 | 19 | scopedPullRequestListKey, |
| 20 | 20 | pullRequestListRowsAreEqual, |
| 21 | withoutScratchProjectScope, | |
| 21 | 22 | } from "./pullRequestList"; |
| 22 | 23 | |
| 23 | 24 | function entry(number: number, patch: Partial<PullRequestListEntry> = {}): PullRequestListEntry { |
| ... | ... | @@ -373,3 +374,39 @@ describe("mobile PR scan and filters", () => { |
| 373 | 374 | expect(pullRequestLabelColor("not-a-color")).toBeNull(); |
| 374 | 375 | }); |
| 375 | 376 | }); |
| 377 | ||
| 378 | describe("withoutScratchProjectScope", () => { | |
| 379 | const projects = [ | |
| 380 | { id: "repo", environmentId: "env-a" }, | |
| 381 | { id: "scratch", environmentId: "env-a", isScratch: true as const }, | |
| 382 | ]; | |
| 383 | ||
| 384 | it("reads a scope saved on the Scratch folder as all projects", () => { | |
| 385 | const controls = withoutScratchProjectScope( | |
| 386 | { ...DEFAULT_PR_LIST_CONTROLS, projectId: "scratch", projectEnvironmentId: "env-a" }, | |
| 387 | projects, | |
| 388 | ); | |
| 389 | expect(controls.projectId).toBeUndefined(); | |
| 390 | expect(controls.projectEnvironmentId).toBeUndefined(); | |
| 391 | }); | |
| 392 | ||
| 393 | it("keeps a repository scope, and one whose projects have not arrived yet", () => { | |
| 394 | const repository = { | |
| 395 | ...DEFAULT_PR_LIST_CONTROLS, | |
| 396 | projectId: "repo", | |
| 397 | projectEnvironmentId: "env-a", | |
| 398 | }; | |
| 399 | expect(withoutScratchProjectScope(repository, projects)).toBe(repository); | |
| 400 | const pending = { ...repository, projectId: "scratch" }; | |
| 401 | expect(withoutScratchProjectScope(pending, [])).toBe(pending); | |
| 402 | }); | |
| 403 | ||
| 404 | it("keeps another server's project that shares the Scratch folder's id", () => { | |
| 405 | const elsewhere = { | |
| 406 | ...DEFAULT_PR_LIST_CONTROLS, | |
| 407 | projectId: "scratch", | |
| 408 | projectEnvironmentId: "env-b", | |
| 409 | }; | |
| 410 | expect(withoutScratchProjectScope(elsewhere, projects)).toBe(elsewhere); | |
| 411 | }); | |
| 412 | }); |
apps/mobile/src/features/pull-requests/pullRequestList.ts+15| ... | ... | @@ -15,6 +15,21 @@ export const DEFAULT_PR_LIST_CONTROLS: PullRequestListControls = { |
| 15 | 15 | sort: "updated", |
| 16 | 16 | }; |
| 17 | 17 | |
| 18 | /** A scope saved on the Scratch folder is no longer offered, so it reads as "All projects". */ | |
| 19 | export function withoutScratchProjectScope( | |
| 20 | controls: PullRequestListControls, | |
| 21 | projects: readonly { id: string; environmentId: string; isScratch?: true }[], | |
| 22 | ): PullRequestListControls { | |
| 23 | return projects.some( | |
| 24 | (project) => | |
| 25 | project.isScratch && | |
| 26 | project.id === controls.projectId && | |
| 27 | project.environmentId === controls.projectEnvironmentId, | |
| 28 | ) | |
| 29 | ? { ...controls, projectId: undefined, projectEnvironmentId: undefined } | |
| 30 | : controls; | |
| 31 | } | |
| 32 | ||
| 18 | 33 | export function pullRequestListKey( |
| 19 | 34 | item: Pick<PullRequestListEntry, "host" | "repository" | "number">, |
| 20 | 35 | ) { |
apps/web/src/routes/_chat.pull-requests.tsx+5-2| ... | ... | @@ -411,9 +411,12 @@ function PullRequestsRouteView() { |
| 411 | 411 | // the one wrong answer the empty state can give. |
| 412 | 412 | const projectsKnown = useAllEnvironmentShellsBootstrapped(); |
| 413 | 413 | // Only the projects the page can actually read: one on an environment that cannot list pull |
| 414 | // requests could neither be listed nor acted on. | |
| 414 | // requests could neither be listed nor acted on, and the Scratch folder is never a repository. | |
| 415 | 415 | const projects = useMemo( |
| 416 | () => allProjects.filter((project) => environmentIds.includes(project.environmentId)), | |
| 416 | () => | |
| 417 | allProjects.filter( | |
| 418 | (project) => !project.isScratch && environmentIds.includes(project.environmentId), | |
| 419 | ), | |
| 417 | 420 | [allProjects, environmentIds], |
| 418 | 421 | ); |
| 419 | 422 | const environmentLabels = useMemo( |