From ab00180c0b1cb928f6f439e428af01f6e6802e4b Mon Sep 17 00:00:00 2001 From: jvzijp <589761+jvzijp@users.noreply.github.com> Date: Tue, 7 Apr 2026 23:08:03 +0200 Subject: [PATCH] fix(web): distinguish singular/plural in pending action submit label --- .../chat/ComposerPrimaryActions.test.ts | 93 +++++++++++++++++++ .../chat/ComposerPrimaryActions.tsx | 9 +- 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 apps/web/src/components/chat/ComposerPrimaryActions.test.ts diff --git a/apps/web/src/components/chat/ComposerPrimaryActions.test.ts b/apps/web/src/components/chat/ComposerPrimaryActions.test.ts new file mode 100644 index 0000000000..1982f145e2 --- /dev/null +++ b/apps/web/src/components/chat/ComposerPrimaryActions.test.ts @@ -0,0 +1,93 @@ +import { describe, expect, it } from "vitest"; + +import { formatPendingPrimaryActionLabel } from "./ComposerPrimaryActions"; + +describe("formatPendingPrimaryActionLabel", () => { + it("returns 'Submitting...' while responding", () => { + expect( + formatPendingPrimaryActionLabel({ + compact: false, + isLastQuestion: false, + isResponding: true, + questionIndex: 0, + }), + ).toBe("Submitting..."); + }); + + it("returns 'Submitting...' while responding regardless of other flags", () => { + expect( + formatPendingPrimaryActionLabel({ + compact: true, + isLastQuestion: true, + isResponding: true, + questionIndex: 3, + }), + ).toBe("Submitting..."); + }); + + it("returns 'Submit' in compact mode on the last question", () => { + expect( + formatPendingPrimaryActionLabel({ + compact: true, + isLastQuestion: true, + isResponding: false, + questionIndex: 0, + }), + ).toBe("Submit"); + }); + + it("returns 'Next' in compact mode when not the last question", () => { + expect( + formatPendingPrimaryActionLabel({ + compact: true, + isLastQuestion: false, + isResponding: false, + questionIndex: 1, + }), + ).toBe("Next"); + }); + + it("returns 'Next question' when not the last question", () => { + expect( + formatPendingPrimaryActionLabel({ + compact: false, + isLastQuestion: false, + isResponding: false, + questionIndex: 0, + }), + ).toBe("Next question"); + }); + + it("returns singular 'Submit answer' on the last question when it is the only question", () => { + expect( + formatPendingPrimaryActionLabel({ + compact: false, + isLastQuestion: true, + isResponding: false, + questionIndex: 0, + }), + ).toBe("Submit answer"); + }); + + it("returns plural 'Submit answers' on the last question when there are multiple questions", () => { + expect( + formatPendingPrimaryActionLabel({ + compact: false, + isLastQuestion: true, + isResponding: false, + questionIndex: 1, + }), + ).toBe("Submit answers"); + }); + + it("returns plural 'Submit answers' for higher question indices", () => { + expect( + formatPendingPrimaryActionLabel({ + compact: false, + isLastQuestion: true, + isResponding: false, + questionIndex: 5, + }), + ).toBe("Submit answers"); + }); +}); diff --git a/apps/web/src/components/chat/ComposerPrimaryActions.tsx b/apps/web/src/components/chat/ComposerPrimaryActions.tsx index 09b343c900..847c1ca17c 100644 --- a/apps/web/src/components/chat/ComposerPrimaryActions.tsx +++ b/apps/web/src/components/chat/ComposerPrimaryActions.tsx @@ -27,10 +27,11 @@ interface ComposerPrimaryActionsProps { onImplementPlanInNewThread: () => void; } -const formatPendingPrimaryActionLabel = (input: { +export const formatPendingPrimaryActionLabel = (input: { compact: boolean; isLastQuestion: boolean; isResponding: boolean; + questionIndex: number; }) => { if (input.isResponding) { return "Submitting..."; @@ -38,7 +39,10 @@ const formatPendingPrimaryActionLabel = (input: { if (input.compact) { return input.isLastQuestion ? "Submit" : "Next"; } - return input.isLastQuestion ? "Submit answers" : "Next question"; + if (!input.isLastQuestion) { + return "Next question"; + } + return input.questionIndex > 0 ? "Submit answers" : "Submit answer"; }; export const ComposerPrimaryActions = memo(function ComposerPrimaryActions({ @@ -95,6 +99,7 @@ export const ComposerPrimaryActions = memo(function ComposerPrimaryActions({ compact, isLastQuestion: pendingAction.isLastQuestion, isResponding: pendingAction.isResponding, + questionIndex: pendingAction.questionIndex, })}