diff --git a/vite-frontend/src/hooks/use-server-order.ts b/vite-frontend/src/hooks/use-server-order.ts index 0ec6a9a..b1be00a 100644 --- a/vite-frontend/src/hooks/use-server-order.ts +++ b/vite-frontend/src/hooks/use-server-order.ts @@ -18,7 +18,8 @@ export function useServerOrder( const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); - const [error, setError] = useState(""); + const [loadError, setLoadError] = useState(""); + const [saveWarning, setSaveWarning] = useState(""); const mounted = useRef(false); const request = useRef(0); const savingRef = useRef(false); @@ -36,11 +37,12 @@ export function useServerOrder( if (!mounted.current || version !== request.current) return; setItems(rows); + setLoadError(""); } catch { if (!mounted.current || version !== request.current) return; // Never expose a partial or unverified set as reorderable after failure. setItems([]); - setError("加载列表失败,请重试后再排序。"); + setLoadError("加载列表失败,请重试后再排序。"); } finally { if (mounted.current && version === request.current) setLoading(false); } @@ -78,7 +80,7 @@ export function useServerOrder( if (from < 0 || to < 0) return; savingRef.current = true; setSaving(true); - setError(""); + setSaveWarning(""); try { const result = await saveOrder({ ids: arrayMove(items, from, to).map((item) => item.id), @@ -87,7 +89,7 @@ export function useServerOrder( if (!mounted.current) return; if (result.code !== 0) { - setError( + setSaveWarning( result.transportError ? "排序保存未确认,请检查重新加载后的服务器顺序再重试。" : result.code === 409 @@ -97,7 +99,7 @@ export function useServerOrder( } } catch { if (mounted.current) - setError("排序保存未确认,请检查重新加载后的服务器顺序再重试。"); + setSaveWarning("排序保存未确认,请检查重新加载后的服务器顺序再重试。"); } finally { if (mounted.current) { await reload(); @@ -112,7 +114,7 @@ export function useServerOrder( setItems, loading, saving, - error, + error: [saveWarning, loadError].filter(Boolean).join(" "), reload, onDragStart, reorder, diff --git a/vite-frontend/src/pages/limit.tsx b/vite-frontend/src/pages/limit.tsx index c49d797..5e45779 100644 --- a/vite-frontend/src/pages/limit.tsx +++ b/vite-frontend/src/pages/limit.tsx @@ -9,6 +9,7 @@ import { OrderStatus, } from "@/components/server-order"; import { useServerOrder } from "@/hooks/use-server-order"; +import { getOrderDisabledReason } from "@/utils/server-order"; import { isAdmin } from "@/utils/auth"; import { AnimatedPage, StaggerList } from "@/components/animated-page"; import { SearchBar } from "@/components/search-bar"; @@ -216,15 +217,12 @@ export default function LimitPage() { } }; - const orderReason = !isAdmin() - ? "仅管理员可调整全局顺序。" - : searchKeyword.length > 0 - ? "搜索期间无法排序,请清空搜索后重试。" - : order.saving - ? "正在保存顺序,请稍候。" - : loading || submitLoading || deleteLoading - ? "正在加载或更新列表,请稍候。" - : ""; + const orderReason = getOrderDisabledReason({ + isAdmin: isAdmin(), + searchKeyword, + saving: order.saving, + busy: loading || submitLoading || deleteLoading, + }); const orderDisabled = Boolean(orderReason); return ( diff --git a/vite-frontend/src/pages/user.tsx b/vite-frontend/src/pages/user.tsx index 4262c65..aa62139 100644 --- a/vite-frontend/src/pages/user.tsx +++ b/vite-frontend/src/pages/user.tsx @@ -5,6 +5,7 @@ import { LayoutGrid, List } from "lucide-react"; import { isAdmin } from "@/utils/auth"; import { useServerOrder } from "@/hooks/use-server-order"; +import { getOrderDisabledReason } from "@/utils/server-order"; import { OrderHandle, OrderItem, @@ -989,15 +990,12 @@ export default function UserPage() { return userTunnels.some((ut) => ut.tunnelId === tunnelId); }; - const orderReason = !isAdmin() - ? "仅管理员可调整全局顺序。" - : searchKeyword.length > 0 - ? "搜索期间无法排序,请清空搜索后重试。" - : order.saving - ? "正在保存顺序,请稍候。" - : loading || userFormLoading || deleteLoading - ? "正在加载或更新列表,请稍候。" - : ""; + const orderReason = getOrderDisabledReason({ + isAdmin: isAdmin(), + searchKeyword, + saving: order.saving, + busy: loading || userFormLoading || deleteLoading, + }); const orderDisabled = Boolean(orderReason); return ( diff --git a/vite-frontend/src/utils/server-order.ts b/vite-frontend/src/utils/server-order.ts new file mode 100644 index 0000000..3ccb7ca --- /dev/null +++ b/vite-frontend/src/utils/server-order.ts @@ -0,0 +1,20 @@ +interface OrderAvailability { + isAdmin: boolean; + searchKeyword: string; + saving: boolean; + busy: boolean; +} + +export function getOrderDisabledReason({ + isAdmin, + searchKeyword, + saving, + busy, +}: OrderAvailability): string { + if (!isAdmin) return "仅管理员可调整全局顺序。"; + if (searchKeyword.length > 0) return "搜索期间无法排序,请清空搜索后重试。"; + if (saving) return "正在保存顺序,请稍候。"; + if (busy) return "正在加载或更新列表,请稍候。"; + + return ""; +}