Browse Source

feat(ui): Add ActorBadge (#69029)

Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
Evan Purkhiser 11 months ago
parent
commit
e5e9e93f24

+ 22 - 0
static/app/components/idBadge/actorBadge.tsx

@@ -0,0 +1,22 @@
+import type {Actor} from 'sentry/types';
+
+import BadgeDisplayName from './badgeDisplayName';
+import {BaseBadge, type BaseBadgeProps} from './baseBadge';
+
+export interface ActorBadgeProps extends BaseBadgeProps {
+  actor: Actor;
+}
+
+function ActorBadge({actor, ...props}: ActorBadgeProps) {
+  const title = actor.type === 'team' ? `#${actor.name}` : actor.name || actor.email;
+
+  return (
+    <BaseBadge
+      displayName={<BadgeDisplayName>{title}</BadgeDisplayName>}
+      actor={actor}
+      {...props}
+    />
+  );
+}
+
+export default ActorBadge;

+ 4 - 1
static/app/components/idBadge/baseBadge.tsx

@@ -3,7 +3,7 @@ import styled from '@emotion/styled';
 
 import Avatar from 'sentry/components/avatar';
 import {space} from 'sentry/styles/space';
-import type {AvatarProject, AvatarUser, Organization, Team} from 'sentry/types';
+import type {Actor, AvatarProject, AvatarUser, Organization, Team} from 'sentry/types';
 
 export interface BaseBadgeProps {
   avatarProps?: Record<string, any>;
@@ -17,6 +17,7 @@ export interface BaseBadgeProps {
 
 interface AllBaseBadgeProps extends BaseBadgeProps {
   displayName: React.ReactNode;
+  actor?: Actor;
   organization?: Organization;
   project?: AvatarProject;
   team?: Team;
@@ -35,6 +36,7 @@ export const BaseBadge = memo(
     user,
     organization,
     project,
+    actor,
     className,
   }: AllBaseBadgeProps) => (
     <Wrapper className={className}>
@@ -46,6 +48,7 @@ export const BaseBadge = memo(
           user={user}
           organization={organization}
           project={project}
+          actor={actor}
         />
       )}
 

+ 11 - 1
static/app/components/idBadge/getBadge.tsx

@@ -1,3 +1,4 @@
+import ActorBadge, {type ActorBadgeProps} from './actorBadge';
 import type {BaseBadgeProps} from './baseBadge';
 import MemberBadge, {type MemberBadgeProps} from './memberBadge';
 import OrganizationBadge, {type OrganizationBadgeProps} from './organizationBadge';
@@ -34,12 +35,18 @@ interface GetProjectBadgeProps
     ProjectBadgeProps,
     AddedBaseBadgeProps {}
 
+interface GetActorBadgeProps
+  extends Omit<BaseBadgeProps, 'displayName' | 'actor'>,
+    ActorBadgeProps,
+    AddedBaseBadgeProps {}
+
 export type GetBadgeProps =
   | GetOrganizationBadgeProps
   | GetTeamBadgeProps
   | GetProjectBadgeProps
   | GetUserBadgeProps
-  | GetMemberBadgeProps;
+  | GetMemberBadgeProps
+  | GetActorBadgeProps;
 
 function getBadge(props): React.ReactElement | null {
   if (props.organization) {
@@ -54,6 +61,9 @@ function getBadge(props): React.ReactElement | null {
   if (props.user) {
     return <UserBadge {...props} />;
   }
+  if (props.actor) {
+    return <ActorBadge {...props} />;
+  }
   if (props.member) {
     return <MemberBadge {...props} />;
   }

+ 28 - 1
static/app/components/idBadge/index.stories.tsx

@@ -1,11 +1,13 @@
 import LoadingIndicator from 'sentry/components/loadingIndicator';
 import storyBook from 'sentry/stories/storyBook';
-import type {Member} from 'sentry/types';
+import type {Actor, Member} from 'sentry/types';
 import useOrganization from 'sentry/utils/useOrganization';
 import useProjects from 'sentry/utils/useProjects';
 import {useTeams} from 'sentry/utils/useTeams';
 import {useUser} from 'sentry/utils/useUser';
 
+import SideBySide from '../stories/sideBySide';
+
 import IdBadge from '.';
 
 export default storyBook(IdBadge, story => {
@@ -81,4 +83,29 @@ export default storyBook(IdBadge, story => {
 
     return <IdBadge member={member} />;
   });
+
+  story('Actor', () => {
+    const user = useUser();
+    const {teams} = useTeams();
+
+    const userActor: Actor = {
+      type: 'user',
+      id: user.id,
+      name: user.name,
+      email: user.email,
+    };
+
+    const teamActor: Actor = {
+      type: 'team',
+      id: teams[0].id,
+      name: teams[0].name,
+    };
+
+    return (
+      <SideBySide>
+        <IdBadge actor={userActor} />
+        <IdBadge actor={teamActor} />
+      </SideBySide>
+    );
+  });
 });