feat(分组): 成员改为方块网格,只显示中文名、全部铺开不滚动
反馈是「不要一行一个,只留中文名,做成方块,全展示不滚动」。 · 标签云 → 方块网格(grid + auto-fill,minmax(92px,1fr)): 窗口越宽一行放得越多,每个成员一格,整齐且密度高 · 去掉账号,格子里只留中文名(账号移到 title 提示里,需要时悬停可看) · 不设 max-height、不加 overflow —— 自然换行铺满,没有滚动条 · 组长:金色底 + 皇冠图标;移除按钮改成悬停才出现(避免误点) · 无权限时方块不可点、也不出现移除按钮,纯展示 已通过 tsc 检查。
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect, useCallback, useMemo } from "react";
|
||||
import { Table, Button, Modal, Input, Checkbox, Tag, App, Spin, Empty, Select, Tooltip } from "antd";
|
||||
import { Table, Button, Modal, Input, Checkbox, Tag, App, Spin, Empty, Select } from "antd";
|
||||
import { Plus, Pencil, Trash2, UserPlus, Crown, ShieldCheck } from "lucide-react";
|
||||
import { useAuth } from "../../contexts/AuthContext";
|
||||
import { isSuperAdmin } from "../../constants/task";
|
||||
@ -385,36 +385,47 @@ export default function AdminGroupsPage() {
|
||||
) : detail.members.length === 0 ? (
|
||||
<Empty description="该分组还没有成员" image={Empty.PRESENTED_IMAGE_SIMPLE} className="py-6" />
|
||||
) : (
|
||||
/* 标签云而非表格:成员多时一人一行要滚很久,标签能一行放好几个。
|
||||
有权限时:点标签正文切换组长、点 × 移除;无权限时纯展示。 */
|
||||
<div className="flex flex-wrap gap-2 rounded-lg border border-gray-100 bg-gray-50/60 p-3">
|
||||
/* 方块网格:每个成员一格,只显示中文名,全部铺开不做滚动。
|
||||
自动按容器宽度铺排(auto-fill),窗口越宽一行放得越多。
|
||||
有权限时:点方块切换组长、悬停右上角出现移除;无权限时纯展示。 */
|
||||
<div className="grid gap-2 [grid-template-columns:repeat(auto-fill,minmax(92px,1fr))]">
|
||||
{detail.members.map((m) => (
|
||||
<Tag
|
||||
<div
|
||||
key={m.user_id}
|
||||
color={m.is_leader ? "gold" : undefined}
|
||||
closable={detail.can_manage_members}
|
||||
onClose={(e) => { e.preventDefault(); handleRemoveMember(m.user_id); }}
|
||||
className="!m-0 !px-2.5 !py-1 !text-sm"
|
||||
title={
|
||||
detail.can_manage_members
|
||||
? `${m.display_name}(${m.user_id})· ${m.is_leader ? "点击取消组长" : "点击设为组长"}`
|
||||
: `${m.display_name}(${m.user_id})`
|
||||
}
|
||||
onClick={() => {
|
||||
if (detail.can_manage_members) handleToggleLeader(m.user_id, !m.is_leader);
|
||||
}}
|
||||
className={`group relative flex h-11 select-none items-center justify-center rounded-lg border px-2 text-sm transition-colors ${
|
||||
m.is_leader
|
||||
? "border-amber-300 bg-amber-50 font-medium text-amber-800"
|
||||
: "border-gray-200 bg-white text-gray-700"
|
||||
} ${
|
||||
detail.can_manage_members
|
||||
? "cursor-pointer hover:border-blue-300 hover:bg-blue-50"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<Tooltip
|
||||
title={
|
||||
detail.can_manage_members
|
||||
? (m.is_leader ? "点击取消组长" : "点击设为组长")
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<span
|
||||
className={`select-none ${detail.can_manage_members ? "cursor-pointer" : ""}`}
|
||||
onClick={() => {
|
||||
if (detail.can_manage_members) handleToggleLeader(m.user_id, !m.is_leader);
|
||||
}}
|
||||
{m.is_leader && (
|
||||
<Crown size={12} className="mr-1 shrink-0 text-amber-500" />
|
||||
)}
|
||||
<span className="truncate">{m.display_name}</span>
|
||||
|
||||
{/* 移除:默认藏起来,悬停该方块才出现,避免误点 */}
|
||||
{detail.can_manage_members && (
|
||||
<button
|
||||
title="移出分组"
|
||||
onClick={(e) => { e.stopPropagation(); handleRemoveMember(m.user_id); }}
|
||||
className="absolute -right-1.5 -top-1.5 hidden h-4 w-4 items-center justify-center rounded-full bg-red-500 text-[10px] leading-none text-white hover:bg-red-600 group-hover:flex"
|
||||
>
|
||||
{m.is_leader && <Crown size={12} className="mr-1 inline align-[-1px]" />}
|
||||
{m.display_name}
|
||||
<span className="ml-1.5 font-mono text-xs opacity-50">{m.user_id}</span>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Tag>
|
||||
×
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user