- Added API endpoints for adding and removing custom project paths, allowing persistence across app restarts. - Implemented IPC handlers for managing custom project paths in the application. - Introduced functionality for adding and removing task relationships (blockedBy, blocks, related) between tasks, enhancing task management capabilities. - Updated relevant components and services to support the new task relationship features and ensure proper integration with the existing task management system. - Enhanced notifications for task relationships to improve user awareness of task dependencies.
77 lines
1.9 KiB
TypeScript
77 lines
1.9 KiB
TypeScript
import { getTeamColorSet } from '@renderer/constants/teamColors';
|
|
import { agentAvatarUrl } from '@renderer/utils/memberHelpers';
|
|
|
|
interface MemberBadgeProps {
|
|
name: string;
|
|
color?: string;
|
|
/** Avatar + badge size variant */
|
|
size?: 'sm' | 'md';
|
|
/** Hide the avatar icon, show only the name badge */
|
|
hideAvatar?: boolean;
|
|
onClick?: (name: string) => void;
|
|
}
|
|
|
|
/**
|
|
* Reusable member avatar + colored name badge.
|
|
* Avatar is rendered OUTSIDE the badge, to the left.
|
|
* When onClick is provided, both avatar and badge are clickable as one unit.
|
|
*/
|
|
export const MemberBadge = ({
|
|
name,
|
|
color,
|
|
size = 'sm',
|
|
hideAvatar,
|
|
onClick,
|
|
}: MemberBadgeProps): React.JSX.Element => {
|
|
const colors = getTeamColorSet(color ?? '');
|
|
const avatarSize = size === 'md' ? 32 : 24;
|
|
const avatarClass = size === 'md' ? 'size-6' : 'size-5';
|
|
const textClass = size === 'md' ? 'text-xs' : 'text-[10px]';
|
|
|
|
const badgeStyle = {
|
|
backgroundColor: colors.badge,
|
|
color: colors.text,
|
|
border: `1px solid ${colors.border}40`,
|
|
};
|
|
|
|
const avatar = (
|
|
<img
|
|
src={agentAvatarUrl(name, avatarSize)}
|
|
alt=""
|
|
className={`${avatarClass} shrink-0 rounded-full bg-[var(--color-surface-raised)]`}
|
|
loading="lazy"
|
|
/>
|
|
);
|
|
|
|
const badge = (
|
|
<span
|
|
className={`rounded px-1.5 py-0.5 ${textClass} font-medium tracking-wide`}
|
|
style={badgeStyle}
|
|
>
|
|
{name === 'team-lead' ? 'lead' : name}
|
|
</span>
|
|
);
|
|
|
|
if (onClick) {
|
|
return (
|
|
<button
|
|
type="button"
|
|
className="inline-flex items-center gap-1 rounded transition-opacity hover:opacity-90 focus:outline-none focus:ring-1 focus:ring-[var(--color-border)]"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onClick(name);
|
|
}}
|
|
>
|
|
{!hideAvatar && avatar}
|
|
{badge}
|
|
</button>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<span className="inline-flex items-center gap-1">
|
|
{!hideAvatar && avatar}
|
|
{badge}
|
|
</span>
|
|
);
|
|
};
|