mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
refactor(site): address plan-mode frontend review feedback (#24426)
> This PR was authored by Mux on behalf of Mike. Address all 8 frontend review comments from DanielleMaywood on #24236. ## Changes **Low-risk cleanups:** - Inlined module-level `toolBadgeClassName` in `AgentChatInput.tsx` - Inlined `planModeInvisibleCharWarning` variable in `PlanModeInstructionsSettings.tsx` - Replaced loose `nilUUID` and `clearPlanMode` sentinels in `chats.ts` with a `toChatPlanModePayload()` helper and inline nil UUID. Page-level mutation callers now pass `undefined` to clear plan mode instead of `""`. **Tool state management:** - Replaced manual `isSubmitting`/`setIsSubmitting` in `ProposePlanTool.tsx` with `useMutation` - Overhauled `AskUserQuestionTool.tsx`: replaced `cloneAnswer` with `structuredClone`, replaced `setIsSubmitting` with `useMutation`, extracted `QuestionStep`, `QuestionOption`, `OtherQuestionOption`, and `AnsweredQuestionText` components **Timeline complexity reduction:** - Extracted `deriveMessageDisplayState()` into `messageHelpers.ts` (pure, testable) - Extracted user-message rendering into `UserMessageContent.tsx` - Reduced `ConversationTimeline.tsx` by ~285 lines ## Validation - TypeScript: pass - Lint (Biome + ESLint): pass - React Compiler: 247 functions, 0 diagnostics - Storybook tests: 42/42 pass (ProposePlanTool 9, ConversationTimeline 22, AskUserQuestionTool 11)
This commit is contained in:
@@ -211,7 +211,6 @@ export const cancelChatListRefetches = (queryClient: QueryClient) => {
|
||||
};
|
||||
|
||||
const DEFAULT_CHAT_PAGE_LIMIT = 50;
|
||||
const nilUUID = "00000000-0000-0000-0000-000000000000";
|
||||
|
||||
type UpdateChatWorkspaceVariables = {
|
||||
chatId: string;
|
||||
@@ -220,10 +219,17 @@ type UpdateChatWorkspaceVariables = {
|
||||
|
||||
type UpdateChatPlanModeVariables = {
|
||||
chatId: string;
|
||||
planMode?: ChatPlanModeOrClear;
|
||||
planMode?: TypesGen.ChatPlanMode;
|
||||
};
|
||||
|
||||
const clearPlanMode = "" satisfies ChatPlanModeOrClear;
|
||||
const CLEAR_PLAN_MODE_WIRE_VALUE = "" satisfies ChatPlanModeOrClear;
|
||||
|
||||
const toChatPlanModePayload = (
|
||||
planMode: TypesGen.ChatPlanMode | undefined,
|
||||
): ChatPlanModeOrClear => {
|
||||
// The API expects an empty string on the wire to clear plan mode.
|
||||
return planMode ?? CLEAR_PLAN_MODE_WIRE_VALUE;
|
||||
};
|
||||
|
||||
export const infiniteChats = (opts?: { q?: string; archived?: boolean }) => {
|
||||
const limit = DEFAULT_CHAT_PAGE_LIMIT;
|
||||
@@ -407,7 +413,7 @@ export const unarchiveChat = (queryClient: QueryClient) => ({
|
||||
export const updateChatPlanMode = (queryClient: QueryClient) => ({
|
||||
mutationFn: ({ chatId, planMode }: UpdateChatPlanModeVariables) =>
|
||||
API.experimental.updateChat(chatId, {
|
||||
plan_mode: planMode ?? clearPlanMode,
|
||||
plan_mode: toChatPlanModePayload(planMode),
|
||||
}),
|
||||
onMutate: async ({ chatId, planMode }: UpdateChatPlanModeVariables) => {
|
||||
await queryClient.cancelQueries({
|
||||
@@ -421,16 +427,15 @@ export const updateChatPlanMode = (queryClient: QueryClient) => ({
|
||||
const previousChat = queryClient.getQueryData<TypesGen.Chat>(
|
||||
chatKey(chatId),
|
||||
);
|
||||
const nextPlanMode = planMode === clearPlanMode ? undefined : planMode;
|
||||
updateInfiniteChatsCache(queryClient, (chats) =>
|
||||
chats.map((chat) =>
|
||||
chat.id === chatId ? { ...chat, plan_mode: nextPlanMode } : chat,
|
||||
chat.id === chatId ? { ...chat, plan_mode: planMode } : chat,
|
||||
),
|
||||
);
|
||||
if (previousChat) {
|
||||
queryClient.setQueryData<TypesGen.Chat>(chatKey(chatId), {
|
||||
...previousChat,
|
||||
plan_mode: nextPlanMode,
|
||||
plan_mode: planMode,
|
||||
});
|
||||
}
|
||||
return { previousChat };
|
||||
@@ -466,7 +471,10 @@ export const updateChatPlanMode = (queryClient: QueryClient) => ({
|
||||
export const updateChatWorkspace = (queryClient: QueryClient) => ({
|
||||
mutationFn: ({ chatId, workspaceId }: UpdateChatWorkspaceVariables) =>
|
||||
API.experimental.updateChat(chatId, {
|
||||
workspace_id: workspaceId ?? nilUUID,
|
||||
workspace_id:
|
||||
workspaceId ??
|
||||
// The API uses the nil UUID to clear the workspace association.
|
||||
"00000000-0000-0000-0000-000000000000",
|
||||
}),
|
||||
onMutate: async ({ chatId, workspaceId }: UpdateChatWorkspaceVariables) => {
|
||||
await queryClient.cancelQueries({
|
||||
|
||||
Reference in New Issue
Block a user