fix(frontend): stabilize multiselect behavior and UI spacing (#154)

* fix(frontend): left-align announcement logo in homepage banner

* fix(frontend): keep multiselect panels floating and preserve summaries

* fix(frontend): rebalance config card header spacing

* fix(frontend): normalize formatting and fix multiselect modal behavior

* fix(frontend): restore config divider spacing on desktop
This commit is contained in:
sagit
2026-02-19 20:50:12 +08:00
committed by GitHub
parent 18c2da7c7e
commit 66de566a00
52 changed files with 743 additions and 301 deletions
+34 -14
View File
@@ -1,4 +1,6 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import toast from "react-hot-toast";
import { Card, CardBody, CardHeader } from "@/shadcn-bridge/heroui/card";
import { Button } from "@/shadcn-bridge/heroui/button";
import { Input } from "@/shadcn-bridge/heroui/input";
@@ -21,8 +23,6 @@ import {
} from "@/shadcn-bridge/heroui/table";
import { Chip } from "@/shadcn-bridge/heroui/chip";
import { Spinner } from "@/shadcn-bridge/heroui/spinner";
import toast from "react-hot-toast";
import {
assignGroupPermission,
assignTunnelsToGroup,
@@ -173,6 +173,22 @@ export default function GroupPage() {
return map;
}, [users]);
const selectedTunnelSummary = useMemo(() => {
const value = Array.from(selectedTunnelKeys)
.map((id) => tunnelNameMap.get(Number(id)) || id)
.join("、");
return value || "无";
}, [selectedTunnelKeys, tunnelNameMap]);
const selectedUserSummary = useMemo(() => {
const value = Array.from(selectedUserKeys)
.map((id) => userNameMap.get(Number(id)) || id)
.join("、");
return value || "无";
}, [selectedUserKeys, userNameMap]);
const loadData = useCallback(async () => {
setLoading(true);
try {
@@ -765,8 +781,10 @@ export default function GroupPage() {
>
<ModalContent>
<ModalHeader>分配隧道 - {assignTunnelGroup?.name}</ModalHeader>
<ModalBody>
<ModalBody className="min-w-0">
<Select
className="min-w-0"
classNames={{ trigger: "max-w-full" }}
items={tunnels}
label="选择隧道"
selectedKeys={selectedTunnelKeys}
@@ -779,11 +797,11 @@ export default function GroupPage() {
>
{(item) => <SelectItem key={item.id}>{item.name}</SelectItem>}
</Select>
<p className="text-xs text-default-500 break-all whitespace-normal">
当前已选:
{Array.from(selectedTunnelKeys)
.map((id) => tunnelNameMap.get(Number(id)) || id)
.join("、") || "无"}
<p
className="w-full min-w-0 max-w-full text-xs text-default-500 truncate"
title={`当前已选:${selectedTunnelSummary}`}
>
当前已选:{selectedTunnelSummary}
</p>
<p className="text-xs text-default-500">
不选择任何隧道并保存将清空该分组成员。
@@ -810,8 +828,10 @@ export default function GroupPage() {
>
<ModalContent>
<ModalHeader>分配用户 - {assignUserGroup?.name}</ModalHeader>
<ModalBody>
<ModalBody className="min-w-0">
<Select
className="min-w-0"
classNames={{ trigger: "max-w-full" }}
items={users}
label="选择用户"
selectedKeys={selectedUserKeys}
@@ -824,11 +844,11 @@ export default function GroupPage() {
>
{(item) => <SelectItem key={item.id}>{item.user}</SelectItem>}
</Select>
<p className="text-xs text-default-500 break-all whitespace-normal">
当前已选:
{Array.from(selectedUserKeys)
.map((id) => userNameMap.get(Number(id)) || id)
.join("、") || "无"}
<p
className="w-full min-w-0 max-w-full text-xs text-default-500 truncate"
title={`当前已选:${selectedUserSummary}`}
>
当前已选:{selectedUserSummary}
</p>
<p className="text-xs text-default-500">
不选择任何用户并保存将清空该分组成员。