feat(FN-4191): complete Step 4 — add chat room settings controls
Fusion-Task-Id: FN-4191 Fusion-Task-Lineage: 00fddcfc-e136-41a5-84b1-b6f53b1692cb
This commit is contained in:
@@ -2037,6 +2037,52 @@ export function SettingsModal({
|
|||||||
</label>
|
</label>
|
||||||
<small>Show the floating chat button in the dashboard. Chat is still accessible from the Chat tab in the mobile navigation.</small>
|
<small>Show the floating chat button in the dashboard. Chat is still accessible from the Chat tab in the mobile navigation.</small>
|
||||||
</div>
|
</div>
|
||||||
|
<h4 className="settings-section-heading settings-section-heading--spaced">Chat Rooms</h4>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="chatRoomRecentVerbatimMessages">Recent verbatim room messages</label>
|
||||||
|
<input
|
||||||
|
id="chatRoomRecentVerbatimMessages"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
className="input"
|
||||||
|
placeholder="12"
|
||||||
|
value={form.chatRoomRecentVerbatimMessages ?? ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
setForm((f) => ({ ...f, chatRoomRecentVerbatimMessages: Number(e.target.value) || undefined }))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<small>Number of most-recent chat-room messages kept verbatim in the responder transcript. Older messages are compacted into a summary block. Default: 12.</small>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="chatRoomCompactionFetchLimit">Room compaction fetch limit</label>
|
||||||
|
<input
|
||||||
|
id="chatRoomCompactionFetchLimit"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
className="input"
|
||||||
|
placeholder="80"
|
||||||
|
value={form.chatRoomCompactionFetchLimit ?? ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
setForm((f) => ({ ...f, chatRoomCompactionFetchLimit: Number(e.target.value) || undefined }))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<small>Upper bound on messages fetched from the room store for compaction consideration. Default: 80.</small>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="chatRoomSummaryMaxChars">Room summary max characters</label>
|
||||||
|
<input
|
||||||
|
id="chatRoomSummaryMaxChars"
|
||||||
|
type="number"
|
||||||
|
min="200"
|
||||||
|
className="input"
|
||||||
|
placeholder="1500"
|
||||||
|
value={form.chatRoomSummaryMaxChars ?? ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
setForm((f) => ({ ...f, chatRoomSummaryMaxChars: Number(e.target.value) || undefined }))
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<small>Hard cap on the synthesized "Earlier room context" summary block. Default: 1500.</small>
|
||||||
|
</div>
|
||||||
<h4 className="settings-section-heading settings-section-heading--spaced">Capacity Risk Banner</h4>
|
<h4 className="settings-section-heading settings-section-heading--spaced">Capacity Risk Banner</h4>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="capacityRiskBannerEnabled" className="checkbox-label">
|
<label htmlFor="capacityRiskBannerEnabled" className="checkbox-label">
|
||||||
|
|||||||
@@ -824,6 +824,35 @@ describe("SettingsModal", () => {
|
|||||||
expect(ephemeralToggle.checked).toBe(true);
|
expect(ephemeralToggle.checked).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("renders and saves chat room compaction controls", async () => {
|
||||||
|
renderModal({ initialSection: "general" });
|
||||||
|
await waitForSettingsModalReady();
|
||||||
|
|
||||||
|
expect(screen.getByRole("heading", { name: "Chat Rooms" })).toBeInTheDocument();
|
||||||
|
|
||||||
|
const recentInput = screen.getByLabelText("Recent verbatim room messages") as HTMLInputElement;
|
||||||
|
const fetchLimitInput = screen.getByLabelText("Room compaction fetch limit") as HTMLInputElement;
|
||||||
|
const summaryMaxInput = screen.getByLabelText("Room summary max characters") as HTMLInputElement;
|
||||||
|
|
||||||
|
expect(recentInput.placeholder).toBe("12");
|
||||||
|
expect(fetchLimitInput.placeholder).toBe("80");
|
||||||
|
expect(summaryMaxInput.placeholder).toBe("1500");
|
||||||
|
|
||||||
|
await userEvent.type(recentInput, "7");
|
||||||
|
await userEvent.type(fetchLimitInput, "60");
|
||||||
|
await userEvent.type(summaryMaxInput, "900");
|
||||||
|
await userEvent.click(screen.getByRole("button", { name: "Save" }));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockUpdateSettings).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
const payload = mockUpdateSettings.mock.calls[0][0] as Record<string, unknown>;
|
||||||
|
expect(payload.chatRoomRecentVerbatimMessages).toBe(7);
|
||||||
|
expect(payload.chatRoomCompactionFetchLimit).toBe(60);
|
||||||
|
expect(payload.chatRoomSummaryMaxChars).toBe(900);
|
||||||
|
});
|
||||||
|
|
||||||
it("renders and saves GitHub tracking controls in the General section", async () => {
|
it("renders and saves GitHub tracking controls in the General section", async () => {
|
||||||
renderModal({ initialSection: "general" });
|
renderModal({ initialSection: "general" });
|
||||||
await waitForSettingsModalReady();
|
await waitForSettingsModalReady();
|
||||||
|
|||||||
Reference in New Issue
Block a user