API only users show a different avatar in the activity feed (#30512)

#28501
This commit is contained in:
Dante Catalfamo
2025-07-07 10:45:51 -04:00
committed by GitHub
parent dd26fb9c8b
commit 6847f12a6f
5 changed files with 74 additions and 17 deletions
+1
View File
@@ -0,0 +1 @@
- Added a new avatar for API-only users in the activity feed
+1
View File
@@ -11,6 +11,7 @@ const DEFAULT_ACTIVITY_MOCK: IActivity = {
actor_id: 1,
actor_gravatar: "",
actor_email: "test@example.com",
actor_api_only: false,
fleet_initiated: false,
type: ActivityType.EditedAgentOptions,
};
@@ -143,6 +143,7 @@ const ActivityItem = ({
size="small"
hasWhiteBackground
useFleetAvatar={activity.fleet_initiated}
useApiOnlyAvatar={activity.actor_api_only}
/>
<div className={`${baseClass}__avatar-lower-dash`} />
</div>
+70 -17
View File
@@ -74,6 +74,54 @@ const FleetAvatar = ({ className }: IFleetAvatarProps) => {
);
};
interface IAPIOnlyAvatar {
className?: string;
}
const APIOnlyAvatar = ({ className }: IAPIOnlyAvatar) => {
return (
<svg
data-testid="apionly-avatar"
className={className}
width="32"
height="32"
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle
cx="16"
cy="16"
r="15"
fill="white"
stroke="#6A67FE"
strokeWidth="2"
/>
<path
d="M11.5 12.75L8 16L11.5 19.25"
stroke="#6A67FE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M18 11L14.5 21"
stroke="#6A67FE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M21 19.25L24.5 16L21 12.75"
stroke="#6A67FE"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
interface IAvatarUserInterface {
gravatar_url?: string;
gravatar_url_dark?: string;
@@ -88,6 +136,8 @@ interface IAvatarProps {
* Set this to `true` to use the fleet avatar instead of the users gravatar.
*/
useFleetAvatar?: boolean;
// Set this to true to show the API Only avatar
useApiOnlyAvatar?: boolean;
}
const baseClass = "avatar";
@@ -97,6 +147,7 @@ const Avatar = ({
size,
user,
hasWhiteBackground,
useApiOnlyAvatar = false,
useFleetAvatar = false,
}: IAvatarProps) => {
const [isLoading, setIsLoading] = useState(true);
@@ -115,23 +166,25 @@ const Avatar = ({
});
const { gravatar_url } = user;
return (
<div className="avatar-wrapper">
{useFleetAvatar ? (
<FleetAvatar className={avatarClasses} />
) : (
<img
alt="User avatar"
className={`${avatarClasses} ${
isLoading || isError ? "default" : ""
}`}
src={gravatar_url || DEFAULT_GRAVATAR_LINK}
onError={onError}
onLoad={onLoad}
/>
)}
</div>
);
let avatar;
if (useFleetAvatar) {
avatar = <FleetAvatar className={avatarClasses} />;
} else if (useApiOnlyAvatar && !gravatar_url) {
avatar = <APIOnlyAvatar className={avatarClasses} />;
} else {
avatar = (
<img
alt="User avatar"
className={`${avatarClasses} ${isLoading || isError ? "default" : ""}`}
src={gravatar_url || DEFAULT_GRAVATAR_LINK}
onError={onError}
onLoad={onLoad}
/>
);
}
return <div className="avatar-wrapper">{avatar}</div>;
};
export default Avatar;
+1
View File
@@ -152,6 +152,7 @@ export interface IActivity {
actor_id: number;
actor_gravatar: string;
actor_email?: string;
actor_api_only: boolean;
type: ActivityType;
fleet_initiated: boolean;
details?: IActivityDetails;