diff --git a/packages/shared/src/issue-thread-interactions.test.ts b/packages/shared/src/issue-thread-interactions.test.ts index 630d0c9da95..66ca57ea3a5 100644 --- a/packages/shared/src/issue-thread-interactions.test.ts +++ b/packages/shared/src/issue-thread-interactions.test.ts @@ -209,6 +209,15 @@ describe("issue thread interaction schemas", () => { }, })).toThrow("defaultSelectedOptionIds must reference existing option ids"); + expect(() => createIssueThreadInteractionSchema.parse({ + ...base, + payload: { + ...base.payload, + defaultSelectedOptionIds: ["item-1"], + minSelected: 2, + }, + })).toThrow("defaultSelectedOptionIds must satisfy minSelected"); + expect(() => createIssueThreadInteractionSchema.parse({ ...base, payload: { diff --git a/packages/shared/src/validators/issue.ts b/packages/shared/src/validators/issue.ts index fa8c8a362db..7d7454c494d 100644 --- a/packages/shared/src/validators/issue.ts +++ b/packages/shared/src/validators/issue.ts @@ -795,6 +795,13 @@ export const requestCheckboxConfirmationPayloadSchema = z.object({ path: ["minSelected"], }); } + if (value.defaultSelectedOptionIds.length < value.minSelected) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "defaultSelectedOptionIds must satisfy minSelected", + path: ["defaultSelectedOptionIds"], + }); + } if (maxSelected != null) { if (maxSelected < value.minSelected) { ctx.addIssue({ diff --git a/server/src/__tests__/issue-thread-interactions-service.test.ts b/server/src/__tests__/issue-thread-interactions-service.test.ts index f4828a6f493..845eb42ffba 100644 --- a/server/src/__tests__/issue-thread-interactions-service.test.ts +++ b/server/src/__tests__/issue-thread-interactions-service.test.ts @@ -820,6 +820,7 @@ describeEmbeddedPostgres("issueThreadInteractionService", () => { { id: "two", label: "Two" }, { id: "three", label: "Three" }, ], + defaultSelectedOptionIds: ["one"], minSelected: 1, maxSelected: 2, }, diff --git a/ui/src/components/IssueThreadInteractionCard.test.tsx b/ui/src/components/IssueThreadInteractionCard.test.tsx index 9687ae8b61f..f4791a1ae9d 100644 --- a/ui/src/components/IssueThreadInteractionCard.test.tsx +++ b/ui/src/components/IssueThreadInteractionCard.test.tsx @@ -442,6 +442,11 @@ describe("IssueThreadInteractionCard", () => { .filter((box) => box.getAttribute("aria-checked") === "false"); expect(stillUnchecked.length).toBeGreaterThan(0); expect(stillUnchecked.every((box) => box.hasAttribute("disabled"))).toBe(true); + + const selectAllButton = Array.from(host.querySelectorAll("button")).find((button) => + button.textContent?.includes("Select all"), + ); + expect(selectAllButton?.hasAttribute("disabled")).toBe(true); }); it("summarizes large accepted selections by count and bounds the chips", () => { diff --git a/ui/src/components/IssueThreadInteractionCard.tsx b/ui/src/components/IssueThreadInteractionCard.tsx index 13c7303c08e..a26ac400a4c 100644 --- a/ui/src/components/IssueThreadInteractionCard.tsx +++ b/ui/src/components/IssueThreadInteractionCard.tsx @@ -1611,7 +1611,7 @@ function RequestCheckboxConfirmationCard({