From b229da0115cb629d5047910fb896c7320f5324dc Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 29 Jul 2026 15:48:41 +0000 Subject: [PATCH] Block delete for in-progress access review campaigns Reject deletion while a campaign is fetching sources so workers are not racing a removed record. All other statuses remain deletable. Signed-off-by: Cursor Agent Co-authored-by: Bryan FRIMIN --- .../campaigns/AccessReviewCampaignsTab.tsx | 9 +++++++-- .../campaigns/CampaignDetailPage.tsx | 2 +- pkg/accessreview/campaign_service.go | 4 ++++ pkg/accessreview/errors.go | 20 +++++++++++++++++++ pkg/accessreview/errors_test.go | 9 +++++++++ .../v1/access_review_campaign_resolvers.go | 4 ++++ 6 files changed, 45 insertions(+), 3 deletions(-) diff --git a/apps/console/src/pages/organizations/access-reviews/campaigns/AccessReviewCampaignsTab.tsx b/apps/console/src/pages/organizations/access-reviews/campaigns/AccessReviewCampaignsTab.tsx index d25852045..f36b8bf00 100644 --- a/apps/console/src/pages/organizations/access-reviews/campaigns/AccessReviewCampaignsTab.tsx +++ b/apps/console/src/pages/organizations/access-reviews/campaigns/AccessReviewCampaignsTab.tsx @@ -132,6 +132,8 @@ export default function AccessReviewCampaignsTab({ queryRef }: Props) { deleteCampaignMutation, ); + const isDeletableStatus = (status: string) => status !== "IN_PROGRESS"; + const handleDelete = (campaignId: string, campaignName: string) => { confirm( () => { @@ -178,7 +180,9 @@ export default function AccessReviewCampaignsTab({ queryRef }: Props) { ); }; - const hasActions = accessReviewCampaigns.edges.some(edge => edge.node.canDelete); + const hasActions = accessReviewCampaigns.edges.some( + edge => edge.node.canDelete && isDeletableStatus(edge.node.status), + ); return (
@@ -209,7 +213,8 @@ export default function AccessReviewCampaignsTab({ queryRef }: Props) { {accessReviewCampaigns.edges.map((edge) => { - const canDeleteRow = edge.node.canDelete; + const canDeleteRow + = edge.node.canDelete && isDeletableStatus(edge.node.status); return (