From c6b68b299121b83ff037306e5c3d045cf36625b6 Mon Sep 17 00:00:00 2001 From: Danielle Maywood Date: Mon, 9 Mar 2026 15:50:36 +0000 Subject: [PATCH] refactor(site): use standard Spinner in AgentsPage (#22811) --- .../src/pages/AgentsPage/AgentChatInput.stories.tsx | 10 +++++++--- site/src/pages/AgentsPage/AgentChatInput.tsx | 10 ++++------ .../AgentsPage/AgentDetail/ConversationTimeline.tsx | 8 +++++--- site/src/pages/AgentsPage/AgentsSidebar.tsx | 3 ++- .../ChatModelAdminPanel/ChatModelAdminPanel.tsx | 4 ++-- .../AgentsPage/ChatModelAdminPanel/ModelForm.tsx | 10 ++++------ .../AgentsPage/ChatModelAdminPanel/ProviderForm.tsx | 13 ++++++++----- site/src/pages/AgentsPage/QueuedMessagesList.tsx | 6 +++--- site/src/pages/AgentsPage/WebPushButton.tsx | 5 +++-- 9 files changed, 38 insertions(+), 31 deletions(-) diff --git a/site/src/pages/AgentsPage/AgentChatInput.stories.tsx b/site/src/pages/AgentsPage/AgentChatInput.stories.tsx index 47245db2f6..1170ae7fb8 100644 --- a/site/src/pages/AgentsPage/AgentChatInput.stories.tsx +++ b/site/src/pages/AgentsPage/AgentChatInput.stories.tsx @@ -112,9 +112,13 @@ export const LoadingSpinner: Story = { const canvas = within(canvasElement); const sendButton = canvas.getByRole("button", { name: "Send" }); expect(sendButton).toBeDisabled(); - // The Loader2Icon renders with the animate-spin class when - // isLoading is true. - expect(sendButton.querySelector(".animate-spin")).toBeTruthy(); + // The Spinner component renders an SVG with a "Loading spinner" + // title when isLoading is true. + const spinnerSvg = sendButton.querySelector("svg"); + expect(spinnerSvg).toBeTruthy(); + expect(spinnerSvg?.querySelector("title")?.textContent).toBe( + "Loading spinner", + ); }, }; diff --git a/site/src/pages/AgentsPage/AgentChatInput.tsx b/site/src/pages/AgentsPage/AgentChatInput.tsx index 41ac54fa94..33f407634c 100644 --- a/site/src/pages/AgentsPage/AgentChatInput.tsx +++ b/site/src/pages/AgentsPage/AgentChatInput.tsx @@ -8,6 +8,7 @@ import { ChatMessageInput, type ChatMessageInputRef, } from "components/ChatMessageInput/ChatMessageInput"; +import { Spinner } from "components/Spinner/Spinner"; import { Tooltip, TooltipContent, @@ -17,7 +18,6 @@ import { AlertTriangleIcon, ArrowUpIcon, ImageIcon, - Loader2Icon, Square, XIcon, } from "lucide-react"; @@ -274,7 +274,7 @@ export const AttachmentPreview = memo<{ )} {uploadState?.status === "uploading" && (
- +
)} {uploadState?.status === "error" && ( @@ -565,9 +565,7 @@ export const AgentChatInput = memo( {isEditingHistoryMessage && editingQueuedMessageID === null && (
- {isLoading && ( - - )} + {isLoading && } {isLoading ? "Saving edit..." : "Editing message"}
diff --git a/site/src/pages/AgentsPage/AgentsSidebar.tsx b/site/src/pages/AgentsPage/AgentsSidebar.tsx index 53ce64fd3e..f00259e5ad 100644 --- a/site/src/pages/AgentsPage/AgentsSidebar.tsx +++ b/site/src/pages/AgentsPage/AgentsSidebar.tsx @@ -23,6 +23,7 @@ import { ExternalImage } from "components/ExternalImage/ExternalImage"; import { CoderIcon } from "components/Icons/CoderIcon"; import { ScrollArea } from "components/ScrollArea/ScrollArea"; import { Skeleton } from "components/Skeleton/Skeleton"; +import { Spinner } from "components/Spinner/Spinner"; import { useAuthenticated } from "hooks"; import { AlertTriangleIcon, @@ -445,7 +446,7 @@ const ChatTreeNode = memo(({ chat, isChildNode }) => {
{isArchivingThisChat ? ( - + ) : ( <> diff --git a/site/src/pages/AgentsPage/ChatModelAdminPanel/ChatModelAdminPanel.tsx b/site/src/pages/AgentsPage/ChatModelAdminPanel/ChatModelAdminPanel.tsx index e25cbdba66..920ff3d5b6 100644 --- a/site/src/pages/AgentsPage/ChatModelAdminPanel/ChatModelAdminPanel.tsx +++ b/site/src/pages/AgentsPage/ChatModelAdminPanel/ChatModelAdminPanel.tsx @@ -12,7 +12,7 @@ import { import type * as TypesGen from "api/typesGenerated"; import { Alert, AlertDescription, AlertTitle } from "components/Alert/Alert"; import { ErrorAlert } from "components/Alert/ErrorAlert"; -import { Loader2Icon } from "lucide-react"; +import { Spinner } from "components/Spinner/Spinner"; import { type FC, useMemo, useState } from "react"; import { useMutation, useQuery, useQueryClient } from "react-query"; import { cn } from "utils/cn"; @@ -301,7 +301,7 @@ export const ChatModelAdminPanel: FC = ({
{isLoading && (
- + Loading
)} diff --git a/site/src/pages/AgentsPage/ChatModelAdminPanel/ModelForm.tsx b/site/src/pages/AgentsPage/ChatModelAdminPanel/ModelForm.tsx index e1d3ae5bf8..0b86febfe2 100644 --- a/site/src/pages/AgentsPage/ChatModelAdminPanel/ModelForm.tsx +++ b/site/src/pages/AgentsPage/ChatModelAdminPanel/ModelForm.tsx @@ -9,12 +9,12 @@ import { SelectTrigger, SelectValue, } from "components/Select/Select"; +import { Spinner } from "components/Spinner/Spinner"; import { useFormik } from "formik"; import { ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, - Loader2Icon, } from "lucide-react"; import { type FC, useMemo, useState } from "react"; import { cn } from "utils/cn"; @@ -487,10 +487,8 @@ export const ModelForm: FC = ({ disabled={isDeleting} onClick={() => void onDeleteModel(editingModel.id)} > - {isDeleting && ( - - )} - Delete model + {isDeleting && } + Delete model{" "}
@@ -522,7 +520,7 @@ export const ModelForm: FC = ({ type="submit" disabled={isSaving || !form.isValid || hasFieldErrors} > - {isSaving && } + {isSaving && }{" "} {isEditing ? "Save" : "Add model"}{" "} diff --git a/site/src/pages/AgentsPage/ChatModelAdminPanel/ProviderForm.tsx b/site/src/pages/AgentsPage/ChatModelAdminPanel/ProviderForm.tsx index 3934022a6a..96c2cc86f5 100644 --- a/site/src/pages/AgentsPage/ChatModelAdminPanel/ProviderForm.tsx +++ b/site/src/pages/AgentsPage/ChatModelAdminPanel/ProviderForm.tsx @@ -2,12 +2,13 @@ import type * as TypesGen from "api/typesGenerated"; import { Alert, AlertDescription, AlertTitle } from "components/Alert/Alert"; import { Button } from "components/Button/Button"; import { Input } from "components/Input/Input"; +import { Spinner } from "components/Spinner/Spinner"; import { Tooltip, TooltipContent, TooltipTrigger, } from "components/Tooltip/Tooltip"; -import { ChevronLeftIcon, InfoIcon, Loader2Icon } from "lucide-react"; +import { ChevronLeftIcon, InfoIcon } from "lucide-react"; import { type FC, type FormEvent, useId, useState } from "react"; import { formatProviderLabel } from "../modelOptions"; import type { ProviderState } from "./ChatModelAdminPanel"; @@ -275,9 +276,9 @@ export const ProviderForm: FC = ({ onClick={() => void onDeleteProvider(providerConfig.id)} > {isProviderMutationPending && ( - + )} - Delete provider + Delete provider{" "} @@ -299,9 +300,11 @@ export const ProviderForm: FC = ({ )} )} diff --git a/site/src/pages/AgentsPage/QueuedMessagesList.tsx b/site/src/pages/AgentsPage/QueuedMessagesList.tsx index 74f54b8c2b..3862c17fc9 100644 --- a/site/src/pages/AgentsPage/QueuedMessagesList.tsx +++ b/site/src/pages/AgentsPage/QueuedMessagesList.tsx @@ -1,5 +1,6 @@ import type { ChatQueuedMessage } from "api/typesGenerated"; import { Button } from "components/Button/Button"; +import { Spinner } from "components/Spinner/Spinner"; import { Tooltip, TooltipContent, @@ -8,7 +9,6 @@ import { import { ArrowUpIcon, CornerDownLeftIcon, - Loader2Icon, PencilIcon, Trash2Icon, } from "lucide-react"; @@ -288,7 +288,7 @@ export const QueuedMessagesList: FC = ({ className="size-6 rounded text-content-secondary hover:bg-surface-tertiary hover:text-content-primary" > {isItemBusy && busyItem.action === "promote" ? ( - + ) : ( )} @@ -307,7 +307,7 @@ export const QueuedMessagesList: FC = ({ className="size-6 rounded text-content-secondary hover:bg-surface-tertiary hover:text-content-destructive" > {isItemBusy && busyItem.action === "delete" ? ( - + ) : ( )} diff --git a/site/src/pages/AgentsPage/WebPushButton.tsx b/site/src/pages/AgentsPage/WebPushButton.tsx index e425ae2c51..c482902b40 100644 --- a/site/src/pages/AgentsPage/WebPushButton.tsx +++ b/site/src/pages/AgentsPage/WebPushButton.tsx @@ -1,12 +1,13 @@ import { getErrorMessage } from "api/errors"; import { Button } from "components/Button/Button"; +import { Spinner } from "components/Spinner/Spinner"; import { Tooltip, TooltipContent, TooltipTrigger, } from "components/Tooltip/Tooltip"; import { useWebpushNotifications } from "contexts/useWebpushNotifications"; -import { BellIcon, BellOffIcon, Loader2Icon } from "lucide-react"; +import { BellIcon, BellOffIcon } from "lucide-react"; import type { FC } from "react"; import { toast } from "sonner"; @@ -51,7 +52,7 @@ export const WebPushButton: FC = () => { className="h-7 w-7 text-content-secondary hover:text-content-primary" > {webPush.loading ? ( - + ) : webPush.subscribed ? ( ) : (