mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-08 02:36:37 +08:00
feat(node): split node page into local and remote sections
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect, useMemo, useCallback } from "react";
|
import { useState, useEffect, useMemo, useCallback } from "react";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
import { useNavigate } from "react-router-dom";
|
|
||||||
import {
|
import {
|
||||||
DndContext,
|
DndContext,
|
||||||
KeyboardSensor,
|
KeyboardSensor,
|
||||||
@@ -66,7 +66,7 @@ import { useNodeOfflineTimers } from "@/pages/node/use-node-offline-timers";
|
|||||||
import { useNodeRealtime } from "@/pages/node/use-node-realtime";
|
import { useNodeRealtime } from "@/pages/node/use-node-realtime";
|
||||||
import { useLocalStorageState } from "@/hooks/use-local-storage-state";
|
import { useLocalStorageState } from "@/hooks/use-local-storage-state";
|
||||||
import { loadStoredOrder, saveOrder } from "@/utils/order-storage";
|
import { loadStoredOrder, saveOrder } from "@/utils/order-storage";
|
||||||
import { PlusIcon, DeleteIcon, CheckAllIcon, XCircleIcon, ListCheckIcon, XIcon, ArrowUpIcon, ShareIcon } from "@/components/icons";
|
|
||||||
|
|
||||||
interface Node {
|
interface Node {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -190,7 +190,6 @@ const SortableItem = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function NodePage() {
|
export default function NodePage() {
|
||||||
const navigate = useNavigate();
|
|
||||||
const [nodeList, setNodeList] = useState<Node[]>([]);
|
const [nodeList, setNodeList] = useState<Node[]>([]);
|
||||||
const [nodeOrder, setNodeOrder] = useState<number[]>([]);
|
const [nodeOrder, setNodeOrder] = useState<number[]>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -1222,95 +1221,70 @@ export default function NodePage() {
|
|||||||
{selectMode ? (
|
{selectMode ? (
|
||||||
<>
|
<>
|
||||||
<span className="text-sm text-default-600 shrink-0">
|
<span className="text-sm text-default-600 shrink-0">
|
||||||
已选择 {selectedIds.size} 项
|
已选 {selectedIds.size} 项
|
||||||
</span>
|
</span>
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
|
||||||
color="primary"
|
color="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
title="全选"
|
|
||||||
variant="flat"
|
variant="flat"
|
||||||
onPress={selectAll}
|
onPress={selectAll}
|
||||||
>
|
>
|
||||||
<CheckAllIcon className="w-4 h-4" />
|
全选
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
|
||||||
color="secondary"
|
color="secondary"
|
||||||
size="sm"
|
size="sm"
|
||||||
title="清空"
|
|
||||||
variant="flat"
|
variant="flat"
|
||||||
onPress={deselectAll}
|
onPress={deselectAll}
|
||||||
>
|
>
|
||||||
<XCircleIcon className="w-4 h-4" />
|
清空
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
|
||||||
color="warning"
|
color="warning"
|
||||||
isDisabled={selectedIds.size === 0}
|
isDisabled={selectedIds.size === 0}
|
||||||
isLoading={batchUpgradeLoading}
|
isLoading={batchUpgradeLoading}
|
||||||
size="sm"
|
size="sm"
|
||||||
title="升级"
|
|
||||||
variant="flat"
|
variant="flat"
|
||||||
onPress={() => openUpgradeModal("batch")}
|
onPress={() => openUpgradeModal("batch")}
|
||||||
>
|
>
|
||||||
<ArrowUpIcon className="w-4 h-4" />
|
升级
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
|
||||||
color="danger"
|
color="danger"
|
||||||
isDisabled={selectedIds.size === 0}
|
isDisabled={selectedIds.size === 0}
|
||||||
size="sm"
|
size="sm"
|
||||||
title="删除"
|
|
||||||
variant="flat"
|
variant="flat"
|
||||||
onPress={() => setBatchDeleteModalOpen(true)}
|
onPress={() => setBatchDeleteModalOpen(true)}
|
||||||
>
|
>
|
||||||
<DeleteIcon className="w-4 h-4" />
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
color="secondary"
|
||||||
color="default"
|
|
||||||
size="sm"
|
size="sm"
|
||||||
title="退出"
|
|
||||||
variant="solid"
|
variant="solid"
|
||||||
onPress={toggleSelectMode}
|
onPress={toggleSelectMode}
|
||||||
>
|
>
|
||||||
<XIcon className="w-4 h-4" />
|
退出
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
className="bg-sky-100 text-sky-700 hover:bg-sky-200 dark:bg-sky-900/30 dark:text-sky-300 dark:hover:bg-sky-900/45"
|
||||||
className="bg-violet-100 text-violet-700 hover:bg-violet-200 dark:bg-violet-900/30 dark:text-violet-300 dark:hover:bg-violet-900/45"
|
|
||||||
color="default"
|
color="default"
|
||||||
size="sm"
|
size="sm"
|
||||||
title="选择"
|
|
||||||
variant="flat"
|
variant="flat"
|
||||||
onPress={toggleSelectMode}
|
onPress={toggleSelectMode}
|
||||||
>
|
>
|
||||||
<ListCheckIcon className="w-4 h-4" />
|
批量
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
isIconOnly
|
|
||||||
className="bg-indigo-100 text-indigo-700 hover:bg-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-300 dark:hover:bg-indigo-900/45"
|
|
||||||
color="default"
|
|
||||||
size="sm"
|
|
||||||
title="面板共享"
|
|
||||||
variant="flat"
|
|
||||||
onPress={() => navigate("/panel-sharing")}
|
|
||||||
>
|
|
||||||
<ShareIcon className="w-4 h-4" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
isIconOnly
|
|
||||||
color="primary"
|
color="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
title="新增"
|
|
||||||
variant="flat"
|
variant="flat"
|
||||||
onPress={handleAdd}
|
onPress={handleAdd}
|
||||||
>
|
>
|
||||||
<PlusIcon className="w-4 h-4" />
|
新增
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user