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:
iliya 2026-02-23 12:04:13 +02:00
parent dc2464a128
commit f1df2be208
6 changed files with 21 additions and 7 deletions

View file

@ -282,7 +282,7 @@ function createTask(paths, flags) {
description: String(description || subject),
activeForm: activeForm ? String(activeForm) : undefined,
owner,
createdBy: from || undefined,
createdBy: from,
status,
blocks: [],
blockedBy: [],

View file

@ -29,7 +29,7 @@ export const MemberCard = ({
return (
<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={{
borderLeft: `3px solid ${colors.border}`,
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">
<img
src={agentAvatarUrl(member.name)}

View file

@ -1,4 +1,4 @@
import { getMemberColor } from '@shared/constants/memberColors';
import { getMemberColorByName } from '@shared/constants/memberColors';
import { MemberCard } from './MemberCard';
@ -29,11 +29,11 @@ export const MemberList = ({
return (
<div className="flex flex-col gap-0.5">
{members.map((member, index) => (
{members.map((member) => (
<MemberCard
key={member.name}
member={member}
memberColor={member.color ?? getMemberColor(index)}
memberColor={member.color ?? getMemberColorByName(member.name)}
isTeamAlive={isTeamAlive}
onClick={() => onMemberClick?.(member)}
onSendMessage={() => onSendMessage?.(member)}

View file

@ -41,10 +41,14 @@ export const MemberLogsTab = ({
void (async () => {
try {
if (taskId == null && !memberName) {
if (!cancelled) setLogs([]);
return;
}
const result =
taskId != null
? await api.teams.getLogsForTask(teamName, taskId)
: await api.teams.getMemberLogs(teamName, memberName ?? '');
: await api.teams.getMemberLogs(teamName, memberName!);
if (!cancelled) {
setLogs(result);
}

View file

@ -8,3 +8,12 @@ export const MEMBER_COLOR_PALETTE = ['blue', 'green', 'yellow', 'cyan', 'magenta
export function getMemberColor(index: number): string {
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];
}

View file

@ -160,7 +160,7 @@ describe('TeamDataService', () => {
expect(result.status).toBe('pending');
expect(createTaskMock).toHaveBeenCalledWith(
'my-team',
expect.objectContaining({ status: 'pending', owner: 'alice' })
expect.objectContaining({ status: 'pending', owner: 'alice', createdBy: 'user' })
);
});
});