mirror of
https://github.com/vxcontrol/pentagi.git
synced 2026-08-25 12:36:30 +00:00
refactor(ui): finish the Spinner migration, retire the Loader2 alias from JSX
The remaining 20 rendered Loader2 spinners carried a deliberate size or colour, so
the earlier pass left them. They convert cleanly after all: Loader2 is a lucide
alias of LoaderCircle (`LoaderCircle as Loader2` in lucide-react's d.ts) and that
is exactly what Spinner variant="circle" renders, while Circle merges an incoming
className over its built-in animate-spin. So each site keeps its size/colour class
and only drops the now-redundant animate-spin. Every rendered spinner in the app is
the Spinner primitive now.
flow-status-icon and flow-task-status-icon keep Loader2: there it is a value in a
Record<StatusType, { icon: LucideIcon }> map, not a rendered spinner, and Spinner
is a variant wrapper rather than a LucideIcon — it does not fit that slot.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
d4dabc2783
commit
9cbda709b6
@@ -1,9 +1,10 @@
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
import { BarChart2, Loader2 } from 'lucide-react';
|
||||
import { BarChart2 } from 'lucide-react';
|
||||
import { ResponsiveContainer } from 'recharts';
|
||||
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
|
||||
export function ChartCard({
|
||||
children,
|
||||
@@ -34,7 +35,10 @@ export function ChartCard({
|
||||
className="flex items-center justify-center"
|
||||
style={{ height }}
|
||||
>
|
||||
<Loader2 className="text-muted-foreground size-6 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-6"
|
||||
variant="circle"
|
||||
/>
|
||||
</div>
|
||||
) : empty ? (
|
||||
<div
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { AriaAttributes, Ref } from 'react';
|
||||
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { lazy, Suspense, useImperativeHandle, useRef } from 'react';
|
||||
|
||||
import type { TextareaRef } from '@/components/ui/textarea';
|
||||
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
@@ -118,7 +118,10 @@ export function MarkdownEditorField({
|
||||
)}
|
||||
id={id}
|
||||
>
|
||||
<Loader2 className="text-muted-foreground size-5 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-5"
|
||||
variant="circle"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
||||
@@ -4,9 +4,9 @@ import type { AriaAttributes, Ref } from 'react';
|
||||
import { history } from '@tiptap/pm/history';
|
||||
import { EditorState, TextSelection } from '@tiptap/pm/state';
|
||||
import { EditorContent, useEditor } from '@tiptap/react';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
import { createMarkdownExtensions } from './markdown-editor-extensions';
|
||||
@@ -121,7 +121,10 @@ function MarkdownEditor({
|
||||
)}
|
||||
data-slot="markdown-editor"
|
||||
>
|
||||
<Loader2 className="text-muted-foreground size-5 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-5"
|
||||
variant="circle"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon } from 'lucide-react';
|
||||
import { CircleCheckIcon, InfoIcon, OctagonXIcon, TriangleAlertIcon } from 'lucide-react';
|
||||
import { Toaster as Sonner, type ToasterProps } from 'sonner';
|
||||
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { useTheme } from '@/hooks/use-theme';
|
||||
|
||||
function Toaster({ ...props }: ToasterProps) {
|
||||
@@ -14,7 +15,12 @@ function Toaster({ ...props }: ToasterProps) {
|
||||
icons={{
|
||||
error: <OctagonXIcon className="size-4" />,
|
||||
info: <InfoIcon className="size-4" />,
|
||||
loading: <Loader2Icon className="size-4 animate-spin" />,
|
||||
loading: (
|
||||
<Spinner
|
||||
className="size-4"
|
||||
variant="circle"
|
||||
/>
|
||||
),
|
||||
success: <CircleCheckIcon className="size-4" />,
|
||||
warning: <TriangleAlertIcon className="size-4" />,
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useQuery } from '@apollo/client/react';
|
||||
import { Activity, CircleDollarSign, Cpu, GitFork, Loader2 } from 'lucide-react';
|
||||
import { Activity, CircleDollarSign, Cpu, GitFork } from 'lucide-react';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import type { UsageStatsFragmentFragment } from '@/graphql/types';
|
||||
@@ -7,6 +7,7 @@ import type { UsageStatsFragmentFragment } from '@/graphql/types';
|
||||
import { MetricCard } from '@/components/dashboard';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import FlowAgentIcon from '@/features/flows/agents/flow-agent-icon';
|
||||
import {
|
||||
@@ -304,7 +305,10 @@ export function FlowDashboardOverview({ flowId }: { flowId: string }) {
|
||||
function LoadingTable() {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 className="text-muted-foreground size-6 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-6"
|
||||
variant="circle"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useQuery } from '@apollo/client/react';
|
||||
import { format } from 'date-fns';
|
||||
import { ChevronRight, Clock, Loader2, Wrench } from 'lucide-react';
|
||||
import { ChevronRight, Clock, Wrench } from 'lucide-react';
|
||||
import { memo, useDeferredValue, useMemo, useRef, useState } from 'react';
|
||||
import { Area, AreaChart, Bar, BarChart, CartesianGrid, Tooltip, XAxis, YAxis } from 'recharts';
|
||||
|
||||
@@ -11,6 +11,7 @@ import { FlowStatusBadge } from '@/components/icons/flow-status-badge';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import {
|
||||
FlowsDocument,
|
||||
FlowsExecutionStatsByPeriodDocument,
|
||||
@@ -362,7 +363,10 @@ export function DashboardAnalytics({ period }: { period: UsageStatsPeriod }) {
|
||||
<CardContent>
|
||||
{executionStatsLoading ? (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 className="text-muted-foreground size-6 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-6"
|
||||
variant="circle"
|
||||
/>
|
||||
</div>
|
||||
) : !deferredExecutionStats.length ? (
|
||||
<p className="text-muted-foreground py-8 text-center text-sm">
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { useQuery } from '@apollo/client/react';
|
||||
import { Activity, CircleDollarSign, Cpu, GitFork, Loader2 } from 'lucide-react';
|
||||
import { Activity, CircleDollarSign, Cpu, GitFork } from 'lucide-react';
|
||||
|
||||
import type { UsageStatsFragmentFragment } from '@/graphql/types';
|
||||
|
||||
import { MetricCard } from '@/components/dashboard';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import {
|
||||
FlowsStatsTotalDocument,
|
||||
@@ -165,7 +166,10 @@ export function DashboardOverview() {
|
||||
function LoadingTable() {
|
||||
return (
|
||||
<div className="flex items-center justify-center py-8">
|
||||
<Loader2 className="text-muted-foreground size-6 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-6"
|
||||
variant="circle"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
ExternalLink,
|
||||
GitFork,
|
||||
GripVertical,
|
||||
Loader2,
|
||||
NotepadText,
|
||||
Pause,
|
||||
PencilLine,
|
||||
@@ -376,7 +375,10 @@ function Flow() {
|
||||
<div className="relative flex h-[calc(100dvh-3rem)] w-full max-w-full flex-1">
|
||||
{isFlowLoading && (
|
||||
<div className="bg-background/50 absolute inset-0 z-50 flex items-center justify-center">
|
||||
<Loader2 className="size-16 animate-spin" />
|
||||
<Spinner
|
||||
className="size-16"
|
||||
variant="circle"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{isDesktop ? (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
import { useMutation } from '@apollo/client/react';
|
||||
import { Ellipsis, Eye, GitFork, Loader2, Pause, Pencil, PencilLine, Plus, Star, Trash } from 'lucide-react';
|
||||
import { Ellipsis, Eye, GitFork, Pause, Pencil, PencilLine, Plus, Star, Trash } from 'lucide-react';
|
||||
import { CheckCircle2, XCircle } from 'lucide-react';
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
@@ -593,7 +593,10 @@ function Flows() {
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia>
|
||||
<Loader2 className="text-muted-foreground size-10 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-10"
|
||||
variant="circle"
|
||||
/>
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>Loading flows...</EmptyTitle>
|
||||
<EmptyDescription>Please wait while we fetch your conversation flows</EmptyDescription>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ColumnDef } from '@tanstack/react-table';
|
||||
|
||||
import { Ellipsis, LibraryBig, Loader2, Pencil, PencilLine, Plus, Trash } from 'lucide-react';
|
||||
import { Ellipsis, LibraryBig, Pencil, PencilLine, Plus, Trash } from 'lucide-react';
|
||||
import { useCallback, useRef, useState } from 'react';
|
||||
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { toast } from 'sonner';
|
||||
@@ -408,7 +408,10 @@ function Knowledges() {
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia>
|
||||
<Loader2 className="text-muted-foreground size-10 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-10"
|
||||
variant="circle"
|
||||
/>
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>Loading knowledges...</EmptyTitle>
|
||||
<EmptyDescription>Please wait while we fetch your knowledge documents</EmptyDescription>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Loader2 } from 'lucide-react';
|
||||
import { useLocation, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import Logo from '@/components/icons/logo';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import LoginForm from '@/features/authentication/login-form';
|
||||
import { routes } from '@/lib/routes';
|
||||
import { getSafeReturnUrl } from '@/lib/utils/auth';
|
||||
@@ -28,7 +28,10 @@ function Login() {
|
||||
returnUrl={returnUrl}
|
||||
/>
|
||||
) : (
|
||||
<Loader2 className="size-16 animate-spin" />
|
||||
<Spinner
|
||||
className="size-16"
|
||||
variant="circle"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="from-primary/20 via-primary/10 to-background hidden bg-linear-to-br lg:flex">
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
Ellipsis,
|
||||
ExternalLink,
|
||||
Key,
|
||||
Loader2,
|
||||
Pencil,
|
||||
Plus,
|
||||
Trash,
|
||||
@@ -872,7 +871,10 @@ function SettingsAPITokens() {
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia>
|
||||
<Loader2 className="text-muted-foreground size-10 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-10"
|
||||
variant="circle"
|
||||
/>
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>Loading tokens...</EmptyTitle>
|
||||
<EmptyDescription>Please wait while we fetch your API tokens</EmptyDescription>
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
Ellipsis,
|
||||
FileDiff,
|
||||
FileText,
|
||||
Loader2,
|
||||
RotateCcw,
|
||||
Save,
|
||||
User,
|
||||
@@ -734,7 +733,10 @@ function SettingsPrompt() {
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia>
|
||||
<Loader2 className="text-muted-foreground size-10 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-10"
|
||||
variant="circle"
|
||||
/>
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>Loading prompt data...</EmptyTitle>
|
||||
<EmptyDescription>Please wait while we fetch prompt information</EmptyDescription>
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
Code,
|
||||
Ellipsis,
|
||||
FileText,
|
||||
Loader2,
|
||||
Pencil,
|
||||
RotateCcw,
|
||||
Settings,
|
||||
@@ -40,6 +39,7 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@/components/ui/empty';
|
||||
import { Spinner } from '@/components/ui/spinner';
|
||||
import { DeletePromptDocument, SettingsPromptsDocument } from '@/graphql/types';
|
||||
import { usePageStorageKeys } from '@/hooks/use-page-storage-keys';
|
||||
import { routes } from '@/lib/routes';
|
||||
@@ -414,7 +414,10 @@ function SettingsPrompts() {
|
||||
resetOperation?.promptName === agent.name &&
|
||||
resetOperation?.type === 'system' ? (
|
||||
<>
|
||||
<Loader2 className="size-3 animate-spin" />
|
||||
<Spinner
|
||||
className="size-3"
|
||||
variant="circle"
|
||||
/>
|
||||
Resetting...
|
||||
</>
|
||||
) : (
|
||||
@@ -438,7 +441,10 @@ function SettingsPrompts() {
|
||||
resetOperation?.promptName === agent.name &&
|
||||
resetOperation?.type === 'human' ? (
|
||||
<>
|
||||
<Loader2 className="size-3 animate-spin" />
|
||||
<Spinner
|
||||
className="size-3"
|
||||
variant="circle"
|
||||
/>
|
||||
Resetting...
|
||||
</>
|
||||
) : (
|
||||
@@ -462,7 +468,10 @@ function SettingsPrompts() {
|
||||
resetOperation?.promptName === agent.name &&
|
||||
resetOperation?.type === 'all' ? (
|
||||
<>
|
||||
<Loader2 className="size-3 animate-spin" />
|
||||
<Spinner
|
||||
className="size-3"
|
||||
variant="circle"
|
||||
/>
|
||||
Resetting...
|
||||
</>
|
||||
) : (
|
||||
@@ -565,7 +574,10 @@ function SettingsPrompts() {
|
||||
resetOperation?.promptName === tool.name &&
|
||||
resetOperation?.type === 'tool' ? (
|
||||
<>
|
||||
<Loader2 className="size-3 animate-spin" />
|
||||
<Spinner
|
||||
className="size-3"
|
||||
variant="circle"
|
||||
/>
|
||||
Resetting...
|
||||
</>
|
||||
) : (
|
||||
@@ -786,7 +798,10 @@ function SettingsPrompts() {
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia>
|
||||
<Loader2 className="text-muted-foreground size-10 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-10"
|
||||
variant="circle"
|
||||
/>
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>Loading prompts...</EmptyTitle>
|
||||
<EmptyDescription>Please wait while we fetch your prompt templates</EmptyDescription>
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
Clock,
|
||||
Ellipsis,
|
||||
Lightbulb,
|
||||
Loader2,
|
||||
Play,
|
||||
Plug,
|
||||
Save,
|
||||
@@ -1564,7 +1563,10 @@ function SettingsProvider() {
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia>
|
||||
<Loader2 className="text-muted-foreground size-10 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-10"
|
||||
variant="circle"
|
||||
/>
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>Loading provider data...</EmptyTitle>
|
||||
<EmptyDescription>Please wait while we fetch provider configuration</EmptyDescription>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ColumnDef, Row } from '@tanstack/react-table';
|
||||
|
||||
import { useMutation, useQuery } from '@apollo/client/react';
|
||||
import { AlertCircle, ChevronDown, Copy, Ellipsis, Loader2, Pencil, Plug, Plus, Settings, Trash } from 'lucide-react';
|
||||
import { AlertCircle, ChevronDown, Copy, Ellipsis, Pencil, Plug, Plus, Settings, Trash } from 'lucide-react';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
@@ -412,7 +412,10 @@ function SettingsProviders() {
|
||||
<Empty>
|
||||
<EmptyHeader>
|
||||
<EmptyMedia>
|
||||
<Loader2 className="text-muted-foreground size-10 animate-spin" />
|
||||
<Spinner
|
||||
className="text-muted-foreground size-10"
|
||||
variant="circle"
|
||||
/>
|
||||
</EmptyMedia>
|
||||
<EmptyTitle>Loading providers...</EmptyTitle>
|
||||
<EmptyDescription>Please wait while we fetch your provider configurations</EmptyDescription>
|
||||
|
||||
Reference in New Issue
Block a user