fix(账号): 固化超级管理员身份
This commit is contained in:
@@ -6,6 +6,7 @@ import { useBugStore } from '@/stores/useBugStore';
|
||||
import { useTestCaseStore } from '@/stores/useTestCaseStore';
|
||||
import { useRequirementStore } from '@/stores/useRequirementStore';
|
||||
import { useAuthStore } from '@/stores/useAuthStore';
|
||||
import { useMemberStore } from '@/stores/useMemberStore';
|
||||
import { BugRow } from './BugRow';
|
||||
import { BugDetailDrawer } from './BugDetailDrawer';
|
||||
import { Pagination, usePagination } from '@/components/Pagination';
|
||||
@@ -13,6 +14,7 @@ import { SearchInput, matchTitleOrNo } from '@/components/SearchInput';
|
||||
import { useDebouncedValue } from '@/hooks/useDebouncedValue';
|
||||
import { BUG_STATUS_LABEL, BUG_SEVERITY_LABEL, bugIntervals } from '@/lib/bug';
|
||||
import { formatWorkHours, calcTwoMetrics } from '@/lib/work-hours';
|
||||
import { isMemberReference, resolveMemberDisplayName } from '@/lib/member-system';
|
||||
import type { BugStatus, BugSeverity } from '@/lib/bug';
|
||||
|
||||
interface Props {
|
||||
@@ -25,6 +27,7 @@ export function BugTab({ versionId, requirementIds }: Props) {
|
||||
const { testCases, fetchTestCases } = useTestCaseStore();
|
||||
const { requirements } = useRequirementStore();
|
||||
const user = useAuthStore((s) => s.user);
|
||||
const members = useMemberStore((s) => s.members);
|
||||
|
||||
useEffect(() => { fetchBugs(); }, [fetchBugs]);
|
||||
useEffect(() => { fetchTestCases(); }, [fetchTestCases]);
|
||||
@@ -48,26 +51,36 @@ export function BugTab({ versionId, requirementIds }: Props) {
|
||||
const [keyword, setKeyword] = useState('');
|
||||
const debouncedKeyword = useDebouncedValue(keyword, 300);
|
||||
|
||||
const [selectedBugId, setSelectedBugId] = useState<string | null>(null);
|
||||
|
||||
const testCaseMap = useMemo(() => new Map(testCases.map((c) => [c.id, c])), [testCases]);
|
||||
const currentMember = useMemo(() => members.find((m) => m.id === user?.id), [members, user?.id]);
|
||||
const currentUserName = currentMember?.name ?? user?.name;
|
||||
|
||||
const assignees = useMemo(() => {
|
||||
const names = new Set(versionBugs.map((b) => resolveMemberDisplayName(b.assigneeId, members)));
|
||||
return Array.from(names);
|
||||
}, [versionBugs, members]);
|
||||
|
||||
const filteredBugs = useMemo(() => {
|
||||
let result = versionBugs;
|
||||
if (filterAssignee) result = result.filter((b) => b.assigneeId === filterAssignee);
|
||||
if (filterAssignee === '__me') {
|
||||
if (currentMember) {
|
||||
result = result.filter((b) => isMemberReference(b.assigneeId, currentMember));
|
||||
} else {
|
||||
result = [];
|
||||
}
|
||||
} else if (filterAssignee) {
|
||||
result = result.filter((b) => resolveMemberDisplayName(b.assigneeId, members) === filterAssignee);
|
||||
}
|
||||
if (filterStatus) result = result.filter((b) => b.status === filterStatus);
|
||||
if (filterSeverity) result = result.filter((b) => b.severity === filterSeverity);
|
||||
if (debouncedKeyword) result = result.filter((b) => matchTitleOrNo({ title: b.title, no: b.bugNo }, debouncedKeyword));
|
||||
return result;
|
||||
}, [versionBugs, filterAssignee, filterStatus, filterSeverity, debouncedKeyword]);
|
||||
}, [versionBugs, filterAssignee, filterStatus, filterSeverity, debouncedKeyword, currentMember, members]);
|
||||
|
||||
const { paged, page, setPage, total, pageSize, setPageSize } = usePagination(filteredBugs, 20);
|
||||
|
||||
const [selectedBugId, setSelectedBugId] = useState<string | null>(null);
|
||||
|
||||
const testCaseMap = useMemo(() => new Map(testCases.map((c) => [c.id, c])), [testCases]);
|
||||
|
||||
const assignees = useMemo(() => {
|
||||
const names = new Set(versionBugs.map((b) => b.assigneeId));
|
||||
return Array.from(names);
|
||||
}, [versionBugs]);
|
||||
|
||||
const hasFilter = !!(filterAssignee || filterStatus || filterSeverity || debouncedKeyword);
|
||||
|
||||
return (
|
||||
@@ -94,8 +107,8 @@ export function BugTab({ versionId, requirementIds }: Props) {
|
||||
<SearchInput value={keyword} onChange={(v) => { setKeyword(v); setPage(1); }} placeholder="搜索标题/编号" />
|
||||
<select value={filterAssignee} onChange={(e) => { setFilterAssignee(e.target.value); setPage(1); }} className="h-7 rounded-md border border-[var(--line)] bg-[var(--bg-card)] px-2 text-[11px] text-[var(--ink-soft)] focus:border-[var(--accent)] focus:outline-none">
|
||||
<option value="">全部修复人</option>
|
||||
{user?.name && <option value={user.name}>我的Bug</option>}
|
||||
{assignees.filter((a) => a !== user?.name).map((a) => <option key={a} value={a}>{a}</option>)}
|
||||
{currentMember && <option value="__me">我的Bug</option>}
|
||||
{assignees.filter((a) => a !== currentUserName).map((a) => <option key={a} value={a}>{a}</option>)}
|
||||
</select>
|
||||
<select value={filterStatus} onChange={(e) => { setFilterStatus(e.target.value); setPage(1); }} className="h-7 rounded-md border border-[var(--line)] bg-[var(--bg-card)] px-2 text-[11px] text-[var(--ink-soft)] focus:border-[var(--accent)] focus:outline-none">
|
||||
<option value="">全部状态</option>
|
||||
|
||||
Reference in New Issue
Block a user