Merge custom order review fixes

This commit is contained in:
sagitchu
2026-11-10 08:27:22 +08:00
4 changed files with 42 additions and 24 deletions
+8 -6
View File
@@ -18,7 +18,8 @@ export function useServerOrder<T extends { id: number }>(
const [items, setItems] = useState<T[]>([]);
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<T extends { id: number }>(
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<T extends { id: number }>(
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<T extends { id: number }>(
if (!mounted.current) return;
if (result.code !== 0) {
setError(
setSaveWarning(
result.transportError
? "排序保存未确认,请检查重新加载后的服务器顺序再重试。"
: result.code === 409
@@ -97,7 +99,7 @@ export function useServerOrder<T extends { id: number }>(
}
} catch {
if (mounted.current)
setError("排序保存未确认,请检查重新加载后的服务器顺序再重试。");
setSaveWarning("排序保存未确认,请检查重新加载后的服务器顺序再重试。");
} finally {
if (mounted.current) {
await reload();
@@ -112,7 +114,7 @@ export function useServerOrder<T extends { id: number }>(
setItems,
loading,
saving,
error,
error: [saveWarning, loadError].filter(Boolean).join(" "),
reload,
onDragStart,
reorder,
+7 -9
View File
@@ -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 (
+7 -9
View File
@@ -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 (
+20
View File
@@ -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 "";
}