Skip to content

Commit

Permalink
feat: Added last_name field (#19463)
Browse files Browse the repository at this point in the history
  • Loading branch information
benjackwhite authored Dec 21, 2023
1 parent 8f33ae0 commit ce48493
Show file tree
Hide file tree
Showing 44 changed files with 107 additions and 72 deletions.
1 change: 1 addition & 0 deletions ee/api/test/__snapshots__/test_time_to_see_data.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"user": {
"distinct_id": "",
"first_name": "",
"last_name": "",
"email": "",
"is_email_verified": false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function MinimalNavigation(): JSX.Element {
<LemonButton
type="tertiary"
status="muted"
icon={<ProfilePicture name={user?.first_name} email={user?.email} size="md" />}
icon={<ProfilePicture user={user} size="md" />}
onClick={toggleSitePopover}
>
{user?.first_name || user?.email}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/layout/navigation-3000/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export function Navbar(): JSX.Element {
className="min-w-70"
>
<NavbarButton
icon={<ProfilePicture name={user?.first_name} email={user?.email} size="md" />}
icon={<ProfilePicture user={user} size="md" />}
identifier="me"
title={`Hi${user?.first_name ? `, ${user?.first_name}` : ''}!`}
shortTitle={user?.first_name || user?.email}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export const breadcrumbsLogic = kea<breadcrumbsLogicType>([
breadcrumbs.push({
key: 'me',
name: user.first_name,
symbol: <ProfilePicture name={user.first_name} email={user.email} size="md" />,
symbol: <ProfilePicture user={user} size="md" />,
})
}
// Instance
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/layout/navigation/TopBar/SitePopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function AccountInfo(): JSX.Element {
tooltipPlacement="left"
sideIcon={<IconSettings className="text-2xl" />}
>
<ProfilePicture name={user?.first_name} email={user?.email} size="xl" />
<ProfilePicture user={user} size="xl" />
<div className="AccountInfo__identification SitePopover__main-info font-sans font-normal">
<div className="font-semibold mb-1">{user?.first_name}</div>
<div className="supplement" title={user?.email}>
Expand Down Expand Up @@ -320,7 +320,7 @@ export function SitePopover(): JSX.Element {
>
<div className="SitePopover__crumb" onClick={toggleSitePopover} data-attr="top-menu-toggle">
<div className="SitePopover__profile-picture" title="Potential system issue">
<ProfilePicture name={user?.first_name} email={user?.email} size="md" />
<ProfilePicture user={user} size="md" />
{!systemStatusHealthy && <IconExclamation className="SitePopover__danger" />}
</div>
<IconChevronDown />
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/lib/components/ActivityLog/ActivityLog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ export const ActivityLogRow = ({
<div className={clsx('ActivityLogRow', logItem.unread && 'ActivityLogRow--unread')}>
<ProfilePicture
showName={false}
name={logItem.isSystem ? logItem.name : undefined}
user={{
first_name: logItem.isSystem ? logItem.name : undefined,
email: logItem.email ?? undefined,
}}
type={logItem.isSystem ? 'system' : 'person'}
email={logItem.email ?? undefined}
size={'xl'}
/>
<div className="ActivityLogRow__details">
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/lib/components/ActivityLog/humanizeActivity.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { dayjs } from 'lib/dayjs'
import { fullName } from 'lib/utils'

import { InsightShortId, PersonType } from '~/types'

Expand Down Expand Up @@ -110,7 +111,7 @@ export function humanize(
if (description !== null) {
logLines.push({
email: logItem.user?.email,
name: logItem.user?.first_name,
name: logItem.user ? fullName(logItem.user) : undefined,
isSystem: logItem.is_system,
description,
extendedDescription,
Expand All @@ -126,5 +127,5 @@ export function userNameForLogItem(logItem: ActivityLogItem): string {
if (logItem.is_system) {
return 'PostHog'
}
return logItem.user?.first_name ?? 'A user'
return logItem.user ? fullName(logItem.user) : 'A user'
}
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,9 @@ function AnnotationCard({ annotation }: { annotation: AnnotationType }): JSX.Ele
<div className="mt-1">{annotation.content}</div>
<div className="leading-6 mt-2">
<ProfilePicture
name={annotation.creation_type === 'GIT' ? 'GitHub automation' : annotation.created_by?.first_name}
email={annotation.creation_type === 'GIT' ? undefined : annotation.created_by?.email}
user={
annotation.creation_type === 'GIT' ? { first_name: 'GitHub automation' } : annotation.created_by
}
showName
size="md"
type={annotation.creation_type === 'GIT' ? 'bot' : 'person'}
Expand Down
10 changes: 2 additions & 8 deletions frontend/src/lib/components/Cards/InsightCard/InsightDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -333,19 +333,13 @@ function InsightDetailsInternal({ insight }: { insight: InsightModel }, ref: Rea
<div>
<h5>Created by</h5>
<section>
<ProfilePicture name={created_by?.first_name} email={created_by?.email} showName size="md" />{' '}
<TZLabel time={created_at} />
<ProfilePicture user={created_by} showName size="md" /> <TZLabel time={created_at} />
</section>
</div>
<div>
<h5>Last modified by</h5>
<section>
<ProfilePicture
name={insight.last_modified_by?.first_name}
email={insight.last_modified_by?.email}
showName
size="md"
/>{' '}
<ProfilePicture user={insight.last_modified_by} showName size="md" />{' '}
<TZLabel time={insight.last_modified_at} />
</section>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,9 +689,7 @@ export const commandPaletteLogic = kea<commandPaletteLogicType>([
},
},
{
icon: () => (
<ProfilePicture name={values.user?.first_name} email={values.user?.email} size="xs" />
),
icon: () => <ProfilePicture user={values.user} size="xs" />,
display: 'Go to User settings',
synonyms: ['account', 'profile'],
executor: () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ function Owner({ user }: { user?: UserBasicType | null }): JSX.Element {
<>
{user?.uuid ? (
<div className="flex items-center flex-row">
<ProfilePicture name={user.first_name} email={user.email} size="sm" />
<ProfilePicture user={user} size="sm" />
<span className="pl-2 inline-flex font-semibold pl-1 whitespace-nowrap">{user.first_name}</span>
</div>
) : (
Expand Down
13 changes: 4 additions & 9 deletions frontend/src/lib/components/MemberSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { LemonButton, LemonButtonProps, LemonDropdown, LemonInput, ProfilePicture } from '@posthog/lemon-ui'
import { useValues } from 'kea'
import { fullName } from 'lib/utils'
import { useMemo, useState } from 'react'
import { membersLogic } from 'scenes/organization/membersLogic'

Expand Down Expand Up @@ -79,17 +80,11 @@ export function MemberSelect({
fullWidth
role="menuitem"
size="small"
icon={
<ProfilePicture
size="md"
name={member.user.first_name}
email={member.user.email}
/>
}
icon={<ProfilePicture size="md" user={member.user} />}
onClick={() => _onChange(member.user)}
>
<span className="flex items-center justify-between gap-2 flex-1">
<span>{member.user.first_name}</span>
<span>{fullName(member.user)}</span>
<span className="text-muted-alt">
{meFirstMembers[0] === member && `(you)`}
</span>
Expand All @@ -112,7 +107,7 @@ export function MemberSelect({
selectedMember
) : selectedMember ? (
<span>
{selectedMember.first_name}
{fullName(selectedMember)}
{meFirstMembers[0].user.uuid === selectedMember.uuid ? ` (you)` : ''}
</span>
) : (
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/lib/components/Table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ export function createdByColumn<T extends Record<string, any> = Record<string, a
render: function Render(_: any, item: any) {
return (
<div className="flex items-center flex-nowrap">
{item.created_by && (
<ProfilePicture name={item.created_by.first_name} email={item.created_by.email} size="md" />
)}
{item.created_by && <ProfilePicture user={item.created_by} size="md" />}
{/* eslint-disable-next-line react/forbid-dom-props */}
<div style={{ maxWidth: 250, width: 'auto', verticalAlign: 'middle', marginLeft: 8 }}>
{item.created_by ? item.created_by.first_name || item.created_by.email : '-'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function UserActivityIndicator({
{at && <TZLabel time={at} />}
{by && <span> by</span>}
</div>
{by && <ProfilePicture name={by.first_name} email={by.email} showName size="md" />}
{by && <ProfilePicture user={by} showName size="md" />}
</div>
) : null
}
2 changes: 1 addition & 1 deletion frontend/src/lib/components/UserSelectItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface UserSelectItemProps {
export function UserSelectItem({ user }: UserSelectItemProps): JSX.Element {
return (
<span className="flex gap-2 items-center">
<ProfilePicture name={user.first_name} email={user.email} size="sm" />
<ProfilePicture user={user} size="sm" />
<span>
{user.first_name} <b>{`<${user.email}>`}</b>
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ const meta: Meta<typeof LemonSelectMultiple> = {
[`user-${i}`]: {
labelComponent: (
<span className="flex gap-2 items-center">
<ProfilePicture name={x} email={`${x}@posthog.com`} size="sm" />
<ProfilePicture
user={{
first_name: x,
email: `${x}@posthog.com`,
}}
size="sm"
/>
<span>
{capitalizeFirstLetter(x)} <b>{`<${x}@posthog.com>`}</b>
</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const ComplexContent: Story = BasicTemplate.bind({})
ComplexContent.args = {
children: (
<span className="flex gap-2 items-center">
<ProfilePicture email="ben@posthog.com" size="sm" />
<ProfilePicture name="ben" size="sm" />
<span>
Look at me I'm <b>bold!</b>
</span>
Expand Down
4 changes: 1 addition & 3 deletions frontend/src/lib/lemon-ui/LemonTable/columnUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ export function createdByColumn<T extends { created_by?: UserBasicType | null }>
const { created_by } = item
return (
<div className={'flex flex-row items-center flex-nowrap'}>
{created_by && (
<ProfilePicture name={created_by.first_name} email={created_by.email} size="md" showName />
)}
{created_by && <ProfilePicture user={created_by} size="md" showName />}
</div>
)
},
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/lib/lemon-ui/ProfilePicture/ProfileBubbles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ export function ProfileBubbles({ people, tooltip, limit = 6, ...divProps }: Prof
{shownPeople.map(({ email, name, title }, index) => (
<ProfilePicture
key={email}
name={name}
email={email}
user={{
email,
first_name: name,
}}
title={title || name || email}
size="md"
index={index}
Expand Down
21 changes: 16 additions & 5 deletions frontend/src/lib/lemon-ui/ProfilePicture/ProfilePicture.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ import './ProfilePicture.scss'

import clsx from 'clsx'
import { useValues } from 'kea'
import { inStorybookTestRunner } from 'lib/utils'
import { fullName, inStorybookTestRunner } from 'lib/utils'
import md5 from 'md5'
import { useMemo, useState } from 'react'
import { userLogic } from 'scenes/userLogic'

import { UserBasicType } from '~/types'

import { IconRobot } from '../icons'
import { Lettermark, LettermarkColor } from '../Lettermark/Lettermark'

export interface ProfilePictureProps {
user?: Pick<Partial<UserBasicType>, 'first_name' | 'email' | 'last_name'> | null
name?: string
email?: string
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'
showName?: boolean
className?: string
Expand All @@ -22,18 +24,25 @@ export interface ProfilePictureProps {
}

export function ProfilePicture({
user,
name,
email,
size = 'lg',
showName,
className,
index,
title,
type = 'person',
}: ProfilePictureProps): JSX.Element {
const { user } = useValues(userLogic)
const { user: currentUser } = useValues(userLogic)
const [gravatarLoaded, setGravatarLoaded] = useState<boolean | undefined>()

let email = user?.email

if (user) {
name = fullName(user)
email = user.email
}

const combinedNameAndEmail = name && email ? `${name} <${email}>` : name || email

const gravatarUrl = useMemo(() => {
Expand Down Expand Up @@ -82,7 +91,9 @@ export function ProfilePicture({
) : (
<div className="profile-package" title={combinedNameAndEmail}>
{pictureComponent}
<span className="profile-name">{user?.email === email ? 'you' : name || email || 'an unknown user'}</span>
<span className="profile-name">
{currentUser?.email === email ? 'you' : name || email || 'an unknown user'}
</span>
</div>
)
}
4 changes: 4 additions & 0 deletions frontend/src/lib/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ export function capitalizeFirstLetter(string: string): string {
return string.charAt(0).toUpperCase() + string.slice(1)
}

export function fullName(props: { first_name?: string; last_name?: string }): string {
return `${props.first_name || ''} ${props.last_name || ''}`.trim()
}

export const genericOperatorMap: Record<string, string> = {
exact: '= equals',
is_not: "≠ doesn't equal",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function sessionNodeFacts(node: TimeToSeeNode): Record<string, JSX.Elemen
? {
type: 'session',
session_id: node.data.session_id,
user: <ProfilePicture name={node.data.user.first_name} email={node.data.user.email} showName size="sm" />,
user: <ProfilePicture user={node.data.user} showName size="sm" />,
duration: humanFriendlyMilliseconds(node.data.duration_ms) || 'unknown',
sessionEventCount: node.data.events_count,
frustratingInteractions: node.data.frustrating_interactions_count,
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/scenes/annotations/Annotations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ export function Annotations(): JSX.Element {
return (
<div className="flex flex-row items-center">
<ProfilePicture
name={creation_type === 'GIT' ? 'GitHub Actions' : created_by?.first_name}
email={creation_type === 'GIT' ? undefined : created_by?.email}
user={creation_type === 'GIT' ? { first_name: 'GitHub Actions' } : created_by}
showName
size="md"
type={creation_type === 'GIT' ? 'bot' : 'person'}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/authentication/InviteSignup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function AuthenticatedAcceptInvite({ invite }: { invite: PrevalidatedInvite }):
className="border rounded-lg border-dashed flex items-center gap-2 px-2 py-1"
data-attr="top-navigation-whoami"
>
<ProfilePicture name={user.first_name} email={user.email} />
<ProfilePicture user={user} />
<div className="">
<div className="font-bold">{user.first_name}</div>
<div>{user.organization?.name}</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/scenes/dashboard/DashboardCollaborators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function CollaboratorRow({

return (
<div className="flex items-center justify-between mt-2 pl-2 h-8">
<ProfilePicture email={user.email} name={user.first_name} size="md" showName />
<ProfilePicture user={user} size="md" showName />
<Tooltip
title={
!wasInvited
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function StaffUsersTab(): JSX.Element {
{
key: 'profile_picture',
render: function ProfilePictureRender(_, user) {
return <ProfilePicture name={user.first_name} email={user.email} />
return <ProfilePicture user={user} />
},
width: 32,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const Component = (props: NodeViewProps): JSX.Element => {
<Tooltip
title={
<div className="p-2 flex items-center gap-2">
<ProfilePicture name={member?.user.first_name} email={member?.user.email} size="xl" />
<ProfilePicture user={member?.user} size="xl" />
<div>
<div className="font-bold">{member?.user.first_name}</div>
<div className="text-sm">{member?.user.email}</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export const Mentions = forwardRef<MentionsRef, MentionsProps>(function SlashCom
key={member.id}
fullWidth
status="primary-alt"
icon={<ProfilePicture name={member.user.first_name} email={member.user.email} size="sm" />}
icon={<ProfilePicture user={member.user} size="sm" />}
active={index === selectedIndex}
onClick={() => void execute(member)}
>
Expand Down
Loading

0 comments on commit ce48493

Please sign in to comment.