From d96f68457cfb6605caec7b17bb7634d7f15ddcf3 Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Wed, 9 Sep 2026 12:49:30 -0400 Subject: [PATCH] fix(mobile): restore main's guard conditions on the four Project-row actions Each had gained a non-null target requirement that demanded a number and a recognised item type where main's guard did not, so a row main would have sent for now returns silently or reports an error. File-viewed and the comment reply gate on main's conditions and build the never-null identity target after them. Metadata update, issue type and comment add gate on the slug and the number, as main did, through the slug target, which does not read the item type. Claude-Session: https://claude.ai/code/session_01JNnE9qzUZMMnqpZWCqM3nb --- .../github-project-host-routing-source.test.ts | 4 +++- .../tasks/mobile-tasks-refactor-parity.test.ts | 4 ++-- .../use-mobile-tasks-project-metadata-actions.tsx | 11 ++++++----- ...-mobile-tasks-project-review-check-actions.tsx | 15 ++++++--------- ...-mobile-tasks-project-thread-reply-actions.tsx | 10 +++------- ...le-tasks-project-workspace-comment-actions.tsx | 5 +++-- 6 files changed, 23 insertions(+), 26 deletions(-) diff --git a/mobile/src/tasks/github-project-host-routing-source.test.ts b/mobile/src/tasks/github-project-host-routing-source.test.ts index 4ab16b0f81c..3c567a819ad 100644 --- a/mobile/src/tasks/github-project-host-routing-source.test.ts +++ b/mobile/src/tasks/github-project-host-routing-source.test.ts @@ -93,7 +93,9 @@ describe('mobile GitHub Project host routing boundary', () => { it('pins Project-row PR actions to the row repository identity', () => { // Every Project-row action resolves its target from the row plus the active Project host. const targets = [ - ...compositionSource.matchAll(/projectRow(?:Mutation|PullRequest)Target\(([^)]*)\)/g) + ...compositionSource.matchAll( + /projectRow(?:Mutation|PullRequest|Slug|Identity)Target\(([^)]*)\)/g + ) ] expect(targets.length).toBeGreaterThan(10) for (const target of targets) { diff --git a/mobile/src/tasks/mobile-tasks-refactor-parity.test.ts b/mobile/src/tasks/mobile-tasks-refactor-parity.test.ts index 22a3fcdc358..9ec7300ef4e 100644 --- a/mobile/src/tasks/mobile-tasks-refactor-parity.test.ts +++ b/mobile/src/tasks/mobile-tasks-refactor-parity.test.ts @@ -25,9 +25,9 @@ const hash = (parts: string[] | string): string => * plus the row-target locals the adapters take in place of inline slug/number checks. Diff hooks, * declarations and styles are untouched. */ -const SCREEN_HOOKS = '28f62d2fbd86d171bf162d26c6bd0763e4fb8c3f58895d7cd1a00633c1465f32' +const SCREEN_HOOKS = '5f298d284b82e70b267c499d192c827c39c0e802e7e3cf2b17715480991376a8' const DIFF_HOOKS = '93c7189b32bed8456cc51814fffa8ce80cf62011ef968a9d53ddec2b9686f58f' -const STATEMENTS = 'd3f99f5ccf5decedadeef99e7633b8ce832b39e9a49675c43fbc0954b2a2e483' +const STATEMENTS = 'd5a642c641b1e830b71a437d53b809ba40e4e8a5fd36adbbbeb8173048569295' const DECLARATIONS = 'cff54172af17a877789be1479c2eb6ca97d83c3e31dd831cd59395962f2b4c4a' const SEMANTICS = 'f767906884b93537f2c6369d6d0bd2d4cb39b4314c31cca9d8f9e5e9b78a75ee' const STYLES = '1db6af69c791d9963928541ad5310942fcbda6d984b422c90b6eb92b6816579a' diff --git a/mobile/src/tasks/use-mobile-tasks-project-metadata-actions.tsx b/mobile/src/tasks/use-mobile-tasks-project-metadata-actions.tsx index 1a29bf6ff02..30550ae1afa 100644 --- a/mobile/src/tasks/use-mobile-tasks-project-metadata-actions.tsx +++ b/mobile/src/tasks/use-mobile-tasks-project-metadata-actions.tsx @@ -7,7 +7,7 @@ import { type GitHubProjectRow, optimisticProjectFieldValue } from './mobile-tasks-legacy-foundation' -import { projectRowIdentityTarget, projectRowMutationTarget } from './mobile-tasks-mutation-targets' +import { projectRowIdentityTarget, projectRowSlugTarget } from './mobile-tasks-mutation-targets' export function useMobileTasksProjectMetadataActions(model: ProjectThreadReplyActionsModel) { const { @@ -35,8 +35,9 @@ export function useMobileTasksProjectMetadataActions(model: ProjectThreadReplyAc if (!taskOperations || projectMutating) { return } - const target = projectRowMutationTarget(row, activeGitHubProjectHost) - if (!target) { + // main gated on the slug and the number only; an unrecognised item type was not a refusal. + const target = projectRowSlugTarget(row, activeGitHubProjectHost) + if (!target || !row.content.number) { setProjectRowDetailError('This project item cannot be edited from mobile.') return } @@ -178,8 +179,8 @@ export function useMobileTasksProjectMetadataActions(model: ProjectThreadReplyAc if (!taskOperations || projectMutating) { return } - const target = projectRowMutationTarget(row, activeGitHubProjectHost) - if (row.itemType !== 'ISSUE' || !target) { + const target = projectRowSlugTarget(row, activeGitHubProjectHost) + if (row.itemType !== 'ISSUE' || !target || !row.content.number) { setProjectRowDetailError('This project issue type cannot be edited from mobile.') return } diff --git a/mobile/src/tasks/use-mobile-tasks-project-review-check-actions.tsx b/mobile/src/tasks/use-mobile-tasks-project-review-check-actions.tsx index e5b739dc0f6..e8c982aa937 100644 --- a/mobile/src/tasks/use-mobile-tasks-project-review-check-actions.tsx +++ b/mobile/src/tasks/use-mobile-tasks-project-review-check-actions.tsx @@ -6,7 +6,10 @@ import { type GitHubProjectRow, splitReviewerList } from './mobile-tasks-legacy-foundation' -import { projectRowPullRequestTarget } from './mobile-tasks-mutation-targets' +import { + projectRowIdentityTarget, + projectRowPullRequestTarget +} from './mobile-tasks-mutation-targets' export function useMobileTasksProjectReviewCheckActions(model: ProjectMetadataActionsModel) { const { @@ -157,16 +160,10 @@ export function useMobileTasksProjectReviewCheckActions(model: ProjectMetadataAc const toggleProjectGitHubFileViewed = useCallback( async (row: GitHubProjectRow, file: GitHubDetailFile): Promise => { const repo = findProjectRowRepo(row) - const target = projectRowPullRequestTarget(row, activeGitHubProjectHost) - if ( - !taskOperations || - projectMutating || - row.itemType !== 'PULL_REQUEST' || - !repo || - !target - ) { + if (!taskOperations || projectMutating || row.itemType !== 'PULL_REQUEST' || !repo) { return } + const target = projectRowIdentityTarget(row, activeGitHubProjectHost) if (projectRowDetail?.provider !== 'github' || !projectRowDetail.pullRequestId) { setProjectRowDetailError('Unable to sync viewed state for this pull request.') return diff --git a/mobile/src/tasks/use-mobile-tasks-project-thread-reply-actions.tsx b/mobile/src/tasks/use-mobile-tasks-project-thread-reply-actions.tsx index 7e5135b4698..1773300fa5f 100644 --- a/mobile/src/tasks/use-mobile-tasks-project-thread-reply-actions.tsx +++ b/mobile/src/tasks/use-mobile-tasks-project-thread-reply-actions.tsx @@ -5,11 +5,7 @@ import { type GitHubProjectRow, commentAuthor } from './mobile-tasks-legacy-foundation' -import { - projectRowIdentityTarget, - projectRowMutationTarget, - projectRowSlugTarget -} from './mobile-tasks-mutation-targets' +import { projectRowIdentityTarget, projectRowSlugTarget } from './mobile-tasks-mutation-targets' export function useMobileTasksProjectThreadReplyActions( model: ProjectWorkspaceCommentActionsModel @@ -116,10 +112,10 @@ export function useMobileTasksProjectThreadReplyActions( const replyToProjectGitHubComment = useCallback( async (row: GitHubProjectRow, comment: DetailComment): Promise => { const repo = findProjectRowRepo(row) - const target = projectRowMutationTarget(row, activeGitHubProjectHost) - if (!taskOperations || projectMutating || !repo || !target) { + if (!taskOperations || projectMutating || !repo || !row.content.number) { return } + const target = projectRowIdentityTarget(row, activeGitHubProjectHost) const key = String(comment.id) const body = (itemReplyDrafts[key] ?? '').trim() if (!body) { diff --git a/mobile/src/tasks/use-mobile-tasks-project-workspace-comment-actions.tsx b/mobile/src/tasks/use-mobile-tasks-project-workspace-comment-actions.tsx index 86f4536e784..53d62a7b84a 100644 --- a/mobile/src/tasks/use-mobile-tasks-project-workspace-comment-actions.tsx +++ b/mobile/src/tasks/use-mobile-tasks-project-workspace-comment-actions.tsx @@ -158,9 +158,10 @@ export function useMobileTasksProjectWorkspaceCommentActions(model: WorkspaceCre if (!taskOperations || projectMutating) { return } - const target = projectRowMutationTarget(row, activeGitHubProjectHost) + // main gated on the slug, the number and a non-empty body; the item type was not read. + const target = projectRowSlugTarget(row, activeGitHubProjectHost) const body = projectCommentDraft.trim() - if (!target || !body) { + if (!target || !row.content.number || !body) { return } setProjectMutating(true)