fix: address CodeRabbit review feedback
- MemberCard: add hover overlay to fix inline backgroundColor killing Tailwind hover effect (UX regression for role="button" element) - MemberLogsTab: guard against missing taskId and memberName to prevent unnecessary IPC call with empty string - MemberList: use hash-based getMemberColorByName() for stable fallback colors independent of array position - TeamAgentToolsInstaller: remove redundant `from || undefined` - TeamDataService test: assert createdBy: 'user' field
This commit is contained in:
parent
dc2464a128
commit
f1df2be208
6 changed files with 21 additions and 7 deletions
|
|
@ -282,7 +282,7 @@ function createTask(paths, flags) {
|
||||||
description: String(description || subject),
|
description: String(description || subject),
|
||||||
activeForm: activeForm ? String(activeForm) : undefined,
|
activeForm: activeForm ? String(activeForm) : undefined,
|
||||||
owner,
|
owner,
|
||||||
createdBy: from || undefined,
|
createdBy: from,
|
||||||
status,
|
status,
|
||||||
blocks: [],
|
blocks: [],
|
||||||
blockedBy: [],
|
blockedBy: [],
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ export const MemberCard = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="group flex cursor-pointer items-center gap-2.5 rounded px-2 py-1.5 hover:bg-[var(--color-surface-raised)]"
|
className="group relative flex cursor-pointer items-center gap-2.5 rounded px-2 py-1.5"
|
||||||
style={{
|
style={{
|
||||||
borderLeft: `3px solid ${colors.border}`,
|
borderLeft: `3px solid ${colors.border}`,
|
||||||
backgroundColor: colors.badge,
|
backgroundColor: colors.badge,
|
||||||
|
|
@ -45,6 +45,7 @@ export const MemberCard = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<div className="pointer-events-none absolute inset-0 rounded transition-colors group-hover:bg-white/5" />
|
||||||
<div className="relative shrink-0">
|
<div className="relative shrink-0">
|
||||||
<img
|
<img
|
||||||
src={agentAvatarUrl(member.name)}
|
src={agentAvatarUrl(member.name)}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { getMemberColor } from '@shared/constants/memberColors';
|
import { getMemberColorByName } from '@shared/constants/memberColors';
|
||||||
|
|
||||||
import { MemberCard } from './MemberCard';
|
import { MemberCard } from './MemberCard';
|
||||||
|
|
||||||
|
|
@ -29,11 +29,11 @@ export const MemberList = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-0.5">
|
<div className="flex flex-col gap-0.5">
|
||||||
{members.map((member, index) => (
|
{members.map((member) => (
|
||||||
<MemberCard
|
<MemberCard
|
||||||
key={member.name}
|
key={member.name}
|
||||||
member={member}
|
member={member}
|
||||||
memberColor={member.color ?? getMemberColor(index)}
|
memberColor={member.color ?? getMemberColorByName(member.name)}
|
||||||
isTeamAlive={isTeamAlive}
|
isTeamAlive={isTeamAlive}
|
||||||
onClick={() => onMemberClick?.(member)}
|
onClick={() => onMemberClick?.(member)}
|
||||||
onSendMessage={() => onSendMessage?.(member)}
|
onSendMessage={() => onSendMessage?.(member)}
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,14 @@ export const MemberLogsTab = ({
|
||||||
|
|
||||||
void (async () => {
|
void (async () => {
|
||||||
try {
|
try {
|
||||||
|
if (taskId == null && !memberName) {
|
||||||
|
if (!cancelled) setLogs([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const result =
|
const result =
|
||||||
taskId != null
|
taskId != null
|
||||||
? await api.teams.getLogsForTask(teamName, taskId)
|
? await api.teams.getLogsForTask(teamName, taskId)
|
||||||
: await api.teams.getMemberLogs(teamName, memberName ?? '');
|
: await api.teams.getMemberLogs(teamName, memberName!);
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setLogs(result);
|
setLogs(result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,12 @@ export const MEMBER_COLOR_PALETTE = ['blue', 'green', 'yellow', 'cyan', 'magenta
|
||||||
export function getMemberColor(index: number): string {
|
export function getMemberColor(index: number): string {
|
||||||
return MEMBER_COLOR_PALETTE[index % MEMBER_COLOR_PALETTE.length];
|
return MEMBER_COLOR_PALETTE[index % MEMBER_COLOR_PALETTE.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Derive a stable fallback color from a member name (position-independent). */
|
||||||
|
export function getMemberColorByName(name: string): string {
|
||||||
|
let hash = 0;
|
||||||
|
for (let i = 0; i < name.length; i++) {
|
||||||
|
hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
|
||||||
|
}
|
||||||
|
return MEMBER_COLOR_PALETTE[Math.abs(hash) % MEMBER_COLOR_PALETTE.length];
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ describe('TeamDataService', () => {
|
||||||
expect(result.status).toBe('pending');
|
expect(result.status).toBe('pending');
|
||||||
expect(createTaskMock).toHaveBeenCalledWith(
|
expect(createTaskMock).toHaveBeenCalledWith(
|
||||||
'my-team',
|
'my-team',
|
||||||
expect.objectContaining({ status: 'pending', owner: 'alice' })
|
expect.objectContaining({ status: 'pending', owner: 'alice', createdBy: 'user' })
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue